[PATCH 2/5] nsiproxy: Wait for an icmp reply.
Huw Davies
huw at codeweavers.com
Tue Oct 5 01:37:50 CDT 2021
This patch doesn't yet recv() that reply.
Signed-off-by: Huw Davies <huw at 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;
--
2.23.0
More information about the wine-devel
mailing list