This represents the state of the icmp request for use on the PE-side.
Signed-off-by: Huw Davies huw@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;