diff --git a/dlls/mswsock/mswsock.spec b/dlls/mswsock/mswsock.spec
index 1f2bd78..c0814fb 100644 (file)
--- a/dlls/mswsock/mswsock.spec
+++ b/dlls/mswsock/mswsock.spec
@@ -1,7 +1,7 @@
-@ stdcall AcceptEx(long long ptr long long long ptr ptr)
+@ stdcall AcceptEx(long long ptr long long long ptr ptr) ws2_32.AcceptEx
 @ stdcall EnumProtocolsA(ptr ptr ptr) ws2_32.WSAEnumProtocolsA
 @ stdcall EnumProtocolsW(ptr ptr ptr) ws2_32.WSAEnumProtocolsW
-@ stdcall GetAcceptExSockaddrs(ptr long long long ptr ptr ptr ptr)
+@ stdcall GetAcceptExSockaddrs(ptr long long long ptr ptr ptr ptr) ws2_32.GetAcceptExSockaddrs
 @ stub GetAddressByNameA
 @ stub GetAddressByNameW
 @ stub GetNameByTypeA
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index 96be7ca..aa73f64 100644 (file)
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -196,6 +196,15 @@ typedef struct ws2_async
     {
         int val;     /* for send operations */
         int *ptr;    /* for recv operations */
+        struct       /* for accept operation */
+        {
+            SOCKET s_accept; /* socket to use as connection socket */
+            PVOID  buf;      /* buffer to write data to */
+            int  data_len;
+            int local_len;
+            int remote_len;
+            DWORD *recvd;
+        } acpt;
     }                                   addrlen;
     DWORD                               flags;
     unsigned int                        n_iovecs;
@@ -241,6 +250,8 @@ static FARPROC blocking_hook = (FARPROC)WSA_DefaultBlockingHook;
 static struct WS_hostent *WS_dup_he(const struct hostent* p_he);
 static struct WS_protoent *WS_dup_pe(const struct protoent* p_pe);
 static struct WS_servent *WS_dup_se(const struct servent* p_se);
+static void WS_AddCompletion( SOCKET sock, ULONG_PTR CompletionValue, NTSTATUS CompletionStatus, ULONG Information );
+
 
 int WSAIOCTL_GetInterfaceCount(void);
 int WSAIOCTL_GetInterfaceName(int intNumber, char *intName);
@@ -1070,6 +1081,244 @@ static void WINAPI ws2_async_apc( void *arg, IO_STATUS_BLOCK *iosb, ULONG reserv
                                                     wsa->flags );
     HeapFree( GetProcessHeap(), 0, wsa );
 }
