Huw Davies : nsiproxy: Introduce a unix-side handle returned by icmp_send_echo().

Alexandre Julliard julliard at winehq.org
Mon Oct 4 15:42:18 CDT 2021


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

Author: Huw Davies <huw at codeweavers.com>
Date:   Mon Oct  4 12:23:22 2021 +0100

nsiproxy: Introduce a unix-side handle returned by icmp_send_echo().

This represents the state of the icmp request for use on the PE-side.

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

---

 dlls/nsiproxy.sys/device.c           | 10 ++++-
 dlls/nsiproxy.sys/icmp_echo.c        | 77 +++++++++++++++++++++++++++++++++++-
 dlls/nsiproxy.sys/nsi.c              |  1 +
 dlls/nsiproxy.sys/nsiproxy_private.h |  1 +
 dlls/nsiproxy.sys/unix_private.h     |  1 +
 5 files changed, 87 insertions(+), 3 deletions(-)

diff --git a/dlls/nsiproxy.sys/device.c b/dlls/nsiproxy.sys/device.c
index 5ae243a4111..cd0bc0e4db2 100644
--- a/dlls/nsiproxy.sys/device.c
+++ b/dlls/nsiproxy.sys/device.c
@@ -58,6 +58,7 @@ static NTSTATUS nsiproxy_call( unsigned int code, void *args )
 
 enum unix_calls
 {
+    icmp_close,
     icmp_send_echo,
     nsi_enumerate_all_ex,
     nsi_get_all_parameters_ex,
@@ -309,7 +310,7 @@ static void handle_queued_send_echo( IRP *irp )
     status = nsiproxy_call( icmp_send_echo, &params );
     TRACE( "icmp_send_echo rets %08x\n", status );
 
-    if (1)
+    if (status != STATUS_PENDING)
     {
         irp->IoStatus.Status = status;
         if (status == STATUS_SUCCESS)
@@ -320,6 +321,13 @@ static void handle_queued_send_echo( IRP *irp )
         }
         IoCompleteRequest( irp, IO_NO_INCREMENT );
     }
+    else
+    {
+        /* FIXME */
+        nsiproxy_call( icmp_close, params.handle );
+        irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
+        IoCompleteRequest( irp, IO_NO_INCREMENT );
+    }
 }
 
 static DWORD WINAPI request_thread_proc( void *arg )
diff --git a/dlls/nsiproxy.sys/icmp_echo.c b/dlls/nsiproxy.sys/icmp_echo.c
index 8ec506f823c..90a779fb67e 100644
--- a/dlls/nsiproxy.sys/icmp_echo.c
+++ b/dlls/nsiproxy.sys/icmp_echo.c
@@ -104,6 +104,68 @@ struct icmp_data
     const struct family_ops *ops;
 };
 
+#define MAX_HANDLES 256 /* Max number of simultaneous pings - could become dynamic if need be */
+static struct icmp_data *handle_table[MAX_HANDLES];
+static pthread_mutex_t handle_lock = PTHREAD_MUTEX_INITIALIZER;
+static struct icmp_data **next_free, **next_unused = handle_table;
+
+static HANDLE handle_alloc( struct icmp_data *data )
+{
+    struct icmp_data **entry;
+    HANDLE h;
+
+    pthread_mutex_lock( &handle_lock );
+    entry = next_free;
+    if (entry) next_free = *(struct icmp_data ***)entry;
+    else if (next_unused < handle_table + MAX_HANDLES) entry = next_unused++;
+    else
+    {
+        pthread_mutex_unlock( &handle_lock );
+        FIXME( "Exhausted icmp handle count\n" );
+        return 0;
+    }
+    *entry = data;
+    h = LongToHandle( entry - handle_table + 1 );
+    pthread_mutex_unlock( &handle_lock );
+    TRACE( "returning handle %p\n", h );
+    return h;
+}
+
+static struct icmp_data **handle_entry( HANDLE h )
+{
+    unsigned int idx = HandleToLong( h );
+
+    if (!idx || idx > MAX_HANDLES)
+    {
+        ERR( "Invalid icmp handle\n" );
+        return NULL;
+    }
+    return handle_table + idx - 1;
+}
+
+static struct icmp_data *handle_data( HANDLE h )
+{
+    struct icmp_data **entry = handle_entry( h );
+
+    if (!entry) return NULL;
+    return *entry;
+}
+
+static void handle_free( HANDLE h )
+{
+    struct icmp_data **entry;
+
+    TRACE( "%p\n", h );
+    pthread_mutex_lock( &handle_lock );
+    entry = handle_entry( h );
+    if (entry)
+    {
+        *(struct icmp_data ***)entry = next_free;
+        next_free = entry;
+    }
+    pthread_mutex_unlock( &handle_lock );
+}
+
 static void ipv4_init_icmp_hdr( struct icmp_data *data, struct icmp_hdr *icmp_hdr )
 {
     icmp_hdr->type = ICMP4_ECHO_REQUEST;
@@ -315,7 +377,18 @@ NTSTATUS icmp_send_echo( void *args )
         return STATUS_SUCCESS;
     }
 
-    /* FIXME */
+    params->handle = handle_alloc( data );
+    if (!params->handle) icmp_data_free( data );
+    return params->handle ? STATUS_PENDING : STATUS_NO_MEMORY;
+}
+
+NTSTATUS icmp_close( void *args )
+{
+    HANDLE handle = args;
+    struct icmp_data *data = handle_data( handle );
+
+    if (!data) return STATUS_INVALID_PARAMETER;
     icmp_data_free( data );
-    return STATUS_NOT_SUPPORTED;
+    handle_free( handle );
+    return STATUS_SUCCESS;
 }
diff --git a/dlls/nsiproxy.sys/nsi.c b/dlls/nsiproxy.sys/nsi.c
index 25219a1c3fe..dec66ad6a33 100644
--- a/dlls/nsiproxy.sys/nsi.c
+++ b/dlls/nsiproxy.sys/nsi.c
@@ -147,6 +147,7 @@ static NTSTATUS unix_nsi_get_parameter_ex( void *args )
 
 const unixlib_entry_t __wine_unix_call_funcs[] =
 {
+    icmp_close,
     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 9831998793d..b40a6198c7c 100644
--- a/dlls/nsiproxy.sys/nsiproxy_private.h
+++ b/dlls/nsiproxy.sys/nsiproxy_private.h
@@ -24,5 +24,6 @@ struct icmp_send_echo_params
     void *request;
     DWORD request_size;
     BYTE ttl, tos;
+    HANDLE handle;
     ULONG ip_status;
 };
diff --git a/dlls/nsiproxy.sys/unix_private.h b/dlls/nsiproxy.sys/unix_private.h
index 0dfe9e69dbc..7f81336e3f1 100644
--- a/dlls/nsiproxy.sys/unix_private.h
+++ b/dlls/nsiproxy.sys/unix_private.h
@@ -157,4 +157,5 @@ static inline int ascii_strcasecmp( const char *s1, const char *s2 )
     return ascii_strncasecmp( s1, s2, -1 );
 }
 
+NTSTATUS icmp_close( void *args ) DECLSPEC_HIDDEN;
 NTSTATUS icmp_send_echo( void *args ) DECLSPEC_HIDDEN;




More information about the wine-cvs mailing list