[PATCH 5/5] nsiproxy: Introduce a unix-side handle returned by icmp_send_echo().
Huw Davies
huw at codeweavers.com
Mon Oct 4 06:23:22 CDT 2021
This represents the state of the icmp request for use on the PE-side.
Signed-off-by: Huw Davies <huw at codeweavers.com>
---
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, ¶ms );
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;
--
2.23.0
More information about the wine-devel
mailing list