+/***********************************************************************
+ *              WS2_acceptex_data                (INTERNAL)
+ *
+ * This function is used to place the ipaddresses in the buffer.
+ */
+static void WS2_acceptex_data( char* buf, int local_len, int remote_len, int data_len, SOCKET s )
+{
+       int len;
+       buf = buf+data_len;
+       len = local_len - sizeof(int);
+       WS_getpeername(s,(struct WS_sockaddr*)(buf+sizeof(int)),&len);
+       *(int*)buf = len;
+       buf += local_len;
+       len = remote_len - sizeof(int);
+       WS_getsockname(s,(struct WS_sockaddr*)(buf+sizeof(int)),&len);
+       *(int*)buf = len;
+}
+/***********************************************************************
+ *              WS2_async_accept                (INTERNAL)
+ *
+ * This is the function called to satisfy the AcceptEx callback
+ */
+static NTSTATUS WINAPI WS2_async_accept( void *arg, IO_STATUS_BLOCK *iosb, NTSTATUS status )
+{
+       ws2_async *wsa = arg;
+       char *buf;
+       if(status != STATUS_ALERTED){
+               if(status != STATUS_HANDLES_CLOSED)
+                       FIXME("Unexpected/Unhandeled status Message= %x \n",status);
+       }
+       TRACE("status Message= %x listen: %lx, accept: %lx\n",status, HANDLE2SOCKET(wsa->hSocket),wsa->addrlen.acpt.s_accept);
+       if(status == STATUS_HANDLES_CLOSED){
+               wsa->user_overlapped->Internal = status;
+               wsa->user_overlapped->InternalHigh = 0;
+               iosb->u.Status = status;
+               iosb->Information = 0;
+               return status;
+       }
+       SERVER_START_REQ( accept_socket )
+       {
+               req->lhandle    = wsa->hSocket;
+               req->ahandle    = SOCKET2HANDLE(wsa->addrlen.acpt.s_accept);
+               req->access     = GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE;
+               req->attributes = OBJ_INHERIT;
+               status          = wine_server_call( req );
+       }
+       SERVER_END_REQ;
+       if(status != STATUS_SUCCESS){
+               FIXME("error in getting socket. socket: %lx, status: %x\n",wsa->addrlen.acpt.s_accept,status);
+               wsa->user_overlapped->Internal = status;
+               wsa->user_overlapped->InternalHigh = 0;
+               iosb->u.Status = status;
+               iosb->Information = 0;
+               return status;
+       }
+       /*We now have a connected socket. pull data in/write info to buffer*/
+       buf = (char*)wsa->addrlen.acpt.buf;
+       WS2_acceptex_data( buf, wsa->addrlen.acpt.local_len, wsa->addrlen.acpt.remote_len,wsa->addrlen.acpt.data_len, wsa->addrlen.acpt.s_accept );
+       /*socket address information is written. next pull in data.*/
+       /*we don't pull in data yet... */
+       wsa->addrlen.acpt.recvd = 0; 
+       wsa->user_overlapped->Internal = status;
+       wsa->user_overlapped->InternalHigh = 0;
+       iosb->u.Status = status;
+       iosb->Information = 0;
+       
+       HeapFree( GetProcessHeap(), 0, wsa );
+       return status;
+    
+}
+
+/***********************************************************************
+ *             AcceptEx (ws2_32.@)
+ *
+ * Accept a new connection, retrieving the connected addresses and initial data.
+ *
+ * listener       [I] Listening socket
+ * acceptor       [I] Socket to accept on
+ * dest           [O] Destination for inital data
+ * dest_len       [I] Size of dest in bytes
+ * local_addr_len [I] Number of bytes reserved in dest for local addrress
+ * rem_addr_len   [I] Number of bytes reserved in dest for remote addrress
+ * received       [O] Destination for number of bytes of initial data
+ * overlapped     [I] For asynchronous execution
+ *
+ * RETURNS
+ * Success: TRUE (We always return false because its simple)
+ * Failure: FALSE. Use WSAGetLastError() for details of the error.
+ */
+BOOL WINAPI AcceptEx(SOCKET listener, SOCKET acceptor, PVOID dest, DWORD dest_len,
+                     DWORD local_addr_len, DWORD rem_addr_len, LPDWORD received,
+                     LPOVERLAPPED overlapped)
+{
+       DWORD status;
+       struct ws2_async *wsa;
+       IO_STATUS_BLOCK *iosb;
+       char *buf = (char*) dest;
+       TRACE("listen: %lx, accept: %lx\n",listener,acceptor);
+       if(overlapped == NULL){
+               set_error(STATUS_INVALID_PARAMETER);
+               return FALSE;
+       }
+       if(dest_len !=0){
+               FIXME("AcceptEx does not support reciving data yet\n");
+               dest_len = 0;
+       }
+       
+       SERVER_START_REQ( accept_socket )
+       {
+               req->lhandle    = SOCKET2HANDLE(listener);
+               req->ahandle    = SOCKET2HANDLE(acceptor);
+               req->access     = GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE;
+               req->attributes = OBJ_INHERIT;
+               status = wine_server_call( req );
+       }
+       SERVER_END_REQ;
+
+       if (STATUS_SUCCESS == status)
+       {
+               buf = buf+dest_len;
+               WS2_acceptex_data( buf, local_addr_len, rem_addr_len, dest_len, acceptor );
+               *received = 0; 
+               overlapped->Internal = status;
+               overlapped->InternalHigh = 0;
+               WS_AddCompletion( listener , (ULONG_PTR)overlapped, STATUS_SUCCESS, 0);
+               set_error(STATUS_PENDING);
+               return FALSE;
+       }
+
+       wsa = HeapAlloc( GetProcessHeap(), 0, sizeof(*wsa) );
+       iosb = HeapAlloc( GetProcessHeap(), 0, sizeof(*iosb) );
+       if(!wsa || !iosb){
+               set_error(ERROR_NOT_ENOUGH_MEMORY);
+               return FALSE;
+       }
+       
+
+       /*Setup the internal data structures!*/
+       overlapped->Internal = STATUS_PENDING;
+       overlapped->InternalHigh = 0;
+       /*Do we need the following? Maybe...*/
+       iosb = &wsa->local_iosb;
+       iosb->u.Status = STATUS_PENDING;
+       iosb->Information = 0;
+
+
+       wsa->hSocket                    = SOCKET2HANDLE(listener);
+       wsa->flags                      = 0;
+       wsa->user_overlapped            = overlapped;
+       wsa->addrlen.acpt.s_accept      = acceptor;
+       wsa->addrlen.acpt.buf           = dest;
+       wsa->addrlen.acpt.data_len      = dest_len;
+       wsa->addrlen.acpt.local_len     = local_addr_len;
+       wsa->addrlen.acpt.remote_len    = rem_addr_len;
+       wsa->addrlen.acpt.recvd         = received;     
+
+       SERVER_START_REQ( set_socket_listener )
+       {
+               req->handle          = SOCKET2HANDLE(acceptor);
+               req->hListen         = SOCKET2HANDLE(listener);
+               status = wine_server_call( req );
+       }
+       SERVER_END_REQ;
+       if(status != STATUS_SUCCESS){
+               FIXME("error setting socket listener\n");
+       }
+
+       SERVER_START_REQ( register_async_l )
+       {
+               req->handle         = wsa->hSocket;
+               req->type           = ASYNC_TYPE_READ;
+               req->locator        = SOCKET2HANDLE(acceptor);
+               req->async.callback = WS2_async_accept;
+               req->async.iosb     = iosb;
+               req->async.arg      = wsa;
+               req->async.event    = overlapped->hEvent;
+               req->async.cvalue   = (ULONG_PTR)overlapped;
+               status = wine_server_call( req );
+       }
+       SERVER_END_REQ; 
+       
+       if(status != STATUS_PENDING){
+               HeapFree( GetProcessHeap(), 0, wsa );
+               HeapFree( GetProcessHeap(), 0, iosb );  
+               set_error(status);
+               return FALSE;
+       }
+       set_error(STATUS_PENDING);
+       return FALSE;
+}
+
+/***********************************************************************
+ *             GetAcceptExSockaddrs (WS2_32.@)
+ *
+ * Get infomation about an accepted socket.
+ *
+ * _buf                [O] Destination for the first block of data from AcceptEx()
+ * data_size           [I] length of data in bytes
+ * local_size          [I] Bytes reserved for local addrinfo
+ * remote_size         [I] Bytes reserved for remote addrinfo
+ * local_addr          [O] Destination for local sockaddr
+ * local_addr_len      [I] Size of local_addr
+ * remote_addr         [O] Destination for remote sockaddr
+ * remote_addr_len     [I] Size of rem_addr
+ *
+ * RETURNS
+ *  Nothing.
+ */
+VOID WINAPI GetAcceptExSockaddrs( PVOID _buf, DWORD data_size, DWORD local_size, DWORD remote_size,
+                  struct sockaddr ** local_addr, LPINT local_addr_len, struct sockaddr ** remote_addr, LPINT remote_addr_len)
+{
+    int len;
+    char *buf = _buf;
+
+    TRACE("buf=%p, data_size=%d, local_size=%d, remote_size=%d, local_addr=%p (%p), remote_addr=%p (%p)\n", buf, data_size, local_size, remote_size,
+            local_addr, local_addr_len, remote_addr, remote_addr_len );
+
+    buf += data_size;
+    if (local_size)
+    {
+        len = *(int*)buf;
+        *local_addr_len = len;
+        *local_addr = (struct sockaddr*)(buf+sizeof(int));
+        buf += local_size;
+        TRACE("local %d bytes to %p\n", len, local_addr);
+    }
+    else
+        *local_addr_len = 0;
+    if (remote_size)
+    {
+        len = *(int*)buf;
+        *remote_addr_len = len;
+        *remote_addr = (struct sockaddr*)(buf+sizeof(int));
+        TRACE("remote %d bytes to %p\n", len, remote_addr);
+    }
+    else
+        *remote_addr_len = 0;
+}
 
 /***********************************************************************
  *              WS2_recv                (INTERNAL)
diff --git a/dlls/ws2_32/ws2_32.spec b/dlls/ws2_32/ws2_32.spec
index a77c215..2e20d38 100644 (file)
--- a/dlls/ws2_32/ws2_32.spec
+++ b/dlls/ws2_32/ws2_32.spec
@@ -119,3 +119,5 @@
 @ stdcall getaddrinfo(str str ptr ptr) WS_getaddrinfo
 @ stdcall getnameinfo(ptr long ptr long ptr long long) WS_getnameinfo
 @ stdcall inet_ntop(long ptr ptr long) WS_inet_ntop
+@ stdcall AcceptEx(long long ptr long long long ptr ptr) 
+@ stdcall GetAcceptExSockaddrs(ptr long long long ptr ptr ptr ptr)
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index c7566ea..9d3deef 100644 (file)
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -47,7 +47,7 @@ struct reply_header
 
 struct request_max_size
 {
-    int pad[16];
+    int pad[20];
 };
 
 #define FIRST_USER_HANDLE 0x0020
@@ -1274,6 +1274,7 @@ struct accept_socket_request
 {
     struct request_header __header;
     obj_handle_t lhandle;
+    obj_handle_t ahandle;
     unsigned int access;
     unsigned int attributes;
 };
@@ -1301,6 +1302,18 @@ struct set_socket_event_reply
 };
 
 
+struct set_socket_listener_request
+{
+    struct request_header __header;
+    obj_handle_t  handle;
+    obj_handle_t  hListen;
+    char __pad_20[4];
+};
+struct set_socket_listener_reply
+{
+    struct reply_header __header;
+};
+
 
 struct get_socket_event_request
 {
@@ -2849,6 +2862,21 @@ struct register_async_reply
 {
     struct reply_header __header;
 };
+
+struct register_async_l_request
+{
+    struct request_header __header;
+    obj_handle_t handle;
+    int          type;
+    int          count;
+    obj_handle_t locator;
+    char __pad_28[4];
+    async_data_t async;
+};
+struct register_async_l_reply
+{
+    struct reply_header __header;
+};
 #define ASYNC_TYPE_READ  0x01
 #define ASYNC_TYPE_WRITE 0x02
 #define ASYNC_TYPE_WAIT  0x03
@@ -4628,6 +4656,7 @@ enum request
     REQ_create_socket,
     REQ_accept_socket,
     REQ_set_socket_event,
+    REQ_set_socket_listener,
     REQ_get_socket_event,
     REQ_enable_socket_event,
     REQ_set_socket_deferred,
@@ -4718,6 +4747,7 @@ enum request
     REQ_get_serial_info,
     REQ_set_serial_info,
     REQ_register_async,
+    REQ_register_async_l,
     REQ_cancel_async,
     REQ_ioctl,
     REQ_get_ioctl_result,
@@ -4873,6 +4903,7 @@ union generic_request
     struct create_socket_request create_socket_request;
     struct accept_socket_request accept_socket_request;
     struct set_socket_event_request set_socket_event_request;
+    struct set_socket_listener_request set_socket_listener_request;
     struct get_socket_event_request get_socket_event_request;
     struct enable_socket_event_request enable_socket_event_request;
     struct set_socket_deferred_request set_socket_deferred_request;
@@ -4963,6 +4994,7 @@ union generic_request
     struct get_serial_info_request get_serial_info_request;
     struct set_serial_info_request set_serial_info_request;
     struct register_async_request register_async_request;
+    struct register_async_l_request register_async_l_request;
     struct cancel_async_request cancel_async_request;
     struct ioctl_request ioctl_request;
     struct get_ioctl_result_request get_ioctl_result_request;
@@ -5116,6 +5148,7 @@ union generic_reply
     struct create_socket_reply create_socket_reply;
     struct accept_socket_reply accept_socket_reply;
     struct set_socket_event_reply set_socket_event_reply;
+    struct set_socket_listener_reply set_socket_listener_reply;
     struct get_socket_event_reply get_socket_event_reply;
     struct enable_socket_event_reply enable_socket_event_reply;
     struct set_socket_deferred_reply set_socket_deferred_reply;
@@ -5206,6 +5239,7 @@ union generic_reply
     struct get_serial_info_reply get_serial_info_reply;
     struct set_serial_info_reply set_serial_info_reply;
     struct register_async_reply register_async_reply;
+    struct register_async_l_reply register_async_l_reply;
     struct cancel_async_reply cancel_async_reply;
     struct ioctl_reply ioctl_reply;
     struct get_ioctl_result_reply get_ioctl_result_reply;
diff --git a/server/async.c b/server/async.c
index 91f0c44..c30d740 100644 (file)
--- a/server/async.c
+++ b/server/async.c
@@ -45,6 +45,7 @@ struct async
     struct completion   *completion;
     apc_param_t          comp_key;
     async_data_t         data;            /* data for async I/O call */
