ntdll: Validate blocks in the heap pending free request list.
[wine.git] / dlls / ndis.sys / main.c
blobb5ce2fd8f5b5de68e5f4454f7d28dac7c2fe5f6b
1 /*
2 * ndis.sys
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
22 #include <stdarg.h>
24 #define NONAMELESSUNION
25 #include "ntstatus.h"
26 #define WIN32_NO_STATUS
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winternl.h"
30 #include "winioctl.h"
31 #include "winsock2.h"
32 #include "ws2ipdef.h"
33 #include "iphlpapi.h"
34 #include "netioapi.h"
35 #include "ddk/wdm.h"
36 #include "ddk/ndis.h"
37 #include "winreg.h"
38 #include "wine/debug.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(ndis);
42 static void query_global_stats(IRP *irp, const MIB_IF_ROW2 *netdev)
44 IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp );
45 void *response = MmGetSystemAddressForMdlSafe( irp->MdlAddress, NormalPagePriority );
46 DWORD len = irpsp->Parameters.DeviceIoControl.OutputBufferLength;
47 DWORD oid;
49 if (irpsp->Parameters.DeviceIoControl.InputBufferLength != sizeof(oid))
51 irp->IoStatus.u.Status = STATUS_INVALID_PARAMETER;
52 return;
54 oid = *(DWORD *)irp->AssociatedIrp.SystemBuffer;
56 switch (oid)
58 case OID_GEN_MEDIA_SUPPORTED:
59 case OID_GEN_MEDIA_IN_USE:
61 if (len < sizeof(NDIS_MEDIUM))
63 irp->IoStatus.u.Status = STATUS_INVALID_PARAMETER;
64 break;
66 *(NDIS_MEDIUM *)response = netdev->MediaType;
67 irp->IoStatus.Information = sizeof(netdev->MediaType);
68 irp->IoStatus.u.Status = STATUS_SUCCESS;
69 break;
71 case OID_802_3_PERMANENT_ADDRESS:
73 irp->IoStatus.Information = netdev->PhysicalAddressLength;
74 if (len < netdev->PhysicalAddressLength)
75 irp->IoStatus.u.Status = STATUS_INVALID_PARAMETER;
76 else
77 memcpy( response, netdev->PermanentPhysicalAddress, sizeof(netdev->PermanentPhysicalAddress) );
78 break;
80 case OID_802_3_CURRENT_ADDRESS:
82 irp->IoStatus.Information = netdev->PhysicalAddressLength;
83 if (len < netdev->PhysicalAddressLength)
84 irp->IoStatus.u.Status = STATUS_INVALID_PARAMETER;
85 else
86 memcpy( response, netdev->PhysicalAddress, sizeof(netdev->PhysicalAddress) );
87 break;
90 default:
91 FIXME( "Unsupported OID %lx\n", oid );
92 irp->IoStatus.u.Status = STATUS_INVALID_PARAMETER;
93 break;
97 static NTSTATUS WINAPI ndis_ioctl(DEVICE_OBJECT *device, IRP *irp)
99 IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp );
100 MIB_IF_ROW2 *netdev = device->DeviceExtension;
101 NTSTATUS status;
103 TRACE( "ioctl %lx insize %lu outsize %lu\n",
104 irpsp->Parameters.DeviceIoControl.IoControlCode,
105 irpsp->Parameters.DeviceIoControl.InputBufferLength,
106 irpsp->Parameters.DeviceIoControl.OutputBufferLength );
108 switch (irpsp->Parameters.DeviceIoControl.IoControlCode)
110 case IOCTL_NDIS_QUERY_GLOBAL_STATS:
111 query_global_stats(irp, netdev);
112 break;
113 default:
114 FIXME( "ioctl %lx not supported\n", irpsp->Parameters.DeviceIoControl.IoControlCode );
115 irp->IoStatus.u.Status = STATUS_NOT_SUPPORTED;
116 break;
119 status = irp->IoStatus.u.Status;
120 IoCompleteRequest( irp, IO_NO_INCREMENT );
121 return status;
124 static void add_key(const WCHAR *guidstrW, const MIB_IF_ROW2 *netdev)
126 HKEY card_key;
127 WCHAR keynameW[100];
129 swprintf( keynameW, ARRAY_SIZE(keynameW), L"Software\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards\\%d", netdev->InterfaceIndex );
130 if (RegCreateKeyExW( HKEY_LOCAL_MACHINE, keynameW, 0, NULL,
131 REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &card_key, NULL ) == ERROR_SUCCESS)
133 RegSetValueExW( card_key, L"Description", 0, REG_SZ, (BYTE *)netdev->Description, (lstrlenW(netdev->Description) + 1) * sizeof(WCHAR) );
134 RegSetValueExW( card_key, L"ServiceName", 0, REG_SZ, (BYTE *)guidstrW, (lstrlenW(guidstrW) + 1) * sizeof(WCHAR) );
135 RegCloseKey( card_key );
139 static int add_device(DRIVER_OBJECT *driver, const WCHAR *guidstrW, MIB_IF_ROW2 *netdev)
141 WCHAR nameW[47], linkW[51];
142 UNICODE_STRING name, link;
143 DEVICE_OBJECT *device;
144 NTSTATUS status;
146 swprintf( nameW, ARRAY_SIZE(nameW), L"\\Device\\%s", guidstrW );
147 RtlInitUnicodeString( &name, nameW );
149 swprintf( linkW, ARRAY_SIZE(linkW), L"\\DosDevices\\%s", guidstrW );
150 RtlInitUnicodeString( &link, linkW );
152 if (!(status = IoCreateDevice( driver, sizeof(*netdev), &name, 0, 0, FALSE, &device )))
153 status = IoCreateSymbolicLink( &link, &name );
154 if (status)
156 FIXME( "failed to create device error %lx\n", status );
157 return 0;
160 memcpy( device->DeviceExtension, netdev, sizeof(*netdev) );
161 return 1;
165 static void create_network_devices(DRIVER_OBJECT *driver)
167 MIB_IF_TABLE2 *table;
168 ULONG i;
170 if (GetIfTable2( &table ) != NO_ERROR)
171 return;
173 for (i = 0; i < table->NumEntries; i++)
175 GUID *guid = &table->Table[i].InterfaceGuid;
176 WCHAR guidstrW[39];
178 swprintf( guidstrW, ARRAY_SIZE(guidstrW), L"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
179 guid->Data1, guid->Data2, guid->Data3, guid->Data4[0], guid->Data4[1],
180 guid->Data4[2], guid->Data4[3], guid->Data4[4], guid->Data4[5],
181 guid->Data4[6], guid->Data4[7] );
183 if (add_device( driver, guidstrW, &table->Table[i] ))
184 add_key( guidstrW, &table->Table[i] );
187 FreeMibTable( table );
190 NTSTATUS WINAPI DriverEntry(DRIVER_OBJECT *driver, UNICODE_STRING *path)
192 TRACE("(%p, %s)\n", driver, debugstr_w(path->Buffer));
194 driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ndis_ioctl;
196 create_network_devices( driver );
198 return STATUS_SUCCESS;
201 NDIS_STATUS WINAPI NdisAllocateMemoryWithTag(void **address, UINT length, ULONG tag)
203 FIXME("(%p, %u, %lu): stub\n", address, length, tag);
204 return NDIS_STATUS_FAILURE;
207 void WINAPI NdisAllocateSpinLock(NDIS_SPIN_LOCK *lock)
209 FIXME("(%p): stub\n", lock);
212 void WINAPI NdisRegisterProtocol(NDIS_STATUS *status, NDIS_HANDLE *handle,
213 NDIS_PROTOCOL_CHARACTERISTICS *prot, UINT len)
215 FIXME("(%p, %p, %p, %u): stub\n", status, handle, prot, len);
216 *status = NDIS_STATUS_FAILURE;
219 CCHAR WINAPI NdisSystemProcessorCount(void)
221 SYSTEM_INFO si;
223 TRACE("()\n");
224 GetSystemInfo(&si);
226 return si.dwNumberOfProcessors;