From 8f7f4f13279d26badf326f4667404074a962378d Mon Sep 17 00:00:00 2001 From: Huw Davies Date: Thu, 1 Jul 2021 09:27:06 +0100 Subject: [PATCH] nsiproxy: Introduce IOCTL_NSIPROXY_WINE_GET_PARAMETER. Signed-off-by: Huw Davies Signed-off-by: Alexandre Julliard --- dlls/nsiproxy.sys/device.c | 37 ++++++++++++++++++++++++++++ dlls/nsiproxy.sys/nsi.c | 18 ++++++++++++++ dlls/nsiproxy.sys/nsiproxy_private.h | 3 +++ include/wine/nsi.h | 13 ++++++++++ 4 files changed, 71 insertions(+) diff --git a/dlls/nsiproxy.sys/device.c b/dlls/nsiproxy.sys/device.c index 88c65ff4602..aa1d7a08bf7 100644 --- a/dlls/nsiproxy.sys/device.c +++ b/dlls/nsiproxy.sys/device.c @@ -123,6 +123,39 @@ static void nsiproxy_get_all_parameters( IRP *irp ) irp->IoStatus.Information = (irp->IoStatus.u.Status == STATUS_SUCCESS) ? out_len : 0; } +static void nsiproxy_get_parameter( IRP *irp ) +{ + IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp ); + struct nsiproxy_get_parameter *in = (struct nsiproxy_get_parameter *)irp->AssociatedIrp.SystemBuffer; + DWORD in_len = irpsp->Parameters.DeviceIoControl.InputBufferLength; + void *out = irp->AssociatedIrp.SystemBuffer; + DWORD out_len = irpsp->Parameters.DeviceIoControl.OutputBufferLength; + struct nsi_get_parameter_ex get_param; + + if (in_len < FIELD_OFFSET(struct nsiproxy_get_parameter, key[0]) || + in_len < FIELD_OFFSET(struct nsiproxy_get_parameter, key[in->key_size])) + { + irp->IoStatus.u.Status = STATUS_INVALID_PARAMETER; + return; + } + + get_param.unknown[0] = 0; + get_param.unknown[1] = 0; + get_param.first_arg = in->first_arg; + get_param.unknown2 = 0; + get_param.module = &in->module; + get_param.table = in->table; + get_param.key = in->key; + get_param.key_size = in->key_size; + get_param.param_type = in->param_type; + get_param.data = out; + get_param.data_size = out_len; + get_param.data_offset = in->data_offset; + + irp->IoStatus.u.Status = nsi_get_parameter_ex( &get_param ); + irp->IoStatus.Information = irp->IoStatus.u.Status == STATUS_SUCCESS ? out_len : 0; +} + static NTSTATUS WINAPI nsi_ioctl( DEVICE_OBJECT *device, IRP *irp ) { IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp ); @@ -142,6 +175,10 @@ static NTSTATUS WINAPI nsi_ioctl( DEVICE_OBJECT *device, IRP *irp ) nsiproxy_get_all_parameters( irp ); break; + case IOCTL_NSIPROXY_WINE_GET_PARAMETER: + nsiproxy_get_parameter( irp ); + break; + default: FIXME( "ioctl %x not supported\n", irpsp->Parameters.DeviceIoControl.IoControlCode ); irp->IoStatus.u.Status = STATUS_NOT_SUPPORTED; diff --git a/dlls/nsiproxy.sys/nsi.c b/dlls/nsiproxy.sys/nsi.c index 2bd8f32fdd7..e4286b5fc93 100644 --- a/dlls/nsiproxy.sys/nsi.c +++ b/dlls/nsiproxy.sys/nsi.c @@ -99,3 +99,21 @@ NTSTATUS nsi_get_all_parameters_ex( struct nsi_get_all_parameters_ex *params ) return entry->get_all_parameters( params->key, params->key_size, rw, params->rw_size, dyn, params->dynamic_size, stat, params->static_size ); } + +NTSTATUS nsi_get_parameter_ex( struct nsi_get_parameter_ex *params ) +{ + const struct module_table *entry = get_module_table( params->module, params->table ); + + if (!entry || !entry->get_parameter) + { + WARN( "table not found\n" ); + return STATUS_INVALID_PARAMETER; + } + + if (params->param_type > 2) return STATUS_INVALID_PARAMETER; + if (params->key_size != entry->sizes[0]) return STATUS_INVALID_PARAMETER; + if (params->data_offset + params->data_size > entry->sizes[params->param_type + 1]) + return STATUS_INVALID_PARAMETER; + return entry->get_parameter( params->key, params->key_size, params->param_type, + params->data, params->data_size, params->data_offset ); +} diff --git a/dlls/nsiproxy.sys/nsiproxy_private.h b/dlls/nsiproxy.sys/nsiproxy_private.h index 37cbbd118c0..0cd2a79d59f 100644 --- a/dlls/nsiproxy.sys/nsiproxy_private.h +++ b/dlls/nsiproxy.sys/nsiproxy_private.h @@ -20,6 +20,7 @@ NTSTATUS nsi_enumerate_all_ex( struct nsi_enumerate_all_ex *params ) DECLSPEC_HIDDEN; NTSTATUS nsi_get_all_parameters_ex( struct nsi_get_all_parameters_ex *params ) DECLSPEC_HIDDEN; +NTSTATUS nsi_get_parameter_ex( struct nsi_get_parameter_ex *params ) DECLSPEC_HIDDEN; struct module_table { @@ -31,6 +32,8 @@ struct module_table NTSTATUS (*get_all_parameters)( const void *key, DWORD key_size, void *rw_data, DWORD rw_size, void *dynamic_data, DWORD dynamic_size, void *static_data, DWORD static_size ); + NTSTATUS (*get_parameter)( const void *key, DWORD key_size, DWORD param_type, + void *data, DWORD data_size, DWORD data_offset ); }; struct module diff --git a/include/wine/nsi.h b/include/wine/nsi.h index 82183d78190..3327b1f7403 100644 --- a/include/wine/nsi.h +++ b/include/wine/nsi.h @@ -98,6 +98,7 @@ struct nsi_ndis_ifinfo_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) /* input for IOCTL_NSIPROXY_WINE_ENUMERATE_ALL */ struct nsiproxy_enumerate_all @@ -126,6 +127,18 @@ struct nsiproxy_get_all_parameters BYTE key[1]; /* key_size */ }; +/* input for IOCTL_NSIPROXY_WINE_GET_PARAMETER */ +struct nsiproxy_get_parameter +{ + NPI_MODULEID module; + DWORD first_arg; + DWORD table; + DWORD key_size; + DWORD param_type; + DWORD data_offset; + BYTE key[1]; /* key_size */ +}; + /* Undocumented Nsi api */ #define NSI_PARAM_TYPE_RW 0