+    obj_handle_t        locator;         /* handle used to locate this async */
 };
 
 static void async_dump( struct object *obj, int verbose );
@@ -117,7 +118,6 @@ static void async_destroy( struct object *obj )
 {
     struct async *async = (struct async *)obj;
     assert( obj->ops == &async_ops );
-
     list_remove( &async->queue_entry );
     async_reselect( async );
 
@@ -192,6 +192,7 @@ void free_async_queue( struct async_queue *queue )
     release_object( queue );
 }
 
+
 /* create an async on a given queue of a fd */
 struct async *create_async( struct thread *thread, struct async_queue *queue, const async_data_t *data )
 {
@@ -214,6 +215,7 @@ struct async *create_async( struct thread *thread, struct async_queue *queue, co
     async->timeout = NULL;
     async->queue   = (struct async_queue *)grab_object( queue );
     async->completion = NULL;
+    async->locator = 0;
     if (queue->fd) async->completion = fd_get_completion( queue->fd, &async->comp_key );
 
     list_add_tail( &queue->queue, &async->queue_entry );
@@ -224,6 +226,15 @@ struct async *create_async( struct thread *thread, struct async_queue *queue, co
     return async;
 }
 
+/* create an async that you can locate later */
+struct async *create_async_l( struct thread *thread, struct async_queue *queue, const async_data_t *data, obj_handle_t l )
+{
+       struct async *out;
+       out = create_async(thread,queue,data);
+       out->locator = l;
+       return out;
+}
+
 /* set the timeout of an async operation */
 void async_set_timeout( struct async *async, timeout_t timeout, unsigned int status )
 {
@@ -279,26 +290,44 @@ void async_set_result( struct object *obj, unsigned int status, unsigned int tot
 /* check if an async operation is waiting to be alerted */
 int async_waiting( struct async_queue *queue )
 {
-    struct list *ptr;
+    struct list *ptr,*next;
     struct async *async;
 
     if (!queue) return 0;
     if (!(ptr = list_head( &queue->queue ))) return 0;
-    async = LIST_ENTRY( ptr, struct async, queue_entry );
-    return async->status == STATUS_PENDING;
+    LIST_FOR_EACH_SAFE( ptr, next, &queue->queue )
+    {
+               async = LIST_ENTRY( ptr, struct async, queue_entry );
+               if(async->status == STATUS_PENDING)
+               { /*something is pending*/
+                       return TRUE;
+               }
+       }
+    return FALSE; /*nothing is pending*/
 }
 
-/* wake up async operations on the queue */
-void async_wake_up( struct async_queue *queue, unsigned int status )
+/* wakes up specific async operations on the queue */
+void async_wake_up_l( struct async_queue *queue, unsigned int status, obj_handle_t l )
 {
     struct list *ptr, *next;
-
     if (!queue) return;
-
     LIST_FOR_EACH_SAFE( ptr, next, &queue->queue )
     {
         struct async *async = LIST_ENTRY( ptr, struct async, queue_entry );
-        async_terminate( async, status );
+       if( (async->locator == l || 0 == l) && /*step one. are we locating?*/
+               (((status == STATUS_ALERTED) && (async->status != STATUS_ALERTED)) || /*don't alert one thats already alerted*/
+                 (status != STATUS_ALERTED)) ) /*if we aren't alerting, notify everything*/
+       {
+               async_terminate( async, status );
         if (status == STATUS_ALERTED) break;  /* only wake up the first one */
+       }
     }
 }
+
+/* wake up async operations on the queue */
+void async_wake_up( struct async_queue *queue, unsigned int status )
+{
+    async_wake_up_l(queue,status,0);
+}
+
+
diff --git a/server/fd.c b/server/fd.c
index a57001a..b94d5a8 100644 (file)
--- a/server/fd.c
+++ b/server/fd.c
@@ -1863,6 +1863,7 @@ void default_fd_cancel_async( struct fd *fd )
     async_wake_up( fd->wait_q, STATUS_CANCELLED );
 }
 
+
 /* default flush() routine */
 void no_flush( struct fd *fd, struct event **event )
 {
@@ -2060,6 +2061,32 @@ DECL_HANDLER(register_async)
     }
 }
 
+/* create / reschedule an async I/O */
+DECL_HANDLER(register_async_l)
+{
+    unsigned int access;
+    struct fd *fd;
+
+    switch(req->type)
+    {
+    case ASYNC_TYPE_READ:
+        access = FILE_READ_DATA;
+        break;
+    case ASYNC_TYPE_WRITE:
+        access = FILE_WRITE_DATA;
+        break;
+    default:
+        set_error( STATUS_INVALID_PARAMETER );
+        return;
+    }
+
+    if ((fd = get_handle_fd_obj( current->process, req->handle, access )))
+    {
+        if (get_unix_fd( fd ) != -1) fd->fd_ops->queue_async_l( fd, &req->async, req->type, req->count, req->locator );
+        release_object( fd );
+    }
+}
+
 /* cancels all async I/O */
 DECL_HANDLER(cancel_async)
 {
@@ -2072,6 +2099,7 @@ DECL_HANDLER(cancel_async)
     }
 }
 
+
 /* attach completion object to a fd */
 DECL_HANDLER(set_completion_info)
 {
diff --git a/server/file.h b/server/file.h
index aef40f7..74b2548 100644 (file)
--- a/server/file.h
+++ b/server/file.h
@@ -47,6 +47,9 @@ struct fd_ops
     void (*reselect_async)( struct fd *, struct async_queue *queue );
     /* cancel an async operation */
     void (*cancel_async)(struct fd *);
+    /* queue a locatable async operation */
+    void (*queue_async_l)(struct fd *, const async_data_t *data, int type, int count, obj_handle_t locator);
+    
 };
 
 /* file descriptor functions */
@@ -138,12 +141,15 @@ extern struct async_queue *create_async_queue( struct fd *fd );
 extern void free_async_queue( struct async_queue *queue );
 extern struct async *create_async( struct thread *thread, struct async_queue *queue,
                                    const async_data_t *data );
+extern struct async *create_async_l( struct thread *thread, struct async_queue *queue,
+                                   const async_data_t *data, obj_handle_t l );
 extern void async_set_timeout( struct async *async, timeout_t timeout, unsigned int status );
 extern void async_set_result( struct object *obj, unsigned int status,
                               unsigned int total, client_ptr_t apc );
 extern int async_waiting( struct async_queue *queue );
 extern void async_terminate( struct async *async, unsigned int status );
 extern void async_wake_up( struct async_queue *queue, unsigned int status );
+extern void async_wake_up_l( struct async_queue *queue, unsigned int status, obj_handle_t l );
 extern struct completion *fd_get_completion( struct fd *fd, apc_param_t *p_key );
 extern void fd_copy_completion( struct fd *src, struct fd *dst );
 
diff --git a/server/protocol.def b/server/protocol.def
index e871736..1bbe89e 100644 (file)
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -63,7 +63,7 @@ struct reply_header
 /* this is used to construct the generic_request union */
 struct request_max_size
 {
-    int pad[16]; /* the max request size is 16 ints */
+    int pad[20]; /* the max request size is 16 ints */
 };
 
 #define FIRST_USER_HANDLE 0x0020  /* first possible value for low word of user handle */
@@ -1041,6 +1041,7 @@ enum server_fd_type
 /* Accept a socket */
 @REQ(accept_socket)
     obj_handle_t lhandle;       /* handle to the listening socket */
+    obj_handle_t ahandle;      /* handle to the accepting socket */
     unsigned int access;        /* wanted access rights */
     unsigned int attributes;    /* object attributes */
 @REPLY
@@ -1057,6 +1058,11 @@ enum server_fd_type
     unsigned int  msg;           /* message to send */
 @END
 
+/* Set socket listener  */
+@REQ(set_socket_listener)
+    obj_handle_t  handle;        /* handle to the socket */
+    obj_handle_t  hListen;      /* handle to the socket listening for connections */
+@END
 
 /* Get socket event parameters */
 @REQ(get_socket_event)
@@ -2064,6 +2070,14 @@ enum message_type
     async_data_t async;         /* async I/O parameters */
     int          count;         /* count - usually # of bytes to be read/written */
 @END
+/* Create a locatable async I/O */
+@REQ(register_async_l)
+    obj_handle_t handle;        /* handle to comm port, socket or file */
+    int          type;          /* type of queue to look after */
+    int          count;         /* count - usually # of bytes to be read/written */
+    obj_handle_t locator;      /* used to locate a specific async request later */
+    async_data_t async;         /* async I/O parameters */
+@END
 #define ASYNC_TYPE_READ  0x01
 #define ASYNC_TYPE_WRITE 0x02
 #define ASYNC_TYPE_WAIT  0x03
diff --git a/server/request.h b/server/request.h
index 4fc3bd6..8e6fe07 100644 (file)
--- a/server/request.h
+++ b/server/request.h
@@ -155,6 +155,7 @@ DECL_HANDLER(unlock_file);
 DECL_HANDLER(create_socket);
 DECL_HANDLER(accept_socket);
 DECL_HANDLER(set_socket_event);
+DECL_HANDLER(set_socket_listener);
 DECL_HANDLER(get_socket_event);
 DECL_HANDLER(enable_socket_event);
 DECL_HANDLER(set_socket_deferred);
@@ -245,6 +246,7 @@ DECL_HANDLER(is_window_hung);
 DECL_HANDLER(get_serial_info);
 DECL_HANDLER(set_serial_info);
 DECL_HANDLER(register_async);
+DECL_HANDLER(register_async_l);
 DECL_HANDLER(cancel_async);
 DECL_HANDLER(ioctl);
 DECL_HANDLER(get_ioctl_result);
@@ -399,6 +401,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
     (req_handler)req_create_socket,
     (req_handler)req_accept_socket,
     (req_handler)req_set_socket_event,
+    (req_handler)req_set_socket_listener,
     (req_handler)req_get_socket_event,
     (req_handler)req_enable_socket_event,
     (req_handler)req_set_socket_deferred,
@@ -489,6 +492,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
     (req_handler)req_get_serial_info,
     (req_handler)req_set_serial_info,
     (req_handler)req_register_async,
+    (req_handler)req_register_async_l,
     (req_handler)req_cancel_async,
     (req_handler)req_ioctl,
     (req_handler)req_get_ioctl_result,
@@ -876,8 +880,9 @@ C_ASSERT( FIELD_OFFSET(struct create_socket_request, flags) == 32 );
 C_ASSERT( FIELD_OFFSET(struct create_socket_reply, handle) == 8 );
 C_ASSERT( sizeof(struct create_socket_reply) == 16 );
 C_ASSERT( FIELD_OFFSET(struct accept_socket_request, lhandle) == 12 );
-C_ASSERT( FIELD_OFFSET(struct accept_socket_request, access) == 16 );
-C_ASSERT( FIELD_OFFSET(struct accept_socket_request, attributes) == 20 );
+C_ASSERT( FIELD_OFFSET(struct accept_socket_request, ahandle) == 16 );
+C_ASSERT( FIELD_OFFSET(struct accept_socket_request, access) == 20 );
+C_ASSERT( FIELD_OFFSET(struct accept_socket_request, attributes) == 24 );
 C_ASSERT( FIELD_OFFSET(struct accept_socket_reply, handle) == 8 );
 C_ASSERT( sizeof(struct accept_socket_reply) == 16 );
 C_ASSERT( FIELD_OFFSET(struct set_socket_event_request, handle) == 12 );
@@ -886,6 +891,9 @@ C_ASSERT( FIELD_OFFSET(struct set_socket_event_request, event) == 20 );
 C_ASSERT( FIELD_OFFSET(struct set_socket_event_request, window) == 24 );
 C_ASSERT( FIELD_OFFSET(struct set_socket_event_request, msg) == 28 );
 C_ASSERT( sizeof(struct set_socket_event_request) == 32 );
+C_ASSERT( FIELD_OFFSET(struct set_socket_listener_request, handle) == 12 );
+C_ASSERT( FIELD_OFFSET(struct set_socket_listener_request, hListen) == 16 );
+C_ASSERT( sizeof(struct set_socket_listener_request) == 24 );
 C_ASSERT( FIELD_OFFSET(struct get_socket_event_request, handle) == 12 );
 C_ASSERT( FIELD_OFFSET(struct get_socket_event_request, service) == 16 );
 C_ASSERT( FIELD_OFFSET(struct get_socket_event_request, c_event) == 20 );
@@ -1350,6 +1358,12 @@ C_ASSERT( FIELD_OFFSET(struct register_async_request, type) == 12 );
 C_ASSERT( FIELD_OFFSET(struct register_async_request, async) == 16 );
 C_ASSERT( FIELD_OFFSET(struct register_async_request, count) == 56 );
 C_ASSERT( sizeof(struct register_async_request) == 64 );
+C_ASSERT( FIELD_OFFSET(struct register_async_l_request, handle) == 12 );
+C_ASSERT( FIELD_OFFSET(struct register_async_l_request, type) == 16 );
+C_ASSERT( FIELD_OFFSET(struct register_async_l_request, count) == 20 );
+C_ASSERT( FIELD_OFFSET(struct register_async_l_request, locator) == 24 );
+C_ASSERT( FIELD_OFFSET(struct register_async_l_request, async) == 32 );
+C_ASSERT( sizeof(struct register_async_l_request) == 72 );
 C_ASSERT( FIELD_OFFSET(struct cancel_async_request, handle) == 12 );
 C_ASSERT( sizeof(struct cancel_async_request) == 16 );
 C_ASSERT( FIELD_OFFSET(struct ioctl_request, code) == 12 );
diff --git a/server/sock.c b/server/sock.c
index baaa9df..96ef50a 100644 (file)
--- a/server/sock.c
+++ b/server/sock.c
@@ -85,6 +85,8 @@ struct sock
     struct sock        *deferred;    /* socket that waits for a deferred accept */
     struct async_queue *read_q;      /* queue for asynchronous reads */
     struct async_queue *write_q;     /* queue for asynchronous writes */
+    obj_handle_t       hListen;     /* socket listening for connections for this one */
+       int                                     incCon;          /* number of incomming connect attempts will will try to wake for */
 };
 
 static void sock_dump( struct object *obj, int verbose );
