Signed-off-by: Isabella Bosia ibosia@codeweavers.com --- dlls/mountmgr.sys/ndis.c | 105 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+)
diff --git a/dlls/mountmgr.sys/ndis.c b/dlls/mountmgr.sys/ndis.c index 0a3f87d410..379d70e6d0 100644 --- a/dlls/mountmgr.sys/ndis.c +++ b/dlls/mountmgr.sys/ndis.c @@ -40,6 +40,86 @@
WINE_DEFAULT_DEBUG_CHANNEL(ndis);
+static void query_global_stats(IRP *irp, const MIB_IF_ROW2 *netdev) +{ + IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp ); + void *response = MmGetSystemAddressForMdlSafe( irp->MdlAddress, NormalPagePriority ); + DWORD len = irpsp->Parameters.DeviceIoControl.OutputBufferLength; + DWORD oid; + + if (irpsp->Parameters.DeviceIoControl.InputBufferLength != sizeof(oid)) + { + irp->IoStatus.u.Status = STATUS_INVALID_PARAMETER; + return; + } + oid = *(DWORD *)irp->AssociatedIrp.SystemBuffer; + + switch (oid) + { + case OID_GEN_MEDIA_SUPPORTED: + case OID_GEN_MEDIA_IN_USE: + { + if (len < sizeof(NDIS_MEDIUM)) + { + irp->IoStatus.u.Status = STATUS_INVALID_PARAMETER; + break; + } + *(NDIS_MEDIUM *)response = netdev->MediaType; + irp->IoStatus.Information = sizeof(netdev->MediaType); + irp->IoStatus.u.Status = STATUS_SUCCESS; + break; + } + case OID_802_3_PERMANENT_ADDRESS: + { + irp->IoStatus.Information = netdev->PhysicalAddressLength; + if (len < netdev->PhysicalAddressLength) + irp->IoStatus.u.Status = STATUS_INVALID_PARAMETER; + else + memcpy( response, netdev->PermanentPhysicalAddress, sizeof(netdev->PermanentPhysicalAddress) ); + break; + } + case OID_802_3_CURRENT_ADDRESS: + { + irp->IoStatus.Information = netdev->PhysicalAddressLength; + if (len < netdev->PhysicalAddressLength) + irp->IoStatus.u.Status = STATUS_INVALID_PARAMETER; + else + memcpy( response, netdev->PhysicalAddress, sizeof(netdev->PhysicalAddress) ); + break; + + } + default: + FIXME( "Unsupported OID %x\n", oid ); + irp->IoStatus.u.Status = STATUS_NOT_SUPPORTED; + break; + } +} + +static NTSTATUS WINAPI ndis_ioctl(DEVICE_OBJECT *device, IRP *irp) +{ + IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp ); + MIB_IF_ROW2 *netdev = device->DeviceExtension; + + TRACE( "ioctl %x insize %u outsize %u\n", + irpsp->Parameters.DeviceIoControl.IoControlCode, + irpsp->Parameters.DeviceIoControl.InputBufferLength, + irpsp->Parameters.DeviceIoControl.OutputBufferLength ); + + switch (irpsp->Parameters.DeviceIoControl.IoControlCode) + { + case IOCTL_NDIS_QUERY_GLOBAL_STATS: + query_global_stats(irp, netdev); + break; + default: + FIXME( "ioctl %x not supported\n", irpsp->Parameters.DeviceIoControl.IoControlCode ); + irp->IoStatus.u.Status = STATUS_NOT_SUPPORTED; + break; + } + + IoCompleteRequest( irp, IO_NO_INCREMENT ); + return STATUS_SUCCESS; +} + static void add_key(const char *guidstr, const MIB_IF_ROW2 *netdev) { HKEY card_key; @@ -61,6 +141,29 @@ static void add_key(const char *guidstr, const MIB_IF_ROW2 *netdev)
static int add_device(DRIVER_OBJECT *driver, const char *guidstr, MIB_IF_ROW2 *netdev) { + char data[300]; + ANSI_STRING nameA, linkA; + UNICODE_STRING nameW, linkW; + DEVICE_OBJECT *device; + NTSTATUS status; + + snprintf( data, sizeof(data), "\Device\%s", guidstr ); + RtlInitAnsiString( &nameA, data ); + RtlAnsiStringToUnicodeString( &nameW, &nameA, TRUE ); + + snprintf( data, sizeof(data), "\DosDevices\%s", guidstr ); + RtlInitAnsiString( &linkA, data ); + RtlAnsiStringToUnicodeString( &linkW, &linkA, TRUE ); + + if (!(status = IoCreateDevice( driver, sizeof(*netdev), &nameW, 0, 0, FALSE, &device ))) + status = IoCreateSymbolicLink( &linkW, &nameW ); + if (status) + { + FIXME( "failed to create device error %x\n", status ); + return 0; + } + + memcpy( device->DeviceExtension, netdev, sizeof(*netdev) ); return 1; }
@@ -92,6 +195,8 @@ NTSTATUS WINAPI ndis_driver_entry(DRIVER_OBJECT *driver, UNICODE_STRING *path) { TRACE("(%p, %s)\n", driver, debugstr_w(path->Buffer));
+ driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ndis_ioctl; + create_network_devices( driver );
return STATUS_SUCCESS;