This differs from native, which passes struct nsi_enumerate_all_ex directly and relies on the kernel being able to access the user-space addresses.
Signed-off-by: Huw Davies huw@codeweavers.com --- dlls/nsiproxy.sys/Makefile.in | 3 +- dlls/nsiproxy.sys/device.c | 54 ++++++++++++++++++++++++++++ dlls/nsiproxy.sys/nsi.c | 38 ++++++++++++++++++++ dlls/nsiproxy.sys/nsiproxy_private.h | 21 +++++++++++ include/wine/nsi.h | 20 +++++++++++ 5 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 dlls/nsiproxy.sys/nsi.c create mode 100644 dlls/nsiproxy.sys/nsiproxy_private.h
diff --git a/dlls/nsiproxy.sys/Makefile.in b/dlls/nsiproxy.sys/Makefile.in index d1913671f49..f382689d463 100644 --- a/dlls/nsiproxy.sys/Makefile.in +++ b/dlls/nsiproxy.sys/Makefile.in @@ -3,4 +3,5 @@ IMPORTS = ntoskrnl EXTRADLLFLAGS = -Wl,--subsystem,native
C_SRCS = \ - device.c + device.c \ + nsi.c diff --git a/dlls/nsiproxy.sys/device.c b/dlls/nsiproxy.sys/device.c index ecd584bd1cb..4ce5ddd6d83 100644 --- a/dlls/nsiproxy.sys/device.c +++ b/dlls/nsiproxy.sys/device.c @@ -28,10 +28,60 @@ #include "winternl.h" #include "winioctl.h" #include "ddk/wdm.h" +#include "ifdef.h" +#include "netiodef.h" +#include "wine/nsi.h" #include "wine/debug.h" +#include "nsiproxy_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(nsi);
+static void nsiproxy_enumerate_all( IRP *irp ) +{ + IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp ); + struct nsiproxy_enumerate_all *in = (struct nsiproxy_enumerate_all *)irp->AssociatedIrp.SystemBuffer; + DWORD in_len = irpsp->Parameters.DeviceIoControl.InputBufferLength; + void *out = irp->AssociatedIrp.SystemBuffer; + DWORD out_len = irpsp->Parameters.DeviceIoControl.OutputBufferLength; + struct nsi_enumerate_all_ex enum_all; + + if (in_len != sizeof(*in)) + { + irp->IoStatus.u.Status = STATUS_INVALID_PARAMETER; + return; + } + + if (out_len < sizeof(DWORD) + (in->key_size + in->rw_size + in->dynamic_size + in->static_size) * in->count) + { + irp->IoStatus.u.Status = STATUS_INVALID_PARAMETER; + return; + } + + enum_all.unknown[0] = 0; + enum_all.unknown[1] = 0; + enum_all.first_arg = in->first_arg; + enum_all.second_arg = in->second_arg; + enum_all.module = &in->module; + enum_all.table = in->table; + enum_all.key_data = (BYTE *)out + sizeof(DWORD); + enum_all.key_size = in->key_size; + enum_all.rw_data = (BYTE *)enum_all.key_data + in->key_size * in->count; + enum_all.rw_size = in->rw_size; + enum_all.dynamic_data = (BYTE *)enum_all.rw_data + in->rw_size * in->count; + enum_all.dynamic_size = in->dynamic_size; + enum_all.static_data = (BYTE *)enum_all.dynamic_data + in->dynamic_size * in->count; + enum_all.static_size = in->static_size; + enum_all.count = in->count; + + irp->IoStatus.u.Status = nsi_enumerate_all_ex( &enum_all ); + if (irp->IoStatus.u.Status == STATUS_SUCCESS || irp->IoStatus.u.Status == STATUS_MORE_ENTRIES) + { + irp->IoStatus.Information = out_len; + *(DWORD *)out = enum_all.count; + } + else irp->IoStatus.Information = 0; +} + static NTSTATUS WINAPI nsi_ioctl( DEVICE_OBJECT *device, IRP *irp ) { IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp ); @@ -43,6 +93,10 @@ static NTSTATUS WINAPI nsi_ioctl( DEVICE_OBJECT *device, IRP *irp )
switch (irpsp->Parameters.DeviceIoControl.IoControlCode) { + case IOCTL_NSIPROXY_WINE_ENUMERATE_ALL: + nsiproxy_enumerate_all( 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 new file mode 100644 index 00000000000..7ff36c093ba --- /dev/null +++ b/dlls/nsiproxy.sys/nsi.c @@ -0,0 +1,38 @@ +/* + * nsiproxy.sys + * + * Copyright 2021 Huw Davies + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <stdarg.h> + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "winternl.h" +#include "winioctl.h" +#include "ddk/wdm.h" +#include "ifdef.h" +#include "netiodef.h" +#include "wine/nsi.h" +#include "nsiproxy_private.h" + +NTSTATUS nsi_enumerate_all_ex( struct nsi_enumerate_all_ex *params ) +{ + return STATUS_NOT_IMPLEMENTED; +} diff --git a/dlls/nsiproxy.sys/nsiproxy_private.h b/dlls/nsiproxy.sys/nsiproxy_private.h new file mode 100644 index 00000000000..19b520d17cc --- /dev/null +++ b/dlls/nsiproxy.sys/nsiproxy_private.h @@ -0,0 +1,21 @@ +/* + * nsiproxy.sys + * + * Copyright 2021 Huw Davies + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +NTSTATUS nsi_enumerate_all_ex( struct nsi_enumerate_all_ex *params ) DECLSPEC_HIDDEN; diff --git a/include/wine/nsi.h b/include/wine/nsi.h index 31ece41d22f..799485fc284 100644 --- a/include/wine/nsi.h +++ b/include/wine/nsi.h @@ -19,6 +19,8 @@ #ifndef __WINE_NSI_H #define __WINE_NSI_H
+#include "winioctl.h" + /* Undocumented NSI NDIS tables */ #define NSI_NDIS_IFINFO_TABLE 0 #define NSI_NDIS_INDEX_LUID_TABLE 2 @@ -92,6 +94,24 @@ struct nsi_ndis_ifinfo_static DWORD phys_medium_type; };
+/* Wine specific ioctl interface */ + +#define IOCTL_NSIPROXY_WINE_ENUMERATE_ALL CTL_CODE(FILE_DEVICE_NETWORK, 0x400, METHOD_BUFFERED, 0) + +/* input for IOCTL_NSIPROXY_WINE_ENUMERATE_ALL */ +struct nsiproxy_enumerate_all +{ + NPI_MODULEID module; + DWORD first_arg; + DWORD second_arg; + DWORD table; + DWORD key_size; + DWORD rw_size; + DWORD dynamic_size; + DWORD static_size; + DWORD count; +}; + /* Undocumented Nsi api */
#define NSI_PARAM_TYPE_RW 0