nsiproxy: Introduce IOCTL_NSIPROXY_WINE_ICMP_ECHO.
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@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
7ed25b6c16
commit
f59a64144b
|
@ -36,6 +36,18 @@
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(nsi);
|
WINE_DEFAULT_DEBUG_CHANNEL(nsi);
|
||||||
|
|
||||||
static unixlib_handle_t nsiproxy_handle;
|
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 )
|
static NTSTATUS nsiproxy_call( unsigned int code, void *args )
|
||||||
{
|
{
|
||||||
|
@ -162,6 +174,59 @@ static NTSTATUS nsiproxy_get_parameter( IRP *irp )
|
||||||
return status;
|
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 )
|
static NTSTATUS WINAPI nsi_ioctl( DEVICE_OBJECT *device, IRP *irp )
|
||||||
{
|
{
|
||||||
IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( 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 );
|
status = nsiproxy_get_parameter( irp );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case IOCTL_NSIPROXY_WINE_ICMP_ECHO:
|
||||||
|
status = nsiproxy_icmp_echo( irp );
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
FIXME( "ioctl %x not supported\n", irpsp->Parameters.DeviceIoControl.IoControlCode );
|
FIXME( "ioctl %x not supported\n", irpsp->Parameters.DeviceIoControl.IoControlCode );
|
||||||
status = STATUS_NOT_SUPPORTED;
|
status = STATUS_NOT_SUPPORTED;
|
||||||
|
@ -220,10 +289,40 @@ static int add_device( DRIVER_OBJECT *driver )
|
||||||
return 1;
|
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 )
|
NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path )
|
||||||
{
|
{
|
||||||
HMODULE instance;
|
HMODULE instance;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
|
HANDLE thread;
|
||||||
|
|
||||||
TRACE( "(%p, %s)\n", driver, debugstr_w( path->Buffer ) );
|
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 );
|
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;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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_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_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_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 */
|
/* input for IOCTL_NSIPROXY_WINE_ENUMERATE_ALL */
|
||||||
struct nsiproxy_enumerate_all
|
struct nsiproxy_enumerate_all
|
||||||
|
@ -420,6 +421,39 @@ struct nsiproxy_get_parameter
|
||||||
BYTE key[1]; /* key_size */
|
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 */
|
/* Undocumented Nsi api */
|
||||||
|
|
||||||
#define NSI_PARAM_TYPE_RW 0
|
#define NSI_PARAM_TYPE_RW 0
|
||||||
|
|
Loading…
Reference in New Issue