@@ -96,8 +98,12 @@ static int sock_get_poll_events( struct fd *fd );
 static void sock_poll_event( struct fd *fd, int event );
 static enum server_fd_type sock_get_fd_type( struct fd *fd );
 static void sock_queue_async( struct fd *fd, const async_data_t *data, int type, int count );
+static void sock_queue_async_l( struct fd *fd, const async_data_t *data, int type, int count, obj_handle_t locator );
 static void sock_reselect_async( struct fd *fd, struct async_queue *queue );
 static void sock_cancel_async( struct fd *fd );
+static int sock_close_handle( struct object *obj, struct process *process, obj_handle_t handle );
+static void sock_async_close_l( struct sock *sock, obj_handle_t locator );
+
 
 static int sock_get_error( int err );
 static void sock_set_error(void);
@@ -118,7 +124,7 @@ static const struct object_ops sock_ops =
     default_set_sd,               /* set_sd */
     no_lookup_name,               /* lookup_name */
     no_open_file,                 /* open_file */
-    fd_close_handle,              /* close_handle */
+    sock_close_handle,              /* close_handle */
     sock_destroy                  /* destroy */
 };
 
@@ -131,7 +137,8 @@ static const struct fd_ops sock_fd_ops =
     default_fd_ioctl,             /* ioctl */
     sock_queue_async,             /* queue_async */
     sock_reselect_async,          /* reselect_async */
