[PATCH 3/5] nsiproxy: Introduce IOCTL_NSIPROXY_WINE_ICMP_ECHO.
Huw Davies
huw at codeweavers.com
Mon Oct 4 06:23:20 CDT 2021
With this patch the irp is simply marked as pending and transferred to
the request thread which completes the irp with STATUS_NOT_SUPPORTED.
Signed-off-by: Huw Davies <huw at codeweavers.com>
---
dlls/nsiproxy.sys/device.c | 103 +++++++++++++++++++++++++++++++++++++
include/wine/nsi.h | 34 ++++++++++++
2 files changed, 137 insertions(+)
diff --git a/dlls/nsiproxy.sys/device.c b/dlls/nsiproxy.sys/device.c
index fb330ddfc93..f4cefd4b794 100644
--- a/dlls/nsiproxy.sys/device.c
+++ b/dlls/nsiproxy.sys/device.c
@@ -36,6 +36,18 @@
WINE_DEFAULT_DEBUG_CHANNEL(nsi);
static unixlib_handle_t nsiproxy_handle;
+static HANDLE request_event;
+
+#define DECLARE_CRITICAL_SECTION(cs) \
+ static CRITICAL_SECTION cs; \
+ static CRITICAL_SECTION_DEBUG cs##_debug = \
+ { 0, 0, &cs, { &cs##_debug.ProcessLocksList, &cs##_debug.ProcessLocksList }, \
+ 0, 0, { (DWORD_PTR)(__FILE__ ": " # cs) }}; \
+ static CRITICAL_SECTION cs = { &cs##_debug, -1, 0, 0, 0, 0 };
+DECLARE_CRITICAL_SECTION( nsiproxy_cs );
+
+#define LIST_ENTRY_INIT( list ) { .Flink = &(list), .Blink = &(list) }
+static LIST_ENTRY request_queue = LIST_ENTRY_INIT( request_queue );
static NTSTATUS nsiproxy_call( unsigned int code, void *args )
{
@@ -162,6 +174,59 @@ static NTSTATUS nsiproxy_get_parameter( IRP *irp )
return status;
}
+static void WINAPI icmp_echo_cancel( DEVICE_OBJECT *device, IRP *irp )
+{
+ TRACE( "device %p, irp %p.\n", device, irp );
+
+ IoReleaseCancelSpinLock( irp->CancelIrql );
+
+ /* FIXME: at the moment just let the request thread bail */
+ return;
+}
+
+static NTSTATUS nsiproxy_icmp_echo( IRP *irp )
+{
+ IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp );
+ struct nsiproxy_icmp_echo *in = (struct nsiproxy_icmp_echo *)irp->AssociatedIrp.SystemBuffer;
+ DWORD in_len = irpsp->Parameters.DeviceIoControl.InputBufferLength;
+ DWORD out_len = irpsp->Parameters.DeviceIoControl.OutputBufferLength;
+
+ TRACE( "\n" );
+
+ if (in_len < offsetof(struct nsiproxy_icmp_echo, data[0]) ||
+ in_len < offsetof(struct nsiproxy_icmp_echo, data[((in->opt_size + 3) & ~3) + in->req_size]) ||
+ out_len < sizeof(struct nsiproxy_icmp_echo_reply))
+ return STATUS_INVALID_PARAMETER;
+
+ switch (in->dst.si_family)
+ {
+ case AF_INET:
+ if (in->dst.Ipv4.sin_addr.s_addr == INADDR_ANY) return STATUS_INVALID_ADDRESS_WILDCARD;
+ break;
+ default:
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ EnterCriticalSection( &nsiproxy_cs );
+
+ IoSetCancelRoutine( irp, icmp_echo_cancel );
+ if (irp->Cancel && !IoSetCancelRoutine( irp, NULL ))
+ {
+ /* IRP was canceled before we set cancel routine */
+ InitializeListHead( &irp->Tail.Overlay.ListEntry );
+ LeaveCriticalSection( &nsiproxy_cs );
+ return STATUS_CANCELLED;
+ }
+
+ InsertTailList( &request_queue, &irp->Tail.Overlay.ListEntry );
+ IoMarkIrpPending( irp );
+
+ LeaveCriticalSection( &nsiproxy_cs );
+ SetEvent( request_event );
+
+ return STATUS_PENDING;
+}
+
static NTSTATUS WINAPI nsi_ioctl( DEVICE_OBJECT *device, IRP *irp )
{
IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp );
@@ -186,6 +251,10 @@ static NTSTATUS WINAPI nsi_ioctl( DEVICE_OBJECT *device, IRP *irp )
status = nsiproxy_get_parameter( irp );
break;
+ case IOCTL_NSIPROXY_WINE_ICMP_ECHO:
+ status = nsiproxy_icmp_echo( irp );
+ break;
+
default:
FIXME( "ioctl %x not supported\n", irpsp->Parameters.DeviceIoControl.IoControlCode );
status = STATUS_NOT_SUPPORTED;
@@ -220,10 +289,40 @@ static int add_device( DRIVER_OBJECT *driver )
return 1;
}
+static DWORD WINAPI request_thread_proc( void *arg )
+{
+ LIST_ENTRY *entry;
+
+ while (WaitForSingleObject( request_event, INFINITE ) == WAIT_OBJECT_0)
+ {
+ TRACE( "request_event triggered\n" );
+ EnterCriticalSection( &nsiproxy_cs );
+ while ((entry = RemoveHeadList( &request_queue )) != &request_queue )
+ {
+ IRP *irp = CONTAINING_RECORD( entry, IRP, Tail.Overlay.ListEntry );
+
+ if (irp->Cancel)
+ {
+ irp->IoStatus.Status = STATUS_CANCELLED;
+ TRACE( "already cancelled\n" );
+ IoCompleteRequest( irp, IO_NO_INCREMENT );
+ continue;
+ }
+
+ /* FIXME */
+ irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
+ IoCompleteRequest( irp, IO_NO_INCREMENT );
+ }
+ LeaveCriticalSection( &nsiproxy_cs );
+ }
+ return 0;
+}
+
NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path )
{
HMODULE instance;
NTSTATUS status;
+ HANDLE thread;
TRACE( "(%p, %s)\n", driver, debugstr_w( path->Buffer ) );
@@ -236,5 +335,9 @@ NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path )
add_device( driver );
+ request_event = CreateEventW( NULL, FALSE, FALSE, NULL );
+ thread = CreateThread( NULL, 0, request_thread_proc, NULL, 0, NULL );
+ CloseHandle( thread );
+
return STATUS_SUCCESS;
}
diff --git a/include/wine/nsi.h b/include/wine/nsi.h
index 7b8cb29e9d5..9664b534b09 100644
--- a/include/wine/nsi.h
+++ b/include/wine/nsi.h
@@ -380,6 +380,7 @@ struct nsi_udp_endpoint_static
#define IOCTL_NSIPROXY_WINE_ENUMERATE_ALL CTL_CODE(FILE_DEVICE_NETWORK, 0x400, METHOD_BUFFERED, 0)
#define IOCTL_NSIPROXY_WINE_GET_ALL_PARAMETERS CTL_CODE(FILE_DEVICE_NETWORK, 0x401, METHOD_BUFFERED, 0)
#define IOCTL_NSIPROXY_WINE_GET_PARAMETER CTL_CODE(FILE_DEVICE_NETWORK, 0x402, METHOD_BUFFERED, 0)
+#define IOCTL_NSIPROXY_WINE_ICMP_ECHO CTL_CODE(FILE_DEVICE_NETWORK, 0x403, METHOD_BUFFERED, 0)
/* input for IOCTL_NSIPROXY_WINE_ENUMERATE_ALL */
struct nsiproxy_enumerate_all
@@ -420,6 +421,39 @@ struct nsiproxy_get_parameter
BYTE key[1]; /* key_size */
};
+/* input for IOCTL_NSIPROXY_WINE_ICMP_ECHO */
+struct nsiproxy_icmp_echo
+{
+ SOCKADDR_INET src;
+ SOCKADDR_INET dst;
+ BYTE ttl;
+ BYTE tos;
+ BYTE flags;
+ DWORD opt_size;
+ DWORD req_size;
+ DWORD timeout;
+ BYTE data[1]; /* ((opt_size + 3) & ~3) + req_size */
+};
+
+/* output for IOCTL_NSIPROXY_WINE_ICMP_ECHO - cf. ICMP_ECHO_REPLY */
+struct nsiproxy_icmp_echo_reply
+{
+ SOCKADDR_INET addr;
+ ULONG status;
+ ULONG round_trip_time;
+ USHORT data_size;
+ USHORT num_of_pkts;
+ DWORD data_offset;
+ struct
+ {
+ BYTE ttl;
+ BYTE tos;
+ BYTE flags;
+ BYTE options_size;
+ DWORD options_offset;
+ } opts;
+};
+
/* Undocumented Nsi api */
#define NSI_PARAM_TYPE_RW 0
--
2.23.0
More information about the wine-devel
mailing list