This patch doesn't yet recv() that reply.
Signed-off-by: Huw Davies huw@codeweavers.com --- 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, ¶ms ); + 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;