4 * Copyright 2014 Austin English
5 * Copyright 2016 André Hentschel
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #define WIN32_NO_STATUS
37 #include "wine/debug.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(ndis
);
41 static void query_global_stats(IRP
*irp
, const MIB_IF_ROW2
*netdev
)
43 IO_STACK_LOCATION
*irpsp
= IoGetCurrentIrpStackLocation( irp
);
44 void *response
= MmGetSystemAddressForMdlSafe( irp
->MdlAddress
, NormalPagePriority
);
45 DWORD len
= irpsp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
48 if (irpsp
->Parameters
.DeviceIoControl
.InputBufferLength
!= sizeof(oid
))
50 irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
53 oid
= *(DWORD
*)irp
->AssociatedIrp
.SystemBuffer
;
57 case OID_GEN_MEDIA_SUPPORTED
:
58 case OID_GEN_MEDIA_IN_USE
:
60 if (len
< sizeof(NDIS_MEDIUM
))
62 irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
65 *(NDIS_MEDIUM
*)response
= netdev
->MediaType
;
66 irp
->IoStatus
.Information
= sizeof(netdev
->MediaType
);
67 irp
->IoStatus
.Status
= STATUS_SUCCESS
;
70 case OID_802_3_PERMANENT_ADDRESS
:
72 irp
->IoStatus
.Information
= netdev
->PhysicalAddressLength
;
73 if (len
< netdev
->PhysicalAddressLength
)
74 irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
76 memcpy( response
, netdev
->PermanentPhysicalAddress
, sizeof(netdev
->PermanentPhysicalAddress
) );
79 case OID_802_3_CURRENT_ADDRESS
:
81 irp
->IoStatus
.Information
= netdev
->PhysicalAddressLength
;
82 if (len
< netdev
->PhysicalAddressLength
)
83 irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
85 memcpy( response
, netdev
->PhysicalAddress
, sizeof(netdev
->PhysicalAddress
) );
90 FIXME( "Unsupported OID %lx\n", oid
);
91 irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
96 static NTSTATUS WINAPI
ndis_ioctl(DEVICE_OBJECT
*device
, IRP
*irp
)
98 IO_STACK_LOCATION
*irpsp
= IoGetCurrentIrpStackLocation( irp
);
99 MIB_IF_ROW2
*netdev
= device
->DeviceExtension
;
102 TRACE( "ioctl %lx insize %lu outsize %lu\n",
103 irpsp
->Parameters
.DeviceIoControl
.IoControlCode
,
104 irpsp
->Parameters
.DeviceIoControl
.InputBufferLength
,
105 irpsp
->Parameters
.DeviceIoControl
.OutputBufferLength
);
107 switch (irpsp
->Parameters
.DeviceIoControl
.IoControlCode
)
109 case IOCTL_NDIS_QUERY_GLOBAL_STATS
:
110 query_global_stats(irp
, netdev
);
113 FIXME( "ioctl %lx not supported\n", irpsp
->Parameters
.DeviceIoControl
.IoControlCode
);
114 irp
->IoStatus
.Status
= STATUS_NOT_SUPPORTED
;
118 status
= irp
->IoStatus
.Status
;
119 IoCompleteRequest( irp
, IO_NO_INCREMENT
);
123 static void add_key(const WCHAR
*guidstrW
, const MIB_IF_ROW2
*netdev
)
128 swprintf( keynameW
, ARRAY_SIZE(keynameW
), L
"Software\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards\\%d", netdev
->InterfaceIndex
);
129 if (RegCreateKeyExW( HKEY_LOCAL_MACHINE
, keynameW
, 0, NULL
,
130 REG_OPTION_VOLATILE
, KEY_ALL_ACCESS
, NULL
, &card_key
, NULL
) == ERROR_SUCCESS
)
132 RegSetValueExW( card_key
, L
"Description", 0, REG_SZ
, (BYTE
*)netdev
->Description
, (lstrlenW(netdev
->Description
) + 1) * sizeof(WCHAR
) );
133 RegSetValueExW( card_key
, L
"ServiceName", 0, REG_SZ
, (BYTE
*)guidstrW
, (lstrlenW(guidstrW
) + 1) * sizeof(WCHAR
) );
134 RegCloseKey( card_key
);
138 static int add_device(DRIVER_OBJECT
*driver
, const WCHAR
*guidstrW
, MIB_IF_ROW2
*netdev
)
140 WCHAR nameW
[47], linkW
[51];
141 UNICODE_STRING name
, link
;
142 DEVICE_OBJECT
*device
;
145 swprintf( nameW
, ARRAY_SIZE(nameW
), L
"\\Device\\%s", guidstrW
);
146 RtlInitUnicodeString( &name
, nameW
);
148 swprintf( linkW
, ARRAY_SIZE(linkW
), L
"\\DosDevices\\%s", guidstrW
);
149 RtlInitUnicodeString( &link
, linkW
);
151 if (!(status
= IoCreateDevice( driver
, sizeof(*netdev
), &name
, 0, 0, FALSE
, &device
)))
152 status
= IoCreateSymbolicLink( &link
, &name
);
155 FIXME( "failed to create device error %lx\n", status
);
159 memcpy( device
->DeviceExtension
, netdev
, sizeof(*netdev
) );
164 static void create_network_devices(DRIVER_OBJECT
*driver
)
166 MIB_IF_TABLE2
*table
;
169 if (GetIfTable2( &table
) != NO_ERROR
)
172 for (i
= 0; i
< table
->NumEntries
; i
++)
174 GUID
*guid
= &table
->Table
[i
].InterfaceGuid
;
177 swprintf( guidstrW
, ARRAY_SIZE(guidstrW
), L
"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
178 guid
->Data1
, guid
->Data2
, guid
->Data3
, guid
->Data4
[0], guid
->Data4
[1],
179 guid
->Data4
[2], guid
->Data4
[3], guid
->Data4
[4], guid
->Data4
[5],
180 guid
->Data4
[6], guid
->Data4
[7] );
182 if (add_device( driver
, guidstrW
, &table
->Table
[i
] ))
183 add_key( guidstrW
, &table
->Table
[i
] );
186 FreeMibTable( table
);
189 NTSTATUS WINAPI
DriverEntry(DRIVER_OBJECT
*driver
, UNICODE_STRING
*path
)
191 TRACE("(%p, %s)\n", driver
, debugstr_w(path
->Buffer
));
193 driver
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = ndis_ioctl
;
195 create_network_devices( driver
);
197 return STATUS_SUCCESS
;
200 NDIS_STATUS WINAPI
NdisAllocateMemoryWithTag(void **address
, UINT length
, ULONG tag
)
202 FIXME("(%p, %u, %lu): stub\n", address
, length
, tag
);
203 return NDIS_STATUS_FAILURE
;
206 void WINAPI
NdisAllocateSpinLock(NDIS_SPIN_LOCK
*lock
)
208 FIXME("(%p): stub\n", lock
);
211 void WINAPI
NdisRegisterProtocol(NDIS_STATUS
*status
, NDIS_HANDLE
*handle
,
212 NDIS_PROTOCOL_CHARACTERISTICS
*prot
, UINT len
)
214 FIXME("(%p, %p, %p, %u): stub\n", status
, handle
, prot
, len
);
215 *status
= NDIS_STATUS_FAILURE
;
218 CCHAR WINAPI
NdisSystemProcessorCount(void)
225 return si
.dwNumberOfProcessors
;