nsiproxy: Wait for an icmp reply.

This patch doesn't yet recv() that reply.

Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Huw Davies 2021-10-05 07:37:50 +01:00 committed by Alexandre Julliard
parent be0765ac26
commit aa73a91125
5 changed files with 76 additions and 2 deletions

View File

@ -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, &params );
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 );

View File

@ -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;

View File

@ -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,

View File

@ -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
{

View File

@ -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;