-    sock_cancel_async             /* cancel_async */
+    sock_cancel_async,            /* cancel_async */
+    sock_queue_async_l           /* quque_async_l */
 };
 
 
@@ -247,11 +254,15 @@ static void sock_wake_up( struct sock *sock, int pollev )
     unsigned int events = sock->pmask & sock->mask;
     int i;
     int async_active = 0;
-
+       
+       /*fprintf(stderr,"sock: %p. pollev & (POLLIN|POLLPRI):%d. async_waiting( sock->read_q ):%d,sock->read_q:%p\n",sock,pollev & (POLLIN|POLLPRI),async_waiting( sock->read_q ),sock->read_q);*/
+               /*      fflush(NULL);*/
     if ( pollev & (POLLIN|POLLPRI) && async_waiting( sock->read_q ))
     {
+       /*      fprintf(stderr,"waking_read_queue pending:%d\n",sock->incCon);*/
+       /*              fflush(NULL);*/
         if (debug_level) fprintf( stderr, "activating read queue for socket %p\n", sock );
-        async_wake_up( sock->read_q, STATUS_ALERTED );
+               async_wake_up( sock->read_q, STATUS_ALERTED );
         async_active = 1;
     }
     if ( pollev & POLLOUT && async_waiting( sock->write_q ))
