diff --git a/dlls/nsiproxy.sys/device.c b/dlls/nsiproxy.sys/device.c index 4ce5ddd6d83..88c65ff4602 100644 --- a/dlls/nsiproxy.sys/device.c +++ b/dlls/nsiproxy.sys/device.c @@ -82,6 +82,47 @@ static void nsiproxy_enumerate_all( IRP *irp ) else irp->IoStatus.Information = 0; } +static void nsiproxy_get_all_parameters( IRP *irp ) +{ + IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp ); + struct nsiproxy_get_all_parameters *in = (struct nsiproxy_get_all_parameters *)irp->AssociatedIrp.SystemBuffer; + DWORD in_len = irpsp->Parameters.DeviceIoControl.InputBufferLength; + BYTE *out = irp->AssociatedIrp.SystemBuffer; + DWORD out_len = irpsp->Parameters.DeviceIoControl.OutputBufferLength; + struct nsi_get_all_parameters_ex get_all; + + if (in_len < FIELD_OFFSET(struct nsiproxy_get_all_parameters, key[0]) || + in_len < FIELD_OFFSET(struct nsiproxy_get_all_parameters, key[in->key_size])) + { + irp->IoStatus.u.Status = STATUS_INVALID_PARAMETER; + return; + } + + if (out_len < in->rw_size + in->dynamic_size + in->static_size) + { + irp->IoStatus.u.Status = STATUS_INVALID_PARAMETER; + return; + } + + get_all.unknown[0] = 0; + get_all.unknown[1] = 0; + get_all.first_arg = in->first_arg; + get_all.unknown2 = 0; + get_all.module = &in->module; + get_all.table = in->table; + get_all.key = in->key; + get_all.key_size = in->key_size; + get_all.rw_data = out; + get_all.rw_size = in->rw_size; + get_all.dynamic_data = out + in->rw_size; + get_all.dynamic_size = in->dynamic_size; + get_all.static_data = out + in->rw_size + in->dynamic_size; + get_all.static_size = in->static_size; + + irp->IoStatus.u.Status = nsi_get_all_parameters_ex( &get_all ); + 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 ); @@ -97,6 +138,10 @@ static NTSTATUS WINAPI nsi_ioctl( DEVICE_OBJECT *device, IRP *irp ) nsiproxy_enumerate_all( irp ); break; + case IOCTL_NSIPROXY_WINE_GET_ALL_PARAMETERS: + nsiproxy_get_all_parameters( 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 85b9be1e587..2bd8f32fdd7 100644 --- a/dlls/nsiproxy.sys/nsi.c +++ b/dlls/nsiproxy.sys/nsi.c @@ -74,3 +74,28 @@ NTSTATUS nsi_enumerate_all_ex( struct nsi_enumerate_all_ex *params ) return entry->enumerate_all( data[0], sizes[0], data[1], sizes[1], data[2], sizes[2], data[3], sizes[3], ¶ms->count ); } + +NTSTATUS nsi_get_all_parameters_ex( struct nsi_get_all_parameters_ex *params ) +{ + const struct module_table *entry = get_module_table( params->module, params->table ); + void *rw = params->rw_data; + void *dyn = params->dynamic_data; + void *stat = params->static_data; + + if (!entry || !entry->get_all_parameters) + { + WARN( "table not found\n" ); + return STATUS_INVALID_PARAMETER; + } + + if (params->key_size != entry->sizes[0]) return STATUS_INVALID_PARAMETER; + if (!params->rw_size) rw = NULL; + else if (params->rw_size != entry->sizes[1]) return STATUS_INVALID_PARAMETER; + if (!params->dynamic_size) dyn = NULL; + else if (params->dynamic_size != entry->sizes[2]) return STATUS_INVALID_PARAMETER; + if (!params->static_size) stat = NULL; + else if (params->static_size != entry->sizes[3]) return STATUS_INVALID_PARAMETER; + + return entry->get_all_parameters( params->key, params->key_size, rw, params->rw_size, + dyn, params->dynamic_size, stat, params->static_size ); +} diff --git a/dlls/nsiproxy.sys/nsiproxy_private.h b/dlls/nsiproxy.sys/nsiproxy_private.h index 6745dbc6b56..37cbbd118c0 100644 --- a/dlls/nsiproxy.sys/nsiproxy_private.h +++ b/dlls/nsiproxy.sys/nsiproxy_private.h @@ -19,6 +19,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; struct module_table { @@ -27,6 +28,9 @@ struct module_table NTSTATUS (*enumerate_all)( void *key_data, DWORD key_size, void *rw_data, DWORD rw_size, void *dynamic_data, DWORD dynamic_size, void *static_data, DWORD static_size, DWORD_PTR *count ); + 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 ); }; struct module diff --git a/include/wine/nsi.h b/include/wine/nsi.h index 799485fc284..82183d78190 100644 --- a/include/wine/nsi.h +++ b/include/wine/nsi.h @@ -97,6 +97,7 @@ struct nsi_ndis_ifinfo_static /* Wine specific ioctl interface */ #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) /* input for IOCTL_NSIPROXY_WINE_ENUMERATE_ALL */ struct nsiproxy_enumerate_all @@ -112,6 +113,19 @@ struct nsiproxy_enumerate_all DWORD count; }; +/* input for IOCTL_NSIPROXY_WINE_GET_ALL_PARAMETERS */ +struct nsiproxy_get_all_parameters +{ + NPI_MODULEID module; + DWORD first_arg; + DWORD table; + DWORD key_size; + DWORD rw_size; + DWORD dynamic_size; + DWORD static_size; + BYTE key[1]; /* key_size */ +}; + /* Undocumented Nsi api */ #define NSI_PARAM_TYPE_RW 0