[PATCH 4/5] mountmgr.sys: Implement IOCTL_NDIS_QUERY_GLOBAL_STATS on network cards.

Isabella Bosia ibosia at codeweavers.com
Tue Aug 25 09:32:24 CDT 2020


Signed-off-by: Isabella Bosia <ibosia at 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;
-- 
2.25.1




More information about the wine-devel mailing list