From bfb7d535af377cbe64fbbf1a24aeede87f4cfe35 Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Tue, 6 May 2014 15:43:52 -0600 Subject: [PATCH] Updated SIO_ADDRESS_LIST_CHANGE patches. --- debian/changelog | 4 + ...-side-support-for-the-interface-cha.patch} | 67 +++++++-------- ...d-support-for-SIO_ADDRESS_LIST_CHAN.patch} | 86 +++++++++++++------ ...-the-interface-change-notification-o.patch | 44 ++++++---- 4 files changed, 120 insertions(+), 81 deletions(-) rename patches/01-Address_Change_Notification/{0003-server-Add-socket-side-support-for-the-interface-cha.patch => 0002-server-Add-socket-side-support-for-the-interface-cha.patch} (69%) rename patches/01-Address_Change_Notification/{0002-server-Add-delayed-processing-for-socket-specific-io.patch => 0003-server-Add-blocked-support-for-SIO_ADDRESS_LIST_CHAN.patch} (57%) diff --git a/debian/changelog b/debian/changelog index 845946b6..39075332 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,7 @@ +wine-compholio (1.7.19) unstable; urgency=low + * Updated SIO_ADDRESS_LIST_CHANGE patches. + -- Erich E. Hoover Tue, 06 May 2014 15:42:32 -0600 + wine-compholio (1.7.18-1) unstable; urgency=low * Fix some issues on BSD systems. * Add additional patches to silence a few FIXMEs. diff --git a/patches/01-Address_Change_Notification/0003-server-Add-socket-side-support-for-the-interface-cha.patch b/patches/01-Address_Change_Notification/0002-server-Add-socket-side-support-for-the-interface-cha.patch similarity index 69% rename from patches/01-Address_Change_Notification/0003-server-Add-socket-side-support-for-the-interface-cha.patch rename to patches/01-Address_Change_Notification/0002-server-Add-socket-side-support-for-the-interface-cha.patch index 38bfe40b..9041c901 100644 --- a/patches/01-Address_Change_Notification/0003-server-Add-socket-side-support-for-the-interface-cha.patch +++ b/patches/01-Address_Change_Notification/0002-server-Add-socket-side-support-for-the-interface-cha.patch @@ -1,15 +1,15 @@ -From 69e77bd226057f486d1c076ccbebb963d3b750ee Mon Sep 17 00:00:00 2001 +From 864781654bfbb059a351fdcda6773e2857019278 Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" -Date: Thu, 3 Apr 2014 09:25:48 -0600 +Date: Tue, 6 May 2014 08:39:18 -0600 Subject: server: Add socket-side support for the interface change notification object. --- - server/sock.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 91 insertions(+), 1 deletion(-) + server/sock.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 86 insertions(+), 1 deletion(-) diff --git a/server/sock.c b/server/sock.c -index 05fc38b..20d022f 100644 +index 3eb1bdf..ad20a69 100644 --- a/server/sock.c +++ b/server/sock.c @@ -106,12 +106,18 @@ struct sock @@ -22,26 +22,26 @@ index 05fc38b..20d022f 100644 }; static void sock_dump( struct object *obj, int verbose ); -+static int sock_add_ifchange( struct sock *sock, const async_data_t *async_data ); ++static void sock_add_ifchange( struct sock *sock, const async_data_t *async_data ); static int sock_signaled( struct object *obj, struct wait_queue_entry *entry ); static struct fd *sock_get_fd( struct object *obj ); static void sock_destroy( struct object *obj ); -+static int sock_get_ifchange_q( struct sock *sock, struct async_queue **async_queue ); ++static struct async_queue *sock_get_ifchange_q( struct sock *sock ); +static void sock_destroy_ifchange_q( struct sock *sock ); static int sock_get_poll_events( struct fd *fd ); static void sock_poll_event( struct fd *fd, int event ); -@@ -539,7 +545,8 @@ obj_handle_t sock_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *a +@@ -529,7 +535,8 @@ obj_handle_t sock_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *a switch(code) { case WS_SIO_ADDRESS_LIST_CHANGE: - /* intentional fallthrough, not yet supported */ -+ error = sock_add_ifchange( sock, async_data ); -+ break; ++ sock_add_ifchange( sock, async_data ); ++ return 0; default: - error = STATUS_NOT_SUPPORTED; - break; -@@ -625,6 +632,7 @@ static void sock_destroy( struct object *obj ) + set_error( STATUS_NOT_SUPPORTED ); + return 0; +@@ -610,6 +617,7 @@ static void sock_destroy( struct object *obj ) free_async_queue( sock->read_q ); free_async_queue( sock->write_q ); @@ -49,7 +49,7 @@ index 05fc38b..20d022f 100644 if (sock->event) release_object( sock->event ); if (sock->fd) { -@@ -651,6 +659,8 @@ static void init_sock(struct sock *sock) +@@ -636,6 +644,8 @@ static void init_sock(struct sock *sock) sock->deferred = NULL; sock->read_q = NULL; sock->write_q = NULL; @@ -58,37 +58,37 @@ index 05fc38b..20d022f 100644 memset( sock->errors, 0, sizeof(sock->errors) ); } -@@ -939,6 +949,86 @@ static void sock_set_error(void) +@@ -924,6 +934,81 @@ static void sock_set_error(void) set_error( sock_get_ntstatus( errno ) ); } +/* add interface change notification to a socket */ -+static int sock_add_ifchange( struct sock *sock, const async_data_t *async_data ) ++static void sock_add_ifchange( struct sock *sock, const async_data_t *async_data ) +{ + struct async_queue *ifchange_q = NULL; + struct async *async; -+ int error; + -+ error = sock_get_ifchange_q( sock, &ifchange_q ); -+ if (error != STATUS_PENDING) -+ return error; ++ if (!(ifchange_q = sock_get_ifchange_q( sock ))) ++ return; + + if (!(async = create_async( current, ifchange_q, async_data ))) + { + if (!async_queued( ifchange_q )) + sock_destroy_ifchange_q( sock ); + -+ return STATUS_NO_MEMORY; ++ set_error( STATUS_NO_MEMORY ); ++ return; + } + + release_object( async ); -+ return error; ++ set_error( STATUS_PENDING ); +} + +/* stub ifchange object */ -+static int get_ifchange( struct object **obj ) ++static struct object *get_ifchange( void ) +{ -+ return STATUS_NOT_SUPPORTED; ++ set_error( STATUS_NOT_SUPPORTED ); ++ return NULL; +} + +/* stub ifchange add socket to list */ @@ -97,21 +97,16 @@ index 05fc38b..20d022f 100644 +} + +/* create a new ifchange queue for a specific socket or, if one already exists, reuse the existing one */ -+static int sock_get_ifchange_q( struct sock *sock, struct async_queue **async_queue ) ++static struct async_queue *sock_get_ifchange_q( struct sock *sock ) +{ + struct object *ifchange = NULL; + struct fd *fd; -+ int error; + + if (sock->ifchange_q) /* reuse existing ifchange_q for this socket */ -+ { -+ *async_queue = sock->ifchange_q; -+ return STATUS_PENDING; -+ } ++ return sock->ifchange_q; + -+ error = get_ifchange( &ifchange ); -+ if (error != STATUS_PENDING) -+ return error; ++ if (!(ifchange = get_ifchange())) ++ return NULL; + + /* create the ifchange notification queue */ + fd = ifchange->ops->get_fd( ifchange ); @@ -120,14 +115,14 @@ index 05fc38b..20d022f 100644 + if (!sock->ifchange_q) + { + release_object( ifchange ); -+ return STATUS_NO_MEMORY; ++ set_error( STATUS_NO_MEMORY ); ++ return NULL; + } + + /* add the socket to the ifchange notification list */ + ifchange_add_sock( ifchange, sock ); + sock->ifchange_obj = ifchange; -+ *async_queue = sock->ifchange_q; -+ return error; ++ return sock->ifchange_q; +} + +/* destroy an existing ifchange queue for a specific socket */ diff --git a/patches/01-Address_Change_Notification/0002-server-Add-delayed-processing-for-socket-specific-io.patch b/patches/01-Address_Change_Notification/0003-server-Add-blocked-support-for-SIO_ADDRESS_LIST_CHAN.patch similarity index 57% rename from patches/01-Address_Change_Notification/0002-server-Add-delayed-processing-for-socket-specific-io.patch rename to patches/01-Address_Change_Notification/0003-server-Add-blocked-support-for-SIO_ADDRESS_LIST_CHAN.patch index 29b1fbaf..9f91a1a1 100644 --- a/patches/01-Address_Change_Notification/0002-server-Add-delayed-processing-for-socket-specific-io.patch +++ b/patches/01-Address_Change_Notification/0003-server-Add-blocked-support-for-SIO_ADDRESS_LIST_CHAN.patch @@ -1,14 +1,14 @@ -From 45dfbd2ddb5ca2c64fcfd56392be9c55513abc4b Mon Sep 17 00:00:00 2001 +From c93a05ca0114b76c542f251de60b8c009e4a72b0 Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" -Date: Thu, 3 Apr 2014 09:23:02 -0600 -Subject: server: Add delayed processing for socket-specific ioctl(). +Date: Tue, 6 May 2014 08:44:59 -0600 +Subject: server: Add blocked support for SIO_ADDRESS_LIST_CHANGE ioctl(). --- server/event.c | 13 +++++++++++++ server/named_pipe.c | 13 ------------- server/object.h | 1 + - server/sock.c | 19 +++++++++++++++++-- - 4 files changed, 31 insertions(+), 15 deletions(-) + server/sock.c | 26 ++++++++++++++++++++------ + 4 files changed, 34 insertions(+), 19 deletions(-) diff --git a/server/event.c b/server/event.c index 4d3c562..0daa5b2 100644 @@ -71,44 +71,78 @@ index bb3ff21..bad162f 100644 extern struct keyed_event *get_keyed_event_obj( struct process *process, obj_handle_t handle, unsigned int access ); extern void pulse_event( struct event *event ); diff --git a/server/sock.c b/server/sock.c -index 3eb1bdf..05fc38b 100644 +index ad20a69..a8a5ac3 100644 --- a/server/sock.c +++ b/server/sock.c -@@ -523,17 +523,32 @@ obj_handle_t sock_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *a +@@ -112,7 +112,7 @@ struct sock + }; + + static void sock_dump( struct object *obj, int verbose ); +-static void sock_add_ifchange( struct sock *sock, const async_data_t *async_data ); ++static int sock_add_ifchange( struct sock *sock, const async_data_t *async_data ); + static int sock_signaled( struct object *obj, struct wait_queue_entry *entry ); + static struct fd *sock_get_fd( struct object *obj ); + static void sock_destroy( struct object *obj ); +@@ -529,14 +529,27 @@ obj_handle_t sock_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *a int blocking, const void *data, data_size_t size ) { struct sock *sock = get_fd_user( fd ); + obj_handle_t wait_handle = 0; + async_data_t new_data; -+ int error; assert( sock->obj.ops == &sock_ops ); -+ if (blocking) -+ { -+ if (!(wait_handle = alloc_wait_event( current->process ))) return 0; -+ new_data = *async_data; -+ new_data.event = wait_handle; -+ async_data = &new_data; -+ } switch(code) { case WS_SIO_ADDRESS_LIST_CHANGE: - /* intentional fallthrough, not yet supported */ - default: -- set_error( STATUS_NOT_SUPPORTED ); +- sock_add_ifchange( sock, async_data ); - return 0; -+ error = STATUS_NOT_SUPPORTED; -+ break; - } -+ set_error( error ); -+ if (error == STATUS_PENDING) ++ if (blocking) ++ { ++ if (!(wait_handle = alloc_wait_event( current->process ))) return 0; ++ new_data = *async_data; ++ new_data.event = wait_handle; ++ async_data = &new_data; ++ } ++ if (!sock_add_ifchange( sock, async_data ) && wait_handle) ++ { ++ close_handle( current->process, wait_handle ); ++ return 0; ++ } + return wait_handle; -+ close_handle( current->process, wait_handle ); -+ return 0; + default: + set_error( STATUS_NOT_SUPPORTED ); + return 0; +@@ -935,13 +948,13 @@ static void sock_set_error(void) } - static void sock_queue_async( struct fd *fd, const async_data_t *data, int type, int count ) + /* add interface change notification to a socket */ +-static void sock_add_ifchange( struct sock *sock, const async_data_t *async_data ) ++static int sock_add_ifchange( struct sock *sock, const async_data_t *async_data ) + { + struct async_queue *ifchange_q = NULL; + struct async *async; + + if (!(ifchange_q = sock_get_ifchange_q( sock ))) +- return; ++ return FALSE; + + if (!(async = create_async( current, ifchange_q, async_data ))) + { +@@ -949,11 +962,12 @@ static void sock_add_ifchange( struct sock *sock, const async_data_t *async_data + sock_destroy_ifchange_q( sock ); + + set_error( STATUS_NO_MEMORY ); +- return; ++ return FALSE; + } + + release_object( async ); + set_error( STATUS_PENDING ); ++ return TRUE; + } + + /* stub ifchange object */ -- 1.7.9.5 diff --git a/patches/01-Address_Change_Notification/0004-server-Implement-the-interface-change-notification-o.patch b/patches/01-Address_Change_Notification/0004-server-Implement-the-interface-change-notification-o.patch index a346c4b3..fe42859f 100644 --- a/patches/01-Address_Change_Notification/0004-server-Implement-the-interface-change-notification-o.patch +++ b/patches/01-Address_Change_Notification/0004-server-Implement-the-interface-change-notification-o.patch @@ -1,14 +1,14 @@ -From 85d0475a493be336c340f25cab9895846e202f26 Mon Sep 17 00:00:00 2001 +From 55c83dc866e2d0e2cdc15b976b6d818a03ef4b89 Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" -Date: Thu, 3 Apr 2014 09:26:34 -0600 +Date: Tue, 6 May 2014 08:49:52 -0600 Subject: server: Implement the interface change notification object. --- - server/sock.c | 200 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 198 insertions(+), 2 deletions(-) + server/sock.c | 206 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 203 insertions(+), 3 deletions(-) diff --git a/server/sock.c b/server/sock.c -index 20d022f..82464f2 100644 +index a8a5ac3..2af9acc 100644 --- a/server/sock.c +++ b/server/sock.c @@ -43,6 +43,10 @@ @@ -22,11 +22,12 @@ index 20d022f..82464f2 100644 #include "ntstatus.h" #define WIN32_NO_STATUS -@@ -972,15 +976,207 @@ static int sock_add_ifchange( struct sock *sock, const async_data_t *async_data - return error; +@@ -970,16 +974,212 @@ static int sock_add_ifchange( struct sock *sock, const async_data_t *async_data + return TRUE; } -/* stub ifchange object */ +-static struct object *get_ifchange( void ) +#ifdef HAVE_LINUX_RTNETLINK_H + +/* only keep one ifchange object around, all sockets waiting for wakeups will look to it */ @@ -162,7 +163,7 @@ index 20d022f..82464f2 100644 +} + +static void ifchange_reselect_async( struct fd *fd, struct async_queue *queue ) -+{ + { + /* do nothing, this object is about to disappear */ +} + @@ -170,8 +171,8 @@ index 20d022f..82464f2 100644 + +/* we only need one of these interface notification objects, all of the sockets dependent upon + * it will wake up when a notification event occurs */ - static int get_ifchange( struct object **obj ) - { ++ static struct object *get_ifchange( void ) ++ { +#ifdef HAVE_LINUX_RTNETLINK_H + struct ifchange *ifchange; + struct sockaddr_nl addr; @@ -180,14 +181,16 @@ index 20d022f..82464f2 100644 + if (ifchange_object) + { + /* increment the refcount for each socket that uses the ifchange object */ -+ *obj = grab_object( ifchange_object ); -+ return STATUS_PENDING; ++ return grab_object( ifchange_object ); + } + + /* create the socket we need for processing interface change notifications */ + unix_fd = socket( PF_NETLINK, SOCK_RAW, NETLINK_ROUTE ); + if (unix_fd == -1) -+ return sock_get_ntstatus( errno ); ++ { ++ sock_set_error(); ++ return NULL; ++ } + fcntl( unix_fd, F_SETFL, O_NONBLOCK ); /* make socket nonblocking */ + memset( &addr, 0, sizeof(addr) ); + addr.nl_family = AF_NETLINK; @@ -196,27 +199,30 @@ index 20d022f..82464f2 100644 + if (bind( unix_fd, (struct sockaddr *)&addr, sizeof(addr) ) == -1) + { + close( unix_fd ); -+ return sock_get_ntstatus( errno ); ++ sock_set_error(); ++ return NULL; + } + if (!(ifchange = alloc_object( &ifchange_ops ))) + { + close( unix_fd ); -+ return STATUS_NO_MEMORY; ++ set_error( STATUS_NO_MEMORY ); ++ return NULL; + } + list_init( &ifchange->sockets ); + if (!(ifchange->fd = create_anonymous_fd( &ifchange_fd_ops, unix_fd, &ifchange->obj, 0 ))) + { + release_object( ifchange ); -+ return STATUS_NO_MEMORY; ++ set_error( STATUS_NO_MEMORY ); ++ return NULL; + } + set_fd_events( ifchange->fd, POLLIN ); /* enable read wakeup on the file descriptor */ + + /* the ifchange object is now successfully configured */ + ifchange_object = &ifchange->obj; -+ *obj = &ifchange->obj; -+ return STATUS_PENDING; ++ return &ifchange->obj; +#else - return STATUS_NOT_SUPPORTED; + set_error( STATUS_NOT_SUPPORTED ); + return NULL; +#endif }