@@ -332,10 +343,14 @@ static void sock_poll_event( struct fd *fd, int event )
         /* listening */
         if (event & POLLIN)
         {
-            /* incoming connection */
+                       
+            /* incoming connection */                  
+                       sock->incCon += 1;
             sock->pmask |= FD_ACCEPT;
             sock->errors[FD_ACCEPT_BIT] = 0;
             sock->hmask |= FD_ACCEPT;
+               /*      fprintf(stderr,"sock: %p. incomming connection. pending: %d\n",sock,sock->incCon);*/
+               /*      fflush(NULL);*/
         }
         else if (event & (POLLERR|POLLHUP))
         {
@@ -435,10 +450,17 @@ static void sock_poll_event( struct fd *fd, int event )
     }
     else
         sock_reselect( sock );
-
+       
     /* wake up anyone waiting for whatever just happened */
-    if ( sock->pmask & sock->mask || sock->flags & WSA_FLAG_OVERLAPPED ) sock_wake_up( sock, event );
-
+    if ( sock->pmask & sock->mask || sock->flags & WSA_FLAG_OVERLAPPED )
+       {
+/*             fprintf(stderr,"sock: %p. pending: %d. 1st: %d. 2nd: %d.\n",sock,sock->incCon, sock->pmask & sock->mask, sock->flags & WSA_FLAG_OVERLAPPED);*/
+/*             fflush(NULL);*/
+               sock_wake_up( sock, event );
+       } else{
+/*     fprintf(stderr,"sock: %p. pending: %d. 1st: %d. 2nd: %d.\n",sock,sock->incCon, sock->pmask & sock->mask, sock->flags & WSA_FLAG_OVERLAPPED);*/
+/*     fflush(NULL);*/
+       }
     /* if anyone is stupid enough to wait on the socket object itself,
      * maybe we should wake them up too, just in case? */
     wake_up( &sock->obj, 0 );
@@ -466,7 +488,7 @@ static int sock_get_poll_events( struct fd *fd )
     struct sock *sock = get_fd_user( fd );
     unsigned int mask = sock->mask & sock->state & ~sock->hmask;
     int ev = 0;
-
+                       
     assert( sock->obj.ops == &sock_ops );
 
     if (sock->state & FD_CONNECT)
@@ -490,7 +512,7 @@ static enum server_fd_type sock_get_fd_type( struct fd *fd )
     return FD_TYPE_SOCKET;
 }
 
