Huw Davies : nsiproxy: Wait for an icmp reply.

Alexandre Julliard julliard at winehq.org
Tue Oct 5 15:51:40 CDT 2021


Module: wine
Branch: master
Commit: aa73a91125b985d8bac17567282e6a55ec3d051d
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=aa73a91125b985d8bac17567282e6a55ec3d051d

Author: Huw Davies <huw at codeweavers.com>
Date:   Tue Oct  5 07:37:50 2021 +0100

nsiproxy: Wait for an icmp reply.

This patch doesn't yet recv() that reply.

Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/nsiproxy.sys/device.c           | 19 ++++++++++++--
 dlls/nsiproxy.sys/icmp_echo.c        | 50 ++++++++++++++++++++++++++++++++++++
 dlls/nsiproxy.sys/nsi.c              |  1 +
 dlls/nsiproxy.sys/nsiproxy_private.h |  7 +++++
 dlls/nsiproxy.sys/unix_private.h     |  1 +
 5 files changed, 76 insertions(+), 2 deletions(-)

diff --git a/dlls/nsiproxy.sys/device.c b/dlls/nsiproxy.sys/device.c
index 0cd168946cb..6461071c395 100644
--- a/dlls/nsiproxy.sys/device.c
+++ b/dlls/nsiproxy.sys/device.c
@@ -59,6 +59,7 @@ static NTSTATUS nsiproxy_call( unsigned int code, void *args )
 enum unix_calls
 {
     icmp_close,
+    icmp_listen,
     icmp_send_echo,
     nsi_enumerate_all_ex,
     nsi_get_all_parameters_ex,
@@ -306,16 +307,30 @@ static int add_device( DRIVER_OBJECT *driver )
 static DWORD WINAPI listen_thread_proc( void *arg )
 {
     IRP *irp = arg;
+    IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp );
+    struct nsiproxy_icmp_echo *in = irp->AssociatedIrp.SystemBuffer;
+    struct icmp_listen_params params;
+    NTSTATUS status;
 
     TRACE( "\n" );
 
-    /* FIXME */
+    params.handle = irp_get_icmp_handle( irp );
+    params.timeout = in->timeout;
+    params.reply = irp->AssociatedIrp.SystemBuffer;
+    params.reply_len = irpsp->Parameters.DeviceIoControl.OutputBufferLength;
+
+    status = nsiproxy_call( icmp_listen, &params );
+    TRACE( "icmp_listen rets %08x\n", status );
 
     EnterCriticalSection( &nsiproxy_cs );
 
     nsiproxy_call( icmp_close, irp_set_icmp_handle( irp, NULL ) );
 
-    irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
+    irp->IoStatus.Status = status;
+    if (status == STATUS_SUCCESS)
+        irp->IoStatus.Information = params.reply_len;
+    else
+        irp->IoStatus.Information = 0;
     IoCompleteRequest( irp, IO_NO_INCREMENT );
 
     LeaveCriticalSection( &nsiproxy_cs );
diff --git a/dlls/nsiproxy.sys/icmp_echo.c b/dlls/nsiproxy.sys/icmp_echo.c
index 90a779fb67e..afb48fc72e3 100644
--- a/dlls/nsiproxy.sys/icmp_echo.c
+++ b/dlls/nsiproxy.sys/icmp_echo.c
@@ -31,6 +31,7 @@
 #include <errno.h>
 #include <limits.h>
 #include <pthread.h>
+#include <poll.h>
 
 #ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
@@ -382,6 +383,55 @@ NTSTATUS icmp_send_echo( void *args )
     return params->handle ? STATUS_PENDING : STATUS_NO_MEMORY;
 }
 
+static NTSTATUS set_reply_ip_status( struct icmp_listen_params *params, IP_STATUS ip_status )
+{
+    struct nsiproxy_icmp_echo_reply *reply = params->reply;
+
+    memset( reply, 0, sizeof(*reply) );
+    reply->status = ip_status;
+    params->reply_len = sizeof(*reply);
+    return STATUS_SUCCESS;
+}
+
+static int get_timeout( LARGE_INTEGER start, DWORD timeout )
+{
+    LARGE_INTEGER now, end;
+
+    end.QuadPart = start.QuadPart + (ULONGLONG)timeout * 10000;
+    NtQueryPerformanceCounter( &now, NULL );
+    if (now.QuadPart >= end.QuadPart) return 0;
+
+    return min( (end.QuadPart - now.QuadPart) / 10000, INT_MAX );
+}
+
+NTSTATUS icmp_listen( void *args )
+{
+    struct icmp_listen_params *params = args;
+    struct icmp_data *data;
+    struct pollfd fds[1];
+    int ret;
+
+    data = handle_data( params->handle );
+    if (!data) return STATUS_INVALID_PARAMETER;
+
+    fds[0].fd = data->socket;
+    fds[0].events = POLLIN;
+
+    while ((ret = poll( fds, ARRAY_SIZE(fds), get_timeout( data->send_time, params->timeout ) )) > 0)
+    {
+        /* FIXME */
+        return STATUS_NOT_SUPPORTED;
+    }
+
+    if (!ret) /* timeout */
+    {
+        TRACE( "timeout\n" );
+        return set_reply_ip_status( params, IP_REQ_TIMED_OUT );
+    }
+    /* ret < 0 */
+    return set_reply_ip_status( params, errno_to_ip_status( errno ) );
+}
+
 NTSTATUS icmp_close( void *args )
 {
     HANDLE handle = args;
diff --git a/dlls/nsiproxy.sys/nsi.c b/dlls/nsiproxy.sys/nsi.c
index dec66ad6a33..b92de7a9a11 100644
--- a/dlls/nsiproxy.sys/nsi.c
+++ b/dlls/nsiproxy.sys/nsi.c
@@ -148,6 +148,7 @@ static NTSTATUS unix_nsi_get_parameter_ex( void *args )
 const unixlib_entry_t __wine_unix_call_funcs[] =
 {
     icmp_close,
+    icmp_listen,
     icmp_send_echo,
     unix_nsi_enumerate_all_ex,
     unix_nsi_get_all_parameters_ex,
diff --git a/dlls/nsiproxy.sys/nsiproxy_private.h b/dlls/nsiproxy.sys/nsiproxy_private.h
index b40a6198c7c..91dd393e41e 100644
--- a/dlls/nsiproxy.sys/nsiproxy_private.h
+++ b/dlls/nsiproxy.sys/nsiproxy_private.h
@@ -17,6 +17,13 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
+struct icmp_listen_params
+{
+    HANDLE handle;
+    void *reply;
+    unsigned int reply_len;
+    int timeout;
+};
 
 struct icmp_send_echo_params
 {
diff --git a/dlls/nsiproxy.sys/unix_private.h b/dlls/nsiproxy.sys/unix_private.h
index 7f81336e3f1..855c06011f9 100644
--- a/dlls/nsiproxy.sys/unix_private.h
+++ b/dlls/nsiproxy.sys/unix_private.h
@@ -158,4 +158,5 @@ static inline int ascii_strcasecmp( const char *s1, const char *s2 )
 }
 
 NTSTATUS icmp_close( void *args ) DECLSPEC_HIDDEN;
+NTSTATUS icmp_listen( void *args ) DECLSPEC_HIDDEN;
 NTSTATUS icmp_send_echo( void *args ) DECLSPEC_HIDDEN;




More information about the wine-cvs mailing list