-static void sock_queue_async( struct fd *fd, const async_data_t *data, int type, int count )
+static void sock_queue_async_l( struct fd *fd, const async_data_t *data, int type, int count, obj_handle_t locator )
 {
     struct sock *sock = get_fd_user( fd );
     struct async_queue *queue;
@@ -514,7 +536,7 @@ static void sock_queue_async( struct fd *fd, const async_data_t *data, int type,
         return;
     }
 
-    if ( ( !( sock->state & FD_READ ) && type == ASYNC_TYPE_READ  ) ||
+    if ( ( !( sock->state & (FD_READ|FD_WINE_LISTENING) ) && type == ASYNC_TYPE_READ  ) ||
          ( !( sock->state & FD_WRITE ) && type == ASYNC_TYPE_WRITE ) )
     {
         set_error( STATUS_PIPE_DISCONNECTED );
@@ -522,7 +544,7 @@ static void sock_queue_async( struct fd *fd, const async_data_t *data, int type,
     else
     {
         struct async *async;
-        if (!(async = create_async( current, queue, data ))) return;
+        if (!(async = create_async_l( current, queue, data, locator ))) return;
         release_object( async );
         set_error( STATUS_PENDING );
     }
@@ -530,6 +552,10 @@ static void sock_queue_async( struct fd *fd, const async_data_t *data, int type,
     pollev = sock_reselect( sock );
     if ( pollev ) sock_try_event( sock, pollev );
 }
+static void sock_queue_async( struct fd *fd, const async_data_t *data, int type, int count)
+{
+       sock_queue_async_l(fd,data,type,count,0);
+}
 
 static void sock_reselect_async( struct fd *fd, struct async_queue *queue )
 {
@@ -542,11 +568,38 @@ static void sock_cancel_async( struct fd *fd )
 {
     struct sock *sock = get_fd_user( fd );
     assert( sock->obj.ops == &sock_ops );
-
     async_wake_up( sock->read_q, STATUS_CANCELLED );
     async_wake_up( sock->write_q, STATUS_CANCELLED );
 }
 
+static int sock_close_handle( struct object *obj, struct process *process, obj_handle_t handle )
+{
+    struct sock *sock = (struct sock*) obj;
+    struct sock *l = NULL;
+    assert( sock->obj.ops == &sock_ops );
+    async_wake_up( sock->read_q, STATUS_HANDLES_CLOSED );
+    async_wake_up( sock->write_q, STATUS_HANDLES_CLOSED );
+    if(current && sock){ /*avoid fatal error when updating wine config files*/
+       l = (struct sock *)get_handle_obj( process, sock->hListen, FILE_WRITE_ATTRIBUTES, &sock_ops );
+       if(l)
+               {
+                   sock_async_close_l( l, handle );
+           release_object( l );
+       }else{
+                       clear_error();
+               }
+    }
+    
+    return fd_close_handle(obj,process,handle);
+}
+
+/*Closes all async operations on a socket with the corresponding locator */
+static void sock_async_close_l( struct sock *sock, obj_handle_t locator )
+{
+    async_wake_up_l( sock->read_q, STATUS_HANDLES_CLOSED, locator );
+    async_wake_up_l( sock->write_q, STATUS_HANDLES_CLOSED, locator );
+}
+
 static struct fd *sock_get_fd( struct object *obj )
 {
     struct sock *sock = (struct sock *)obj;
@@ -609,6 +662,7 @@ static struct object *create_socket( int family, int type, int protocol, unsigne
     sock->deferred = NULL;
     sock->read_q  = NULL;
     sock->write_q = NULL;
+       sock->incCon = 0;
     if (!(sock->fd = create_anonymous_fd( &sock_fd_ops, sockfd, &sock->obj,
                             (flags & WSA_FLAG_OVERLAPPED) ? 0 : FILE_SYNCHRONOUS_IO_NONALERT )))
     {
@@ -621,16 +675,17 @@ static struct object *create_socket( int family, int type, int protocol, unsigne
 }
 
 /* accept a socket (creates a new fd) */
-static struct sock *accept_socket( obj_handle_t handle )
+static struct sock *accept_socket( obj_handle_t handle, obj_handle_t ahandle )
 {
-    struct sock *acceptsock;
+    struct sock *acceptsock = NULL;
     struct sock *sock;
     int	acceptfd;
     struct sockaddr	saddr;
-
+	
     sock = (struct sock *)get_handle_obj( current->process, handle, FILE_READ_DATA, &sock_ops );
-    if (!sock)
+    if (!sock){
     	return NULL;
+    }
 
     if ( sock->deferred )
     {
@@ -650,46 +705,62 @@ static struct sock *accept_socket( obj_handle_t handle )
         {
             sock_set_error();
             release_object( sock );
-            return NULL;
+           return NULL;
         }
-        if (!(acceptsock = alloc_object( &sock_ops )))
-        {
-            close( acceptfd );
-            release_object( sock );
-            return NULL;
-        }
-
-        /* newly created socket gets the same properties of the listening socket */
-        fcntl(acceptfd, F_SETFL, O_NONBLOCK); /* make socket nonblocking */
-        acceptsock->state  = FD_WINE_CONNECTED|FD_READ|FD_WRITE;
-        if (sock->state & FD_WINE_NONBLOCKING)
-            acceptsock->state |= FD_WINE_NONBLOCKING;
-        acceptsock->mask    = sock->mask;
-        acceptsock->hmask   = 0;
-        acceptsock->pmask   = 0;
-        acceptsock->polling = 0;
-        acceptsock->type    = sock->type;
-        acceptsock->family  = sock->family;
-        acceptsock->event   = NULL;
-        acceptsock->window  = sock->window;
-        acceptsock->message = sock->message;
-        acceptsock->wparam  = 0;
-        if (sock->event) acceptsock->event = (struct event *)grab_object( sock->event );
-        acceptsock->flags = sock->flags;
-        acceptsock->deferred = NULL;
-        acceptsock->read_q  = NULL;
-        acceptsock->write_q = NULL;
-        if (!(acceptsock->fd = create_anonymous_fd( &sock_fd_ops, acceptfd, &acceptsock->obj,
+               
+               if(ahandle){
+                       acceptsock = (struct sock *)get_handle_obj(current->process, ahandle, FILE_READ_DATA | FILE_WRITE_DATA, &sock_ops );
+                       if(acceptsock){
+                               if(acceptsock->event)
+                                       release_object( acceptsock->event );
+                               release_object( acceptsock->fd );
+                       }
+               }else{
+                       acceptsock = alloc_object( &sock_ops );
+               }
+       if (!acceptsock)
+       {
+           close( acceptfd );
+           release_object( sock );
+           return NULL;
+       }
+       
+
+               fcntl(acceptfd, F_SETFL, O_NONBLOCK); /* make socket nonblocking */
+               acceptsock->state  = FD_WINE_CONNECTED|FD_READ|FD_WRITE;
+       acceptsock->hmask   = 0;
+       acceptsock->pmask   = 0;
+       acceptsock->polling = 0;
+       acceptsock->event   = NULL;
+       acceptsock->deferred = NULL;
+       acceptsock->read_q  = NULL;
+       acceptsock->write_q = NULL;
+       acceptsock->wparam  = 0;
+               acceptsock->incCon = 0;
+               /* newly created socket gets the same properties of the listening socket */
+       if (sock->state & FD_WINE_NONBLOCKING)
+           acceptsock->state |= FD_WINE_NONBLOCKING;
+       acceptsock->mask    = sock->mask;
+       acceptsock->type    = sock->type;
+       acceptsock->family  = sock->family;
+       acceptsock->window  = sock->window;
+       acceptsock->message = sock->message;
+       if (sock->event) acceptsock->event = (struct event *)grab_object( sock->event );
+       acceptsock->flags = sock->flags;
+       if (!(acceptsock->fd = create_anonymous_fd( &sock_fd_ops, acceptfd, &acceptsock->obj,
                                                     get_fd_options( sock->fd ) )))
-        {
-            release_object( acceptsock );
-            release_object( sock );
-            return NULL;
-        }
+       {
+                   release_object( acceptsock );
+           release_object( sock );
+           return NULL;
+       }
     }
     clear_error();
-    sock->pmask &= ~FD_ACCEPT;
-    sock->hmask &= ~FD_ACCEPT;
+       sock->pmask &= ~FD_ACCEPT;
+       sock->hmask &= ~FD_ACCEPT;
+       sock->incCon -= 1;
+       //fprintf(stderr,"accept: pending: %d\n",sock->incCon);
+       //fflush(NULL);
     sock_reselect( sock );
     release_object( sock );
     return acceptsock;
@@ -787,13 +858,35 @@ DECL_HANDLER(accept_socket)
     struct sock *sock;
 
     reply->handle = 0;
-    if ((sock = accept_socket( req->lhandle )) != NULL)
+    if ((sock = accept_socket( req->lhandle, req->ahandle )) != NULL)
     {
-        reply->handle = alloc_handle( current->process, &sock->obj, req->access, req->attributes );
-        sock->wparam = reply->handle;  /* wparam for message is the socket handle */
-        sock_reselect( sock );
-        release_object( &sock->obj );
+        if (req->ahandle)
+            reply->handle = req->ahandle;
+        else
+        {
+            reply->handle = alloc_handle( current->process, &sock->obj, req->access, req->attributes );
+            sock->wparam = reply->handle;  /* wparam for message is the socket handle */
+            sock_reselect( sock );
+        }
+        release_object( &sock->obj );//I think this needs togo in the else. But i want to check.
+       //We can't release the object unless we allocate a handle for it.
+       //Do we need to se the wparam? What is this? No... maybe... i dont know.
+    }
+}
+
+/* Sets which socket is listening for connections for this socket */
+DECL_HANDLER(set_socket_listener)
+{
+    struct sock *sock;
+    sock = (struct sock *)get_handle_obj( current->process, req->handle, FILE_WRITE_ATTRIBUTES, &sock_ops );
+    if(!sock){
+       set_error( STATUS_INVALID_HANDLE );
+       return;
     }
+    sock->hListen = req->hListen;
+    release_object( &sock->obj );
+    set_error( STATUS_SUCCESS );
+    return;
 }
 
 /* set socket event parameters */
diff --git a/server/trace.c b/server/trace.c
index d24f653..fa23e00 100644 (file)
--- a/server/trace.c
+++ b/server/trace.c
@@ -1553,6 +1553,7 @@ static void dump_create_socket_reply( const struct create_socket_reply *req )
 static void dump_accept_socket_request( const struct accept_socket_request *req )
 {
     fprintf( stderr, " lhandle=%04x", req->lhandle );
+    fprintf( stderr, ", ahandle=%04x", req->ahandle );
     fprintf( stderr, ", access=%08x", req->access );
     fprintf( stderr, ", attributes=%08x", req->attributes );
 }
@@ -1571,6 +1572,12 @@ static void dump_set_socket_event_request( const struct set_socket_event_request
     fprintf( stderr, ", msg=%08x", req->msg );
 }
 
+static void dump_set_socket_listener_request( const struct set_socket_listener_request *req )
+{
+    fprintf( stderr, " handle=%04x", req->handle );
+    fprintf( stderr, ", hListen=%04x", req->hListen );
+}
+
 static void dump_get_socket_event_request( const struct get_socket_event_request *req )
 {
     fprintf( stderr, " handle=%04x", req->handle );
@@ -2565,6 +2572,15 @@ static void dump_register_async_request( const struct register_async_request *re
     fprintf( stderr, ", count=%d", req->count );
 }
 
+static void dump_register_async_l_request( const struct register_async_l_request *req )
+{
+    fprintf( stderr, " handle=%04x", req->handle );
+    fprintf( stderr, ", type=%d", req->type );
+    fprintf( stderr, ", count=%d", req->count );
+    fprintf( stderr, ", locator=%04x", req->locator );
+    dump_async_data( ", async=", &req->async );
+}
+
 static void dump_cancel_async_request( const struct cancel_async_request *req )
 {
     fprintf( stderr, " handle=%04x", req->handle );
@@ -3857,6 +3873,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)dump_create_socket_request,
     (dump_func)dump_accept_socket_request,
     (dump_func)dump_set_socket_event_request,
+    (dump_func)dump_set_socket_listener_request,
     (dump_func)dump_get_socket_event_request,
     (dump_func)dump_enable_socket_event_request,
     (dump_func)dump_set_socket_deferred_request,
@@ -3947,6 +3964,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)dump_get_serial_info_request,
     (dump_func)dump_set_serial_info_request,
     (dump_func)dump_register_async_request,
+    (dump_func)dump_register_async_l_request,
     (dump_func)dump_cancel_async_request,
     (dump_func)dump_ioctl_request,
     (dump_func)dump_get_ioctl_result_request,
@@ -4098,6 +4116,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)dump_create_socket_reply,
     (dump_func)dump_accept_socket_reply,
     NULL,
+    NULL,
     (dump_func)dump_get_socket_event_reply,
     NULL,
     NULL,
@@ -4189,6 +4208,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
     NULL,
     NULL,
     NULL,
+    NULL,
     (dump_func)dump_ioctl_reply,
     (dump_func)dump_get_ioctl_result_reply,
     (dump_func)dump_create_named_pipe_reply,
@@ -4339,6 +4359,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
     "create_socket",
     "accept_socket",
     "set_socket_event",
+    "set_socket_listener",
     "get_socket_event",
     "enable_socket_event",
     "set_socket_deferred",
@@ -4429,6 +4450,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
     "get_serial_info",
     "set_serial_info",
     "register_async",
+    "register_async_l",
     "cancel_async",
     "ioctl",
     "get_ioctl_result",
diff --git a/tools/make_requests b/tools/make_requests
index e7a1ffb..d3a517b 100755 (executable)
--- a/tools/make_requests
+++ b/tools/make_requests
@@ -59,7 +59,7 @@ my @asserts = ();
 
 my @trace_lines = ();
 
-my $max_req_size = 64;
+my $max_req_size = 80;
 
 my $warnings = scalar(@ARGV) && $ARGV[0] eq "-w";