1 // SoftEther VPN Source Code - Developer Edition Master Branch
2 // Kernel Device Driver
3
4
5 // NDIS6.c
6 // Windows NDIS 6.2 Routine
7
8 #include <GlobalConst.h>
9
10 #define NEO_DEVICE_DRIVER
11
12 #include "Neo6.h"
13
14 static UINT64 max_speed = NEO_MAX_SPEED_DEFAULT;
15 static bool keep_link = false;
16 static UINT reg_if_type = IF_TYPE_ETHERNET_CSMACD;
17
18 BOOLEAN
19 PsGetVersion(
20 PULONG MajorVersion OPTIONAL,
21 PULONG MinorVersion OPTIONAL,
22 PULONG BuildNumber OPTIONAL,
23 PUNICODE_STRING CSDVersion OPTIONAL
24 );
25
26 // Memory related
27 static NDIS_PHYSICAL_ADDRESS HighestAcceptableMax = NDIS_PHYSICAL_ADDRESS_CONST(-1, -1);
28 NDIS_HANDLE ndis_miniport_driver_handle = NULL;
29
30 // Flag for whether Windows 8
31 bool g_is_win8 = false;
32
33 // Win32 driver entry point
DriverEntry(DRIVER_OBJECT * DriverObject,UNICODE_STRING * RegistryPath)34 NDIS_STATUS DriverEntry(DRIVER_OBJECT *DriverObject, UNICODE_STRING *RegistryPath)
35 {
36 NDIS_MINIPORT_DRIVER_CHARACTERISTICS miniport;
37 ULONG os_major_ver = 0, os_minor_ver = 0;
38 NDIS_STATUS ret;
39
40 // Initialize the Neo library
41 if (NeoInit() == FALSE)
42 {
43 // Initialization Failed
44 return STATUS_UNSUCCESSFUL;
45 }
46
47 g_is_win8 = false;
48
49 // Get the OS version
50 PsGetVersion(&os_major_ver, &os_minor_ver, NULL, NULL);
51
52 if (os_major_ver >= 7 || (os_major_ver == 6 && os_minor_ver >= 2))
53 {
54 // Windows 8
55 g_is_win8 = true;
56 }
57
58 // Register a NDIS miniport driver
59 NeoZero(&miniport, sizeof(NDIS_MINIPORT_DRIVER_CHARACTERISTICS));
60
61 miniport.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_DRIVER_CHARACTERISTICS;
62 miniport.Header.Revision = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_2;
63 miniport.Header.Size = NDIS_SIZEOF_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_2;
64
65 miniport.MajorNdisVersion = NEO_NDIS_MAJOR_VERSION;
66 miniport.MinorNdisVersion = NEO_NDIS_MINOR_VERSION;
67
68 // Register the handler
69 miniport.InitializeHandlerEx = NeoNdisInitEx;
70 miniport.HaltHandlerEx = NeoNdisHaltEx;
71 miniport.OidRequestHandler = NeoNdisOidRequest;
72 miniport.ResetHandlerEx = NeoNdisResetEx;
73 miniport.CheckForHangHandlerEx = NeoNdisCheckForHangEx;
74 miniport.UnloadHandler = NeoNdisDriverUnload;
75 miniport.SendNetBufferListsHandler = NeoNdisSendNetBufferLists;
76
77 miniport.SetOptionsHandler = NeoNdisSetOptions;
78 miniport.PauseHandler = NeoNdisPause;
79 miniport.RestartHandler = NeoNdisRestart;
80 miniport.ReturnNetBufferListsHandler = NeoNdisReturnNetBufferLists;
81 miniport.CancelSendHandler = NeoNdisCancelSend;
82 miniport.DevicePnPEventNotifyHandler = NeoNdisDevicePnPEventNotify;
83 miniport.ShutdownHandlerEx = NeoNdisShutdownEx;
84 miniport.CancelOidRequestHandler = NeoNdisCancelOidRequest;
85
86 ret = NdisMRegisterMiniportDriver(DriverObject, RegistryPath,
87 NULL, &miniport, &ndis_miniport_driver_handle);
88
89 if (NG(ret))
90 {
91 // Registration failure
92 return STATUS_UNSUCCESSFUL;
93 }
94
95 // Initialization success
96 return STATUS_SUCCESS;
97 }
98
NeoNdisSetOptions(NDIS_HANDLE NdisDriverHandle,NDIS_HANDLE DriverContext)99 NDIS_STATUS NeoNdisSetOptions(NDIS_HANDLE NdisDriverHandle, NDIS_HANDLE DriverContext)
100 {
101 return NDIS_STATUS_SUCCESS;
102 }
103
NeoNdisPause(NDIS_HANDLE MiniportAdapterContext,PNDIS_MINIPORT_PAUSE_PARAMETERS MiniportPauseParameters)104 NDIS_STATUS NeoNdisPause(NDIS_HANDLE MiniportAdapterContext, PNDIS_MINIPORT_PAUSE_PARAMETERS MiniportPauseParameters)
105 {
106 UINT counter_dbg = 0;
107
108 ctx->Paused = true;
109
110 NeoLockPacketQueue();
111 NeoUnlockPacketQueue();
112
113 // Wait for complete all tasks
114 while (ctx->NumCurrentDispatch != 0)
115 {
116 NdisMSleep(10000);
117 counter_dbg++;
118 if (counter_dbg >= 1500)
119 {
120 break;
121 }
122 }
123
124 return NDIS_STATUS_SUCCESS;
125 }
126
NeoNdisRestart(NDIS_HANDLE MiniportAdapterContext,PNDIS_MINIPORT_RESTART_PARAMETERS MiniportRestartParameters)127 NDIS_STATUS NeoNdisRestart(NDIS_HANDLE MiniportAdapterContext, PNDIS_MINIPORT_RESTART_PARAMETERS MiniportRestartParameters)
128 {
129 ctx->Paused = false;
130
131 return NDIS_STATUS_SUCCESS;
132 }
133
NeoNdisReturnNetBufferLists(NDIS_HANDLE MiniportAdapterContext,PNET_BUFFER_LIST NetBufferLists,ULONG ReturnFlags)134 void NeoNdisReturnNetBufferLists(NDIS_HANDLE MiniportAdapterContext, PNET_BUFFER_LIST NetBufferLists, ULONG ReturnFlags)
135 {
136 }
137
NeoNdisCancelSend(NDIS_HANDLE MiniportAdapterContext,PVOID CancelId)138 void NeoNdisCancelSend(NDIS_HANDLE MiniportAdapterContext, PVOID CancelId)
139 {
140 //NeoNdisCrash2(__LINE__, __LINE__, __LINE__, __LINE__);
141 }
142
NeoNdisDevicePnPEventNotify(NDIS_HANDLE MiniportAdapterContext,PNET_DEVICE_PNP_EVENT NetDevicePnPEvent)143 void NeoNdisDevicePnPEventNotify(NDIS_HANDLE MiniportAdapterContext, PNET_DEVICE_PNP_EVENT NetDevicePnPEvent)
144 {
145 }
146
NeoNdisShutdownEx(NDIS_HANDLE MiniportAdapterContext,NDIS_SHUTDOWN_ACTION ShutdownAction)147 void NeoNdisShutdownEx(NDIS_HANDLE MiniportAdapterContext, NDIS_SHUTDOWN_ACTION ShutdownAction)
148 {
149 }
150
NeoNdisCancelOidRequest(NDIS_HANDLE MiniportAdapterContext,PVOID RequestId)151 void NeoNdisCancelOidRequest(NDIS_HANDLE MiniportAdapterContext, PVOID RequestId)
152 {
153 //NeoNdisCrash2(__LINE__, __LINE__, __LINE__, __LINE__);
154 }
155
156 // Initialization handler of adapter
NeoNdisInitEx(NDIS_HANDLE MiniportAdapterHandle,NDIS_HANDLE MiniportDriverContext,PNDIS_MINIPORT_INIT_PARAMETERS MiniportInitParameters)157 NDIS_STATUS NeoNdisInitEx(NDIS_HANDLE MiniportAdapterHandle,
158 NDIS_HANDLE MiniportDriverContext,
159 PNDIS_MINIPORT_INIT_PARAMETERS MiniportInitParameters)
160 {
161 NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES attr;
162 NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES gen;
163 NDIS_PM_CAPABILITIES pnpcap;
164
165 if (ctx == NULL)
166 {
167 return NDIS_STATUS_FAILURE;
168 }
169
170 if (ctx->NdisMiniportDriverHandle == NULL)
171 {
172 ctx->NdisMiniportDriverHandle = ndis_miniport_driver_handle;
173 }
174
175 // Prevention of multiple start
176 if (ctx->Initing != FALSE)
177 {
178 // Multiple started
179 return NDIS_STATUS_FAILURE;
180 }
181 ctx->Initing = TRUE;
182
183 // Examine whether it has already been initialized
184 if (ctx->Inited != FALSE)
185 {
186 // Driver is started on another instance already.
187 // VPN driver can start only one instance per one service.
188 // User can start multiple drivers with different instance ID
189 return NDIS_STATUS_FAILURE;
190 }
191
192 // Current value of the packet filter
193 ctx->CurrentPacketFilter = NDIS_PACKET_TYPE_ALL_LOCAL | NDIS_PACKET_TYPE_BROADCAST | NDIS_PACKET_TYPE_DIRECTED | NDIS_PACKET_TYPE_ALL_FUNCTIONAL;
194
195 // Initialize the adapter information
196 ctx->NdisMiniport = MiniportAdapterHandle;
197 ctx->NdisContext = ctx;
198 ctx->HardwareStatus = NdisHardwareStatusReady;
199 ctx->Halting = FALSE;
200 ctx->Connected = ctx->ConnectedOld = FALSE;
201
202 //if (keep_link == false)
203 {
204 ctx->ConnectedForce = TRUE;
205 }
206
207 // Read the information from the registry
208 if (NeoLoadRegistry() == FALSE)
209 {
210 // Failure
211 ctx->Initing = FALSE;
212 return NDIS_STATUS_FAILURE;
213 }
214
215 // Register the device attributes
216 NeoZero(&attr, sizeof(attr));
217 attr.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES;
218 attr.Header.Revision = NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;
219 attr.Header.Size = sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES);
220 attr.AttributeFlags = NDIS_MINIPORT_ATTRIBUTES_NO_HALT_ON_SUSPEND;
221 attr.InterfaceType = NdisInterfaceInternal;
222 attr.MiniportAdapterContext = ctx->NdisContext;
223
224 NdisMSetMiniportAttributes(ctx->NdisMiniport, (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&attr);
225
226 NeoZero(&pnpcap, sizeof(pnpcap));
227
228 NeoZero(&gen, sizeof(gen));
229 gen.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES;
230 gen.Header.Revision = NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_2;
231 gen.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_2;
232 gen.MediaType = NdisMedium802_3;
233 gen.PhysicalMediumType = NdisPhysicalMedium802_3;
234 gen.MtuSize = NEO_MAX_PACKET_SIZE_ANNOUNCE - NEO_MIN_PACKET_SIZE;
235 gen.MaxXmitLinkSpeed = gen.MaxRcvLinkSpeed = max_speed;
236 gen.RcvLinkSpeed = gen.XmitLinkSpeed = max_speed;
237 gen.MediaConnectState = MediaConnectStateDisconnected;
238 gen.LookaheadSize = NEO_MAX_PACKET_SIZE_ANNOUNCE - NEO_MIN_PACKET_SIZE;
239 gen.MacOptions = NDIS_MAC_OPTION_TRANSFERS_NOT_PEND | NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | NDIS_MAC_OPTION_NO_LOOPBACK;
240 gen.SupportedPacketFilters = NDIS_PACKET_TYPE_ALL_LOCAL | NDIS_PACKET_TYPE_BROADCAST | NDIS_PACKET_TYPE_DIRECTED | NDIS_PACKET_TYPE_ALL_FUNCTIONAL;
241 gen.MaxMulticastListSize = NEO_MAX_MULTICASE;
242 gen.MacAddressLength = NEO_MAC_ADDRESS_SIZE;
243 NeoCopy(gen.PermanentMacAddress, ctx->MacAddress, NEO_MAC_ADDRESS_SIZE);
244 NeoCopy(gen.CurrentMacAddress, ctx->MacAddress, NEO_MAC_ADDRESS_SIZE);
245 gen.AccessType = NET_IF_ACCESS_BROADCAST;
246 gen.DirectionType = NET_IF_DIRECTION_SENDRECEIVE;
247 gen.ConnectionType = NET_IF_CONNECTION_DEDICATED;
248 gen.IfType = reg_if_type;
249 gen.IfConnectorPresent = FALSE;
250 gen.SupportedStatistics =
251 NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_RCV |
252 NDIS_STATISTICS_FLAGS_VALID_MULTICAST_FRAMES_RCV |
253 NDIS_STATISTICS_FLAGS_VALID_BROADCAST_FRAMES_RCV |
254 NDIS_STATISTICS_FLAGS_VALID_BYTES_RCV |
255 NDIS_STATISTICS_FLAGS_VALID_RCV_DISCARDS |
256 NDIS_STATISTICS_FLAGS_VALID_RCV_ERROR |
257 NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_XMIT |
258 NDIS_STATISTICS_FLAGS_VALID_MULTICAST_FRAMES_XMIT |
259 NDIS_STATISTICS_FLAGS_VALID_BROADCAST_FRAMES_XMIT |
260 NDIS_STATISTICS_FLAGS_VALID_BYTES_XMIT |
261 NDIS_STATISTICS_FLAGS_VALID_XMIT_ERROR |
262 NDIS_STATISTICS_FLAGS_VALID_XMIT_DISCARDS |
263 NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_RCV |
264 NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_RCV |
265 NDIS_STATISTICS_FLAGS_VALID_BROADCAST_BYTES_RCV |
266 NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_XMIT |
267 NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_XMIT |
268 NDIS_STATISTICS_FLAGS_VALID_BROADCAST_BYTES_XMIT;
269 gen.SupportedPauseFunctions = NdisPauseFunctionsUnsupported;
270 gen.AutoNegotiationFlags = NDIS_LINK_STATE_XMIT_LINK_SPEED_AUTO_NEGOTIATED |
271 NDIS_LINK_STATE_RCV_LINK_SPEED_AUTO_NEGOTIATED |
272 NDIS_LINK_STATE_DUPLEX_AUTO_NEGOTIATED |
273 NDIS_LINK_STATE_PAUSE_FUNCTIONS_AUTO_NEGOTIATED;
274 gen.SupportedOidList = SupportedOids;
275 gen.SupportedOidListLength = sizeof(SupportedOids);
276
277 NeoZero(&pnpcap, sizeof(pnpcap));
278 pnpcap.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
279 pnpcap.Header.Revision = NDIS_PM_CAPABILITIES_REVISION_1;
280 pnpcap.Header.Size = NDIS_SIZEOF_NDIS_PM_CAPABILITIES_REVISION_1;
281 pnpcap.MinMagicPacketWakeUp = NdisDeviceStateUnspecified;
282 pnpcap.MinPatternWakeUp = NdisDeviceStateUnspecified;
283 pnpcap.MinLinkChangeWakeUp = NdisDeviceStateUnspecified;
284 gen.PowerManagementCapabilitiesEx = &pnpcap;
285
286 NdisMSetMiniportAttributes(ctx->NdisMiniport, (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&gen);
287
288 // Initialize the received packet array
289 NeoInitPacketArray();
290
291 // Initialize the control device
292 NeoInitControlDevice();
293
294 // Start the adapter
295 NeoStartAdapter();
296
297 // Flag setting
298 ctx->Initing = FALSE;
299 ctx->Inited = TRUE;
300
301 // Notify the connection state
302 NeoSetConnectState(FALSE);
303
304 return NDIS_STATUS_SUCCESS;
305 }
306
307 // Open the device
NeoNdisOnOpen(IRP * irp,IO_STACK_LOCATION * stack)308 BOOL NeoNdisOnOpen(IRP *irp, IO_STACK_LOCATION *stack)
309 {
310 char name[MAX_SIZE];
311
312 if (ctx == NULL)
313 {
314 return FALSE;
315 }
316
317 if (ctx->Opened)
318 {
319 // Another client is connected already
320 return FALSE;
321 }
322 ctx->Opened = TRUE;
323
324 // Initialize the event name
325 sprintf(name, NDIS_NEO_EVENT_NAME, ctx->HardwareID);
326
327 // Register a Event
328 ctx->Event = NeoNewEvent(name);
329 if (ctx->Event == NULL)
330 {
331 ctx->Opened = FALSE;
332 return FALSE;
333 }
334
335 // Set the connection state
336 NeoSetConnectState(TRUE);
337
338 return TRUE;
339 }
340
341 // Close the device
NeoNdisOnClose(IRP * irp,IO_STACK_LOCATION * stack)342 BOOL NeoNdisOnClose(IRP *irp, IO_STACK_LOCATION *stack)
343 {
344 NEO_EVENT *free_event = NULL;
345 if (ctx == NULL)
346 {
347 return FALSE;
348 }
349
350 if (ctx->Opened == FALSE)
351 {
352 // Client is not connected
353 return FALSE;
354 }
355 ctx->Opened = FALSE;
356
357 NeoLockPacketQueue();
358 {
359 // Release the event
360 free_event = ctx->Event;
361 ctx->Event = NULL;
362
363 // Release all packets
364 NeoClearPacketQueue(true);
365 }
366 NeoUnlockPacketQueue();
367
368 if (free_event != NULL)
369 {
370 NeoFreeEvent(free_event);
371 }
372
373 NeoSetConnectState(FALSE);
374
375 return TRUE;
376 }
377
378 // Crash 2
NeoNdisCrash2(UINT a,UINT b,UINT c,UINT d)379 void NeoNdisCrash2(UINT a, UINT b, UINT c, UINT d)
380 {
381 KeBugCheckEx(0x00000061, (ULONG_PTR)a, (ULONG_PTR)b, (ULONG_PTR)c, (ULONG_PTR)d);
382 }
383
384 // Crash
NeoNdisCrash()385 void NeoNdisCrash()
386 {
387 NEO_QUEUE *q;
388 q = (NEO_QUEUE *)0xACACACAC;
389 q->Size = 128;
390 NeoCopy(q->Buf, "ABCDEFG", 8);
391 }
392
393 // Dispatch table for control
NeoNdisDispatch(DEVICE_OBJECT * DeviceObject,IRP * Irp)394 NTSTATUS NeoNdisDispatch(DEVICE_OBJECT *DeviceObject, IRP *Irp)
395 {
396 NTSTATUS status;
397 IO_STACK_LOCATION *stack;
398 void *buf;
399 BOOL ok;
400 status = STATUS_SUCCESS;
401
402 if (ctx == NULL)
403 {
404 return NDIS_STATUS_FAILURE;
405 }
406
407 InterlockedIncrement(&ctx->NumCurrentDispatch);
408
409 // Get the IRP stack
410 stack = IoGetCurrentIrpStackLocation(Irp);
411
412 // Initialize the number of bytes
413 Irp->IoStatus.Information = 0;
414 Irp->IoStatus.Status = STATUS_SUCCESS;
415
416 buf = Irp->UserBuffer;
417
418 if (ctx->Halting != FALSE)
419 {
420 // Device driver is terminating
421 Irp->IoStatus.Information = STATUS_UNSUCCESSFUL;
422 InterlockedDecrement(&ctx->NumCurrentDispatch);
423
424 IoCompleteRequest(Irp, IO_NO_INCREMENT);
425
426 return STATUS_SUCCESS;
427 }
428
429 // Branch to each operation
430 switch (stack->MajorFunction)
431 {
432 case IRP_MJ_CREATE:
433 // Device is opened
434 if (NeoNdisOnOpen(Irp, stack) == FALSE)
435 {
436 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
437 status = STATUS_UNSUCCESSFUL;
438 }
439 break;
440
441 case IRP_MJ_CLOSE:
442 // Device is closed
443 if (NeoNdisOnClose(Irp, stack) == FALSE)
444 {
445 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
446 status = STATUS_UNSUCCESSFUL;
447 }
448 break;
449
450 case IRP_MJ_READ:
451 // Read (Reading of the received packet)
452 ok = false;
453 if (buf != NULL)
454 {
455 if (ctx->Opened && ctx->Inited)
456 {
457 if (stack->Parameters.Read.Length == NEO_EXCHANGE_BUFFER_SIZE)
458 {
459 // Address check
460 bool check_ok = true;
461 __try
462 {
463 ProbeForWrite(buf, NEO_EXCHANGE_BUFFER_SIZE, 1);
464 }
465 __except (EXCEPTION_EXECUTE_HANDLER)
466 {
467 check_ok = false;
468 }
469
470 if (check_ok)
471 {
472 // Address check
473 MDL *mdl = IoAllocateMdl(buf, NEO_EXCHANGE_BUFFER_SIZE, false, false, NULL);
474
475 if (mdl != NULL)
476 {
477 MmProbeAndLockPages(mdl, KernelMode, IoWriteAccess);
478 }
479
480 // Read
481 NeoRead(buf);
482 Irp->IoStatus.Information = NEO_EXCHANGE_BUFFER_SIZE;
483 ok = true;
484
485 if (mdl != NULL)
486 {
487 MmUnlockPages(mdl);
488 IoFreeMdl(mdl);
489 }
490 }
491 }
492 }
493 }
494 if (ok == FALSE)
495 {
496 // An error occurred
497 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
498 status = STATUS_UNSUCCESSFUL;
499 }
500 break;
501
502 case IRP_MJ_WRITE:
503 // Write (Writing of a transmission packet)
504 ok = false;
505 if (buf != NULL)
506 {
507 if (ctx->Opened && ctx->Inited)
508 {
509 if (stack->Parameters.Write.Length == NEO_EXCHANGE_BUFFER_SIZE)
510 {
511 // Address check
512 bool check_ok = true;
513 __try
514 {
515 ProbeForRead(buf, NEO_EXCHANGE_BUFFER_SIZE, 1);
516 }
517 __except (EXCEPTION_EXECUTE_HANDLER)
518 {
519 check_ok = false;
520 }
521
522 if (check_ok)
523 {
524 // Address check
525 MDL *mdl = IoAllocateMdl(buf, NEO_EXCHANGE_BUFFER_SIZE, false, false, NULL);
526
527 if (mdl != NULL)
528 {
529 MmProbeAndLockPages(mdl, KernelMode, IoReadAccess);
530 }
531 __try
532 {
533 ProbeForRead(buf, NEO_EXCHANGE_BUFFER_SIZE, 1);
534 }
535 __except (EXCEPTION_EXECUTE_HANDLER)
536 {
537 check_ok = false;
538 }
539 if (check_ok) {
540 // Write
541 NeoWrite(buf);
542 Irp->IoStatus.Information = stack->Parameters.Write.Length;
543 ok = true;
544
545 if (mdl != NULL)
546 {
547 MmUnlockPages(mdl);
548 IoFreeMdl(mdl);
549 }
550 }
551 }
552 }
553 }
554 }
555 if (ok == FALSE)
556 {
557 // An error occurred
558 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
559 status = STATUS_UNSUCCESSFUL;
560 }
561 break;
562 }
563
564 InterlockedDecrement(&ctx->NumCurrentDispatch);
565
566 IoCompleteRequest(Irp, IO_NO_INCREMENT);
567
568 return STATUS_SUCCESS;
569 }
570
571 // Initialize the control device
NeoInitControlDevice()572 void NeoInitControlDevice()
573 {
574 char name_kernel[MAX_SIZE];
575 char name_win32[MAX_SIZE];
576 UNICODE *unicode_kernel, *unicode_win32;
577 DEVICE_OBJECT *control_device_object;
578 NDIS_HANDLE ndis_control_handle;
579 NDIS_DEVICE_OBJECT_ATTRIBUTES t;
580
581 if (ctx == NULL)
582 {
583 return;
584 }
585
586 // Initialize the dispatch table
587 NeoZero(ctx->DispatchTable, sizeof(PDRIVER_DISPATCH) * IRP_MJ_MAXIMUM_FUNCTION);
588
589 // Register the handler
590 ctx->DispatchTable[IRP_MJ_CREATE] =
591 ctx->DispatchTable[IRP_MJ_CLOSE] =
592 ctx->DispatchTable[IRP_MJ_READ] =
593 ctx->DispatchTable[IRP_MJ_WRITE] =
594 ctx->DispatchTable[IRP_MJ_DEVICE_CONTROL] = NeoNdisDispatch;
595 ctx->Opened = FALSE;
596 ctx->Paused = FALSE;
597
598 // Generate the device name
599 sprintf(name_kernel, NDIS_NEO_DEVICE_NAME, ctx->HardwareID);
600 unicode_kernel = NewUnicode(name_kernel);
601 sprintf(name_win32, NDIS_NEO_DEVICE_NAME_WIN32, ctx->HardwareID);
602 unicode_win32 = NewUnicode(name_win32);
603
604 // Register the device
605 NeoZero(&t, sizeof(t));
606 t.Header.Type = NDIS_OBJECT_TYPE_DEVICE_OBJECT_ATTRIBUTES;
607 t.Header.Revision = NDIS_DEVICE_OBJECT_ATTRIBUTES_REVISION_1;
608 t.Header.Size = NDIS_SIZEOF_DEVICE_OBJECT_ATTRIBUTES_REVISION_1;
609 t.DeviceName = GetUnicode(unicode_kernel);
610 t.SymbolicName = GetUnicode(unicode_win32);
611 t.MajorFunctions = ctx->DispatchTable;
612
613 NdisRegisterDeviceEx(ndis_miniport_driver_handle, &t,
614 &control_device_object,
615 &ndis_control_handle);
616
617 ctx->NdisControlDevice = control_device_object;
618 ctx->NdisControl = ndis_control_handle;
619
620 // Initialize the display name
621 if (strlen(ctx->HardwareID) > 11)
622 {
623 sprintf(ctx->HardwarePrintableID, NDIS_NEO_HARDWARE_ID, ctx->HardwareID_Raw + 11);
624 }
625 else
626 {
627 sprintf(ctx->HardwarePrintableID, NDIS_NEO_HARDWARE_ID, ctx->HardwareID_Raw);
628 }
629 }
630
631 // Release the control device
NeoFreeControlDevice()632 void NeoFreeControlDevice()
633 {
634 if (ctx == NULL)
635 {
636 return;
637 }
638
639 if (ctx->Opened != FALSE)
640 {
641 // Delete the event
642 NeoSet(ctx->Event);
643 NeoFreeEvent(ctx->Event);
644 ctx->Event = NULL;
645 ctx->Opened = FALSE;
646 }
647
648 // Delete the device
649 NdisDeregisterDeviceEx(ctx->NdisControl);
650 }
651
652
653 // Read the information from the registry
NeoLoadRegistry()654 BOOL NeoLoadRegistry()
655 {
656 void *buf;
657 NDIS_STATUS ret;
658 UINT size;
659 NDIS_HANDLE config;
660 NDIS_CONFIGURATION_PARAMETER *param;
661 UNICODE *name;
662 ANSI_STRING ansi;
663 UNICODE_STRING *unicode;
664 UINT64 speed;
665 BOOL keep;
666 NDIS_CONFIGURATION_OBJECT config_obj;
667
668 // Get the Config handle
669 NeoZero(&config_obj, sizeof(config_obj));
670 config_obj.Header.Type = NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT;
671 config_obj.Header.Revision = NDIS_CONFIGURATION_OBJECT_REVISION_1;
672 config_obj.Header.Size = NDIS_SIZEOF_CONFIGURATION_OBJECT_REVISION_1;
673 config_obj.NdisHandle = ctx->NdisMiniport;
674
675 ret = NdisOpenConfigurationEx(&config_obj, &config);
676 if (NG(ret))
677 {
678 // Failure
679 return FALSE;
680 }
681
682 // Read the MAC address
683 NdisReadNetworkAddress(&ret, &buf, &size, config);
684 if (NG(ret))
685 {
686 // Failure
687 NdisCloseConfiguration(config);
688 return FALSE;
689 }
690
691 // Copy the MAC address
692 if (size != NEO_MAC_ADDRESS_SIZE)
693 {
694 // Invalid size
695 NdisCloseConfiguration(config);
696 return FALSE;
697 }
698 NeoCopy(ctx->MacAddress, buf, NEO_MAC_ADDRESS_SIZE);
699
700 if (ctx->MacAddress[0] == 0x00 &&
701 ctx->MacAddress[1] == 0x00 &&
702 ctx->MacAddress[2] == 0x01 &&
703 ctx->MacAddress[3] == 0x00 &&
704 ctx->MacAddress[4] == 0x00 &&
705 ctx->MacAddress[5] == 0x01)
706 {
707 // Special MAC address
708 UINT ptr32 = (UINT)((UINT64)ctx);
709 LARGE_INTEGER current_time;
710 UCHAR *current_time_bytes;
711
712 KeQuerySystemTime(¤t_time);
713
714 current_time_bytes = (UCHAR *)¤t_time;
715
716 ctx->MacAddress[0] = 0x00;
717 ctx->MacAddress[1] = 0xAD;
718 ctx->MacAddress[2] = ((UCHAR *)(&ptr32))[0];
719 ctx->MacAddress[3] = ((UCHAR *)(&ptr32))[1];
720 ctx->MacAddress[4] = ((UCHAR *)(&ptr32))[2];
721 ctx->MacAddress[5] = ((UCHAR *)(&ptr32))[3];
722
723 ctx->MacAddress[2] ^= current_time_bytes[0];
724 ctx->MacAddress[3] ^= current_time_bytes[1];
725 ctx->MacAddress[4] ^= current_time_bytes[2];
726 ctx->MacAddress[5] ^= current_time_bytes[3];
727
728 ctx->MacAddress[2] ^= current_time_bytes[4];
729 ctx->MacAddress[3] ^= current_time_bytes[5];
730 ctx->MacAddress[4] ^= current_time_bytes[6];
731 ctx->MacAddress[5] ^= current_time_bytes[7];
732 }
733
734 // Initialize the key name of the device name
735 name = NewUnicode("MatchingDeviceId");
736
737 // Read the hardware ID
738 NdisReadConfiguration(&ret, ¶m, config, GetUnicode(name), NdisParameterString);
739 FreeUnicode(name);
740 if (NG(ret))
741 {
742 // Failure
743 NdisCloseConfiguration(config);
744 return FALSE;
745 }
746 // Type checking
747 if (param->ParameterType != NdisParameterString)
748 {
749 // Failure
750 NdisCloseConfiguration(config);
751 return FALSE;
752 }
753 unicode = ¶m->ParameterData.StringData;
754
755 // Prepare a buffer for ANSI string
756 NeoZero(&ansi, sizeof(ANSI_STRING));
757 ansi.MaximumLength = MAX_SIZE - 1;
758 ansi.Buffer = NeoZeroMalloc(MAX_SIZE);
759
760 // Convert to ANSI string
761 NdisUnicodeStringToAnsiString(&ansi, unicode);
762 // Copy
763 strcpy(ctx->HardwareID, ansi.Buffer);
764 strcpy(ctx->HardwareID_Raw, ctx->HardwareID);
765 // Convert to upper case
766 _strupr(ctx->HardwareID);
767 // Release the memory
768 NeoFree(ansi.Buffer);
769
770 // Read the bit rate
771 name = NewUnicode("MaxSpeed");
772 NdisReadConfiguration(&ret, ¶m, config, GetUnicode(name), NdisParameterInteger);
773 FreeUnicode(name);
774
775 if (NG(ret) || param->ParameterType != NdisParameterInteger)
776 {
777 speed = NEO_MAX_SPEED_DEFAULT;
778 }
779 else
780 {
781 speed = (UINT64)param->ParameterData.IntegerData * 1000000ULL;
782 }
783
784 max_speed = speed;
785
786 // Read the link keeping flag
787 name = NewUnicode("KeepLink");
788 NdisReadConfiguration(&ret, ¶m, config, GetUnicode(name), NdisParameterInteger);
789 FreeUnicode(name);
790
791 if (NG(ret) || param->ParameterType != NdisParameterInteger)
792 {
793 keep = false;
794 }
795 else
796 {
797 keep = (param->ParameterData.IntegerData == 0 ? false : true);
798 }
799
800 keep_link = keep;
801
802 // Read the *IfType value
803 name = NewUnicode("*IfType");
804 NdisReadConfiguration(&ret, ¶m, config, GetUnicode(name), NdisParameterInteger);
805 FreeUnicode(name);
806
807 if (NG(ret) || param->ParameterType != NdisParameterInteger)
808 {
809 reg_if_type = IF_TYPE_ETHERNET_CSMACD;
810 }
811 else
812 {
813 reg_if_type = param->ParameterData.IntegerData;
814 }
815
816 // Close the config handle
817 NdisCloseConfiguration(config);
818
819 return TRUE;
820 }
821
822 // Unload the driver
NeoNdisDriverUnload(PDRIVER_OBJECT DriverObject)823 VOID NeoNdisDriverUnload(PDRIVER_OBJECT DriverObject)
824 {
825 NdisMDeregisterMiniportDriver(ndis_miniport_driver_handle);
826 }
827
828 // Stop handler of adapter
NeoNdisHaltEx(NDIS_HANDLE MiniportAdapterContext,NDIS_HALT_ACTION HaltAction)829 void NeoNdisHaltEx(NDIS_HANDLE MiniportAdapterContext, NDIS_HALT_ACTION HaltAction)
830 {
831 NEO_EVENT *free_event = NULL;
832 UINT counter_dbg = 0;
833 if (ctx == NULL)
834 {
835 return;
836 }
837
838 if (ctx->Halting != FALSE)
839 {
840 // That has already been stopped
841 return;
842 }
843 ctx->Halting = TRUE;
844
845 ctx->Opened = FALSE;
846
847 NeoLockPacketQueue();
848 {
849 // Release the event
850 free_event = ctx->Event;
851 ctx->Event = NULL;
852
853 // Release all packets
854 NeoClearPacketQueue(true);
855 }
856 NeoUnlockPacketQueue();
857
858 if (free_event != NULL)
859 {
860 NeoSet(free_event);
861 }
862
863 // Wait for complete all tasks
864 while (ctx->NumCurrentDispatch != 0)
865 {
866 NdisMSleep(10000);
867 counter_dbg++;
868 if (counter_dbg >= 1500)
869 {
870 break;
871 }
872 }
873
874 if (free_event != NULL)
875 {
876 NeoFreeEvent(free_event);
877 }
878
879 // Delete the control device
880 NeoFreeControlDevice();
881
882 // Stop the adapter
883 NeoStopAdapter();
884
885 // Release the packet array
886 NeoFreePacketArray();
887
888 // Complete to stop
889 ctx->Initing = ctx->Inited = FALSE;
890 ctx->Connected = ctx->ConnectedForce = ctx->ConnectedOld = FALSE;
891 ctx->Halting = FALSE;
892
893 // Shutdown of Neo
894 NeoShutdown();
895 }
896
897 // Reset handler of adapter
NeoNdisResetEx(NDIS_HANDLE MiniportAdapterContext,PBOOLEAN AddressingReset)898 NDIS_STATUS NeoNdisResetEx(NDIS_HANDLE MiniportAdapterContext, PBOOLEAN AddressingReset)
899 {
900 return NDIS_STATUS_SUCCESS;
901 }
902
903 // Hang-up check handler of adapter
NeoNdisCheckForHangEx(NDIS_HANDLE MiniportAdapterContext)904 BOOLEAN NeoNdisCheckForHangEx(NDIS_HANDLE MiniportAdapterContext)
905 {
906 return FALSE;
907 }
908
909 // OID request handler
NeoNdisOidRequest(NDIS_HANDLE MiniportAdapterContext,PNDIS_OID_REQUEST OidRequest)910 NDIS_STATUS NeoNdisOidRequest(NDIS_HANDLE MiniportAdapterContext,
911 PNDIS_OID_REQUEST OidRequest)
912 {
913 NDIS_STATUS ret = STATUS_UNSUCCESSFUL;
914 ULONG dummy = 0;
915
916 switch (OidRequest->RequestType)
917 {
918 case NdisRequestQueryInformation:
919 case NdisRequestQueryStatistics:
920 ret = NeoNdisQuery(MiniportAdapterContext,
921 OidRequest->DATA.QUERY_INFORMATION.Oid,
922 OidRequest->DATA.QUERY_INFORMATION.InformationBuffer,
923 OidRequest->DATA.QUERY_INFORMATION.InformationBufferLength,
924 &OidRequest->DATA.QUERY_INFORMATION.BytesWritten,
925 &OidRequest->DATA.QUERY_INFORMATION.BytesNeeded);
926 break;
927
928 case NdisRequestSetInformation:
929 ret = NeoNdisSet(MiniportAdapterContext,
930 OidRequest->DATA.SET_INFORMATION.Oid,
931 OidRequest->DATA.SET_INFORMATION.InformationBuffer,
932 OidRequest->DATA.SET_INFORMATION.InformationBufferLength,
933 &dummy,
934 &OidRequest->DATA.SET_INFORMATION.BytesNeeded);
935 break;
936
937 default:
938 ret = NDIS_STATUS_NOT_SUPPORTED;
939 break;
940 }
941
942 return ret;
943 }
944
945
946 // Information acquisition handler of adapter
NeoNdisQuery(NDIS_HANDLE MiniportAdapterContext,NDIS_OID Oid,void * InformationBuffer,ULONG InformationBufferLength,ULONG * BytesWritten,ULONG * BytesNeeded)947 NDIS_STATUS NeoNdisQuery(NDIS_HANDLE MiniportAdapterContext,
948 NDIS_OID Oid,
949 void *InformationBuffer,
950 ULONG InformationBufferLength,
951 ULONG *BytesWritten,
952 ULONG *BytesNeeded)
953 {
954 NDIS_MEDIUM media;
955 void *buf;
956 UINT value32;
957 USHORT value16;
958 UINT size;
959 NDIS_STATISTICS_INFO stat;
960 NDIS_INTERRUPT_MODERATION_PARAMETERS intp;
961
962 if (ctx == NULL)
963 {
964 return NDIS_STATUS_FAILURE;
965 }
966
967 // Initialization
968 size = sizeof(UINT);
969 value32 = value16 = 0;
970 buf = &value32;
971
972 // Branch processing
973 switch (Oid)
974 {
975 case OID_GEN_SUPPORTED_LIST:
976 // Return a list of supported OID
977 buf = SupportedOids;
978 size = sizeof(SupportedOids);
979 break;
980
981 case OID_GEN_MAC_OPTIONS:
982 // Ethernet option
983 value32 = NDIS_MAC_OPTION_TRANSFERS_NOT_PEND | NDIS_MAC_OPTION_RECEIVE_SERIALIZED |
984 NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | NDIS_MAC_OPTION_NO_LOOPBACK;
985 break;
986
987 case OID_GEN_HARDWARE_STATUS:
988 // Hardware state
989 buf = &ctx->HardwareStatus;
990 size = sizeof(NDIS_HARDWARE_STATUS);
991 break;
992
993 case OID_GEN_MEDIA_SUPPORTED:
994 case OID_GEN_MEDIA_IN_USE:
995 // Type of media
996 media = NdisMedium802_3;
997 buf = &media;
998 size = sizeof(NDIS_MEDIUM);
999 break;
1000
1001 case OID_GEN_CURRENT_LOOKAHEAD:
1002 case OID_GEN_MAXIMUM_LOOKAHEAD:
1003 // Read-ahead available size
1004 value32 = NEO_MAX_PACKET_SIZE_ANNOUNCE - NEO_MIN_PACKET_SIZE;
1005 break;
1006
1007 case OID_GEN_MAXIMUM_FRAME_SIZE:
1008 // Maximum frame size
1009 value32 = NEO_MAX_PACKET_SIZE_ANNOUNCE - NEO_MIN_PACKET_SIZE;
1010 break;
1011
1012 case OID_GEN_MAXIMUM_TOTAL_SIZE:
1013 case OID_GEN_TRANSMIT_BLOCK_SIZE:
1014 case OID_GEN_RECEIVE_BLOCK_SIZE:
1015 // Maximum packet size
1016 value32 = NEO_MAX_PACKET_SIZE_ANNOUNCE;
1017 break;
1018
1019 case OID_GEN_TRANSMIT_BUFFER_SPACE:
1020 case OID_GEN_RECEIVE_BUFFER_SPACE:
1021 // Buffer size
1022 value32 = NEO_MAX_PACKET_SIZE_ANNOUNCE * NEO_MAX_PACKET_EXCHANGE;
1023 break;
1024
1025 case OID_GEN_LINK_SPEED:
1026 // Communication speed
1027 value32 = (UINT)(max_speed / 100);
1028 break;
1029
1030 case OID_GEN_VENDOR_ID:
1031 // Vendor ID
1032 NeoCopy(&value32, ctx->MacAddress, 3);
1033 value32 &= 0xFFFFFF00;
1034 value32 |= 0x01;
1035 break;
1036
1037 case OID_GEN_VENDOR_DESCRIPTION:
1038 // Hardware ID
1039 buf = ctx->HardwarePrintableID;
1040 size = (UINT)strlen(ctx->HardwarePrintableID) + 1;
1041 break;
1042
1043 case OID_GEN_DRIVER_VERSION:
1044 // Driver version
1045 value16 = ((USHORT)NEO_NDIS_MAJOR_VERSION << 8) | NEO_NDIS_MINOR_VERSION;
1046 buf = &value16;
1047 size = sizeof(USHORT);
1048 break;
1049
1050 case OID_GEN_VENDOR_DRIVER_VERSION:
1051 // Vendor driver version
1052 value16 = ((USHORT)NEO_NDIS_MAJOR_VERSION << 8) | NEO_NDIS_MINOR_VERSION;
1053 buf = &value16;
1054 size = sizeof(USHORT);
1055 break;
1056
1057 case OID_802_3_PERMANENT_ADDRESS:
1058 case OID_802_3_CURRENT_ADDRESS:
1059 // MAC address
1060 buf = ctx->MacAddress;
1061 size = NEO_MAC_ADDRESS_SIZE;
1062 break;
1063
1064 case OID_802_3_MAXIMUM_LIST_SIZE:
1065 // Number of multicast
1066 value32 = NEO_MAX_MULTICASE;
1067 break;
1068
1069 case OID_GEN_MAXIMUM_SEND_PACKETS:
1070 // Number of packets that can be sent at a time
1071 value32 = NEO_MAX_PACKET_EXCHANGE;
1072 break;
1073
1074 case OID_GEN_XMIT_OK:
1075 // Number of packets sent
1076 value32 = ctx->Status.NumPacketSend;
1077 break;
1078
1079 case OID_GEN_RCV_OK:
1080 // Number of received packets
1081 value32 = ctx->Status.NumPacketRecv;
1082 break;
1083
1084 case OID_GEN_XMIT_ERROR:
1085 // Number of transmission error packets
1086 value32 = ctx->Status.NumPacketSendError;
1087 break;
1088
1089 case OID_GEN_RCV_ERROR:
1090 // Number of error packets received
1091 value32 = ctx->Status.NumPacketRecvError;
1092 break;
1093
1094 case OID_GEN_RCV_NO_BUFFER:
1095 // Number of reception buffer shortage occurrences
1096 value32 = ctx->Status.NumPacketRecvNoBuffer;
1097 break;
1098
1099 case OID_802_3_RCV_ERROR_ALIGNMENT:
1100 // Number of errors
1101 value32 = 0;
1102 break;
1103
1104 case OID_GEN_MEDIA_CONNECT_STATUS:
1105 // Cable connection state
1106 NeoCheckConnectState();
1107 if (keep_link == false)
1108 {
1109 value32 = ctx->Connected ? NdisMediaStateConnected : NdisMediaStateDisconnected;
1110 }
1111 else
1112 {
1113 value32 = NdisMediaStateConnected;
1114 }
1115 break;
1116
1117 case OID_802_3_XMIT_ONE_COLLISION:
1118 case OID_802_3_XMIT_MORE_COLLISIONS:
1119 // Number of collisions
1120 value32 = 0;
1121 break;
1122
1123 case OID_GEN_CURRENT_PACKET_FILTER:
1124 // Current settings of the packet filter
1125 value32 = ctx->CurrentPacketFilter;
1126 break;
1127
1128 /* case OID_GEN_PROTOCOL_OPTIONS:
1129 // Current value of the protocol option
1130 value32 = ctx->CurrentProtocolOptions;
1131 break;*/
1132
1133 case OID_GEN_STATISTICS:
1134 // Statistics (NDIS 6.0)
1135 NeoZero(&stat, sizeof(stat));
1136 buf = &stat;
1137 size = sizeof(stat);
1138
1139 stat.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
1140 stat.Header.Revision = NDIS_STATISTICS_INFO_REVISION_1;
1141 stat.Header.Size = NDIS_SIZEOF_STATISTICS_INFO_REVISION_1;
1142 stat.SupportedStatistics =
1143 NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_RCV |
1144 NDIS_STATISTICS_FLAGS_VALID_MULTICAST_FRAMES_RCV |
1145 NDIS_STATISTICS_FLAGS_VALID_BROADCAST_FRAMES_RCV |
1146 NDIS_STATISTICS_FLAGS_VALID_BYTES_RCV |
1147 NDIS_STATISTICS_FLAGS_VALID_RCV_DISCARDS |
1148 NDIS_STATISTICS_FLAGS_VALID_RCV_ERROR |
1149 NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_XMIT |
1150 NDIS_STATISTICS_FLAGS_VALID_MULTICAST_FRAMES_XMIT |
1151 NDIS_STATISTICS_FLAGS_VALID_BROADCAST_FRAMES_XMIT |
1152 NDIS_STATISTICS_FLAGS_VALID_BYTES_XMIT |
1153 NDIS_STATISTICS_FLAGS_VALID_XMIT_ERROR |
1154 NDIS_STATISTICS_FLAGS_VALID_XMIT_DISCARDS |
1155 NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_RCV |
1156 NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_RCV |
1157 NDIS_STATISTICS_FLAGS_VALID_BROADCAST_BYTES_RCV |
1158 NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_XMIT |
1159 NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_XMIT |
1160 NDIS_STATISTICS_FLAGS_VALID_BROADCAST_BYTES_XMIT;
1161
1162 stat.ifInErrors = ctx->Status.Int64NumRecvError;
1163 stat.ifHCInOctets = ctx->Status.Int64BytesRecvTotal;
1164 stat.ifHCInUcastPkts = ctx->Status.Int64NumRecvUnicast;
1165 stat.ifHCInBroadcastPkts = ctx->Status.Int64NumRecvBroadcast;
1166 stat.ifHCOutOctets = ctx->Status.Int64BytesSendTotal;
1167 stat.ifHCOutUcastPkts = ctx->Status.Int64NumSendUnicast;
1168 stat.ifHCOutBroadcastPkts = ctx->Status.Int64NumSendBroadcast;
1169 stat.ifOutErrors = ctx->Status.Int64NumSendError;
1170 stat.ifHCInUcastOctets = ctx->Status.Int64BytesRecvUnicast;
1171 stat.ifHCInBroadcastOctets = ctx->Status.Int64BytesRecvBroadcast;
1172 stat.ifHCOutUcastOctets = ctx->Status.Int64BytesSendUnicast;
1173 stat.ifHCOutBroadcastOctets = ctx->Status.Int64BytesSendBroadcast;
1174 break;
1175
1176 case OID_GEN_INTERRUPT_MODERATION:
1177 // Interrupt Moderation (NDIS 6.0)
1178 NeoZero(&intp, sizeof(intp));
1179 buf = &intp;
1180 size = sizeof(intp);
1181
1182 intp.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
1183 intp.Header.Revision = NDIS_INTERRUPT_MODERATION_PARAMETERS_REVISION_1;
1184 intp.Header.Size = NDIS_SIZEOF_INTERRUPT_MODERATION_PARAMETERS_REVISION_1;
1185 intp.InterruptModeration = NdisInterruptModerationNotSupported;
1186 break;
1187
1188 default:
1189 // Unknown OID
1190 *BytesWritten = 0;
1191 return NDIS_STATUS_INVALID_OID;
1192 }
1193
1194 if (size > InformationBufferLength)
1195 {
1196 // Undersize
1197 *BytesNeeded = size;
1198 *BytesWritten = 0;
1199 return NDIS_STATUS_INVALID_LENGTH;
1200 }
1201
1202 // Data copy
1203 NeoCopy(InformationBuffer, buf, size);
1204 *BytesWritten = size;
1205
1206 return NDIS_STATUS_SUCCESS;
1207 }
1208
1209 // Set the cable connection state
NeoSetConnectState(BOOL connected)1210 void NeoSetConnectState(BOOL connected)
1211 {
1212 if (ctx == NULL)
1213 {
1214 return;
1215 }
1216 ctx->Connected = connected;
1217 NeoCheckConnectState();
1218 }
1219
1220 // Check the cable connection state
NeoCheckConnectState()1221 void NeoCheckConnectState()
1222 {
1223 NDIS_STATUS_INDICATION t;
1224 NDIS_LINK_STATE state;
1225 if (ctx == NULL || ctx->NdisMiniport == NULL)
1226 {
1227 return;
1228 }
1229
1230 NeoZero(&t, sizeof(t));
1231 t.Header.Type = NDIS_OBJECT_TYPE_STATUS_INDICATION;
1232 t.Header.Revision = NDIS_STATUS_INDICATION_REVISION_1;
1233 t.Header.Size = NDIS_SIZEOF_STATUS_INDICATION_REVISION_1;
1234
1235 t.SourceHandle = ctx->NdisMiniport;
1236
1237 NeoZero(&state, sizeof(state));
1238 state.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
1239 state.Header.Revision = NDIS_LINK_STATE_REVISION_1;
1240 state.Header.Size = NDIS_SIZEOF_LINK_STATE_REVISION_1;
1241
1242 state.MediaDuplexState = NdisPauseFunctionsSendAndReceive;
1243 state.XmitLinkSpeed = state.RcvLinkSpeed = max_speed;
1244 state.PauseFunctions = NdisPauseFunctionsUnsupported;
1245
1246 t.StatusCode = NDIS_STATUS_LINK_STATE;
1247 t.StatusBuffer = &state;
1248 t.StatusBufferSize = sizeof(NDIS_LINK_STATE);
1249
1250 if (keep_link == false)
1251 {
1252 if (ctx->ConnectedOld != ctx->Connected || ctx->ConnectedForce)
1253 {
1254 ctx->ConnectedForce = FALSE;
1255 ctx->ConnectedOld = ctx->Connected;
1256 if (ctx->Halting == FALSE)
1257 {
1258 state.MediaConnectState = ctx->Connected ? MediaConnectStateConnected : MediaConnectStateDisconnected;
1259 NdisMIndicateStatusEx(ctx->NdisMiniport, &t);
1260 }
1261 }
1262 }
1263 else
1264 {
1265 if (ctx->ConnectedForce)
1266 {
1267 ctx->ConnectedForce = false;
1268
1269 if (ctx->Halting == FALSE)
1270 {
1271 state.MediaConnectState = MediaConnectStateConnected;
1272 NdisMIndicateStatusEx(ctx->NdisMiniport, &t);
1273 }
1274 }
1275 }
1276 }
1277
1278 // Information setting handler of adapter
NeoNdisSet(NDIS_HANDLE MiniportAdapterContext,NDIS_OID Oid,void * InformationBuffer,ULONG InformationBufferLength,ULONG * BytesRead,ULONG * BytesNeeded)1279 NDIS_STATUS NeoNdisSet(
1280 NDIS_HANDLE MiniportAdapterContext,
1281 NDIS_OID Oid,
1282 void *InformationBuffer,
1283 ULONG InformationBufferLength,
1284 ULONG *BytesRead,
1285 ULONG *BytesNeeded)
1286 {
1287 if (ctx == NULL)
1288 {
1289 return STATUS_UNSUCCESSFUL;
1290 }
1291
1292 // Initialization
1293 *BytesRead = 0;
1294 *BytesNeeded = 0;
1295
1296 // Branch processing
1297 switch (Oid)
1298 {
1299 case OID_GEN_CURRENT_PACKET_FILTER:
1300 /* Packet filter */
1301 if (InformationBufferLength != 4)
1302 {
1303 *BytesNeeded = 4;
1304 return NDIS_STATUS_INVALID_LENGTH;
1305 }
1306 *BytesRead = 4;
1307 ctx->CurrentPacketFilter = *((UINT *)InformationBuffer);
1308 return NDIS_STATUS_SUCCESS;
1309
1310 // case OID_GEN_PROTOCOL_OPTIONS:
1311 /* Current protocol option value */
1312 /* if (InformationBufferLength != 4)
1313 {
1314 *BytesNeeded = 4;
1315 return NDIS_STATUS_INVALID_LENGTH;
1316 }
1317 *BytesRead = 4;
1318 ctx->CurrentProtocolOptions = *((UINT *)InformationBuffer);
1319 return NDIS_STATUS_SUCCESS;*/
1320
1321 case OID_GEN_CURRENT_LOOKAHEAD:
1322 /* Look ahead */
1323 if (InformationBufferLength != 4)
1324 {
1325 *BytesNeeded = 4;
1326 return NDIS_STATUS_INVALID_LENGTH;
1327 }
1328 *BytesRead = 4;
1329 return NDIS_STATUS_SUCCESS;
1330
1331 case OID_GEN_LINK_PARAMETERS:
1332 // NDIS 6.0 Link setting
1333 *BytesRead = InformationBufferLength;
1334 return NDIS_STATUS_SUCCESS;
1335
1336 case OID_802_3_MULTICAST_LIST:
1337 // Multicast list
1338 *BytesRead = InformationBufferLength;
1339
1340 return NDIS_STATUS_SUCCESS;
1341
1342 case OID_PNP_SET_POWER:
1343 case OID_PNP_QUERY_POWER:
1344 // Power events
1345 *BytesRead = InformationBufferLength;
1346
1347 return NDIS_STATUS_SUCCESS;
1348 }
1349
1350 return NDIS_STATUS_INVALID_OID;
1351 }
1352
1353 // Set status values of NET_BUFFER_LISTs
NeoNdisSetNetBufferListsStatus(NET_BUFFER_LIST * nbl,UINT status)1354 void NeoNdisSetNetBufferListsStatus(NET_BUFFER_LIST *nbl, UINT status)
1355 {
1356 if (nbl == NULL)
1357 {
1358 return;
1359 }
1360
1361 while (nbl != NULL)
1362 {
1363 NET_BUFFER_LIST_STATUS(nbl) = status;
1364
1365 nbl = NET_BUFFER_LIST_NEXT_NBL(nbl);
1366 }
1367 }
1368
1369 // Packet send handler
NeoNdisSendNetBufferLists(NDIS_HANDLE MiniportAdapterContext,NET_BUFFER_LIST * NetBufferLists,NDIS_PORT_NUMBER PortNumber,ULONG SendFlags)1370 void NeoNdisSendNetBufferLists(NDIS_HANDLE MiniportAdapterContext,
1371 NET_BUFFER_LIST *NetBufferLists,
1372 NDIS_PORT_NUMBER PortNumber,
1373 ULONG SendFlags)
1374 {
1375 bool is_dispatch_level = SendFlags & NDIS_SEND_FLAGS_DISPATCH_LEVEL;
1376 UINT send_complete_flags = 0;
1377 if (ctx == NULL)
1378 {
1379 return;
1380 }
1381
1382 if (is_dispatch_level)
1383 {
1384 send_complete_flags |= NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL;
1385 }
1386
1387 InterlockedIncrement(&ctx->NumCurrentDispatch);
1388
1389 // Update the connection state
1390 NeoCheckConnectState();
1391
1392 if (ctx->Halting != FALSE || ctx->Opened == FALSE || ctx->Paused)
1393 {
1394 UINT status = NDIS_STATUS_FAILURE;
1395
1396 if (ctx->Paused)
1397 {
1398 status = NDIS_STATUS_PAUSED;
1399 }
1400 else if (ctx->Halting)
1401 {
1402 status = NDIS_STATUS_FAILURE;
1403 }
1404 else if (ctx->Opened == false && keep_link)
1405 {
1406 status = NDIS_STATUS_SUCCESS;
1407 }
1408
1409 NeoNdisSetNetBufferListsStatus(NetBufferLists, status);
1410
1411 InterlockedDecrement(&ctx->NumCurrentDispatch);
1412
1413 NdisMSendNetBufferListsComplete(ctx->NdisMiniport, NetBufferLists, send_complete_flags);
1414
1415 return;
1416 }
1417
1418 // Operation of the packet queue
1419 NeoLockPacketQueue();
1420 {
1421 NET_BUFFER_LIST *nbl;
1422
1423 if (ctx->Halting != FALSE || ctx->Opened == FALSE || ctx->Paused)
1424 {
1425 UINT status = NDIS_STATUS_FAILURE;
1426
1427 if (ctx->Paused)
1428 {
1429 status = NDIS_STATUS_PAUSED;
1430 }
1431 else if (ctx->Halting)
1432 {
1433 status = NDIS_STATUS_FAILURE;
1434 }
1435 else if (ctx->Opened == false && keep_link)
1436 {
1437 status = NDIS_STATUS_SUCCESS;
1438 }
1439
1440 NeoUnlockPacketQueue();
1441
1442 NeoNdisSetNetBufferListsStatus(NetBufferLists, status);
1443
1444 InterlockedDecrement(&ctx->NumCurrentDispatch);
1445
1446 NdisMSendNetBufferListsComplete(ctx->NdisMiniport, NetBufferLists, send_complete_flags);
1447
1448 return;
1449 }
1450
1451 nbl = NetBufferLists;
1452
1453 while (nbl != NULL)
1454 {
1455 NET_BUFFER *nb = NET_BUFFER_LIST_FIRST_NB(nbl);
1456
1457 NET_BUFFER_LIST_STATUS(nbl) = NDIS_STATUS_SUCCESS;
1458
1459 while (nb != NULL)
1460 {
1461 UINT size = NET_BUFFER_DATA_LENGTH(nb);
1462
1463 if (size >= NEO_MIN_PACKET_SIZE && size <= NEO_MAX_PACKET_SIZE)
1464 {
1465 UCHAR *buf = NeoMalloc(size);
1466 void *ptr;
1467
1468 ptr = NdisGetDataBuffer(nb, size, buf, 1, 0);
1469
1470 if (ptr == NULL)
1471 {
1472 ctx->Status.NumPacketSendError++;
1473 ctx->Status.Int64NumSendError++;
1474 NeoFree(buf);
1475 }
1476 else
1477 {
1478 if (ptr != buf)
1479 {
1480 NeoCopy(buf, ptr, size);
1481 }
1482
1483 NeoInsertQueue(buf, size);
1484 ctx->Status.NumPacketSend++;
1485
1486 if (buf[0] & 0x40)
1487 {
1488 ctx->Status.Int64NumSendBroadcast++;
1489 ctx->Status.Int64BytesSendBroadcast += (UINT64)size;
1490 }
1491 else
1492 {
1493 ctx->Status.Int64NumSendUnicast++;
1494 ctx->Status.Int64BytesSendUnicast += (UINT64)size;
1495 }
1496
1497 ctx->Status.Int64BytesSendTotal += (UINT64)size;
1498 }
1499 }
1500 else
1501 {
1502 ctx->Status.NumPacketSendError++;
1503 ctx->Status.Int64NumSendError++;
1504 }
1505
1506 nb = NET_BUFFER_NEXT_NB(nb);
1507 }
1508
1509 nbl = NET_BUFFER_LIST_NEXT_NBL(nbl);
1510 }
1511
1512 // Reception event
1513 NeoSet(ctx->Event);
1514 }
1515 NeoUnlockPacketQueue();
1516
1517 // Notify the transmission completion
1518 InterlockedDecrement(&ctx->NumCurrentDispatch);
1519 NdisMSendNetBufferListsComplete(ctx->NdisMiniport, NetBufferLists, send_complete_flags);
1520 }
1521
1522 // Initialize the packet array
NeoInitPacketArray()1523 void NeoInitPacketArray()
1524 {
1525 UINT i;
1526 // Create a packet buffer
1527 for (i = 0;i < NEO_MAX_PACKET_EXCHANGE;i++)
1528 {
1529 ctx->PacketBuffer[i] = NeoNewPacketBuffer();
1530 }
1531 }
1532
1533 // Release the packet array
NeoFreePacketArray()1534 void NeoFreePacketArray()
1535 {
1536 UINT i;
1537 for (i = 0;i < NEO_MAX_PACKET_EXCHANGE;i++)
1538 {
1539 NeoFreePacketBuffer(ctx->PacketBuffer[i]);
1540 ctx->PacketBuffer[i] = NULL;
1541 }
1542 }
1543
1544 // Release the packet buffer
NeoFreePacketBuffer(PACKET_BUFFER * p)1545 void NeoFreePacketBuffer(PACKET_BUFFER *p)
1546 {
1547 // Validate arguments
1548 if (p == NULL)
1549 {
1550 return;
1551 }
1552
1553 // Release the NET_BUFFER_LIST
1554 NdisFreeNetBufferList(p->NetBufferList);
1555 // Release the NET_BUFFER_LIST pool
1556 NdisFreeNetBufferListPool(p->NetBufferListPool);
1557 // Release the memory
1558 NeoFree(p);
1559 }
1560
1561 // Create a packet buffer
NeoNewPacketBuffer()1562 PACKET_BUFFER *NeoNewPacketBuffer()
1563 {
1564 PACKET_BUFFER *p;
1565 NET_BUFFER_LIST_POOL_PARAMETERS p1;
1566
1567 // Memory allocation
1568 p = NeoZeroMalloc(sizeof(PACKET_BUFFER));
1569
1570 // Create a NET_BUFFER_LIST pool
1571 NeoZero(&p1, sizeof(p1));
1572 p1.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
1573 p1.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
1574 p1.Header.Size = NDIS_SIZEOF_NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
1575 p1.ProtocolId = NDIS_PROTOCOL_ID_DEFAULT;
1576 p1.fAllocateNetBuffer = TRUE;
1577 p1.DataSize = NEO_MAX_PACKET_SIZE;
1578 p1.PoolTag = 'SETH';
1579 p->NetBufferListPool = NdisAllocateNetBufferListPool(NULL, &p1);
1580
1581 // Create a NET_BUFFER_LIST
1582 p->NetBufferList = NdisAllocateNetBufferList(p->NetBufferListPool, 0, 0);
1583
1584 return p;
1585 }
1586
1587 // Reset the event
NeoReset(NEO_EVENT * event)1588 void NeoReset(NEO_EVENT *event)
1589 {
1590 // Validate arguments
1591 if (event == NULL)
1592 {
1593 return;
1594 }
1595
1596 KeResetEvent(event->event);
1597 }
1598
1599 // Set the event
NeoSet(NEO_EVENT * event)1600 void NeoSet(NEO_EVENT *event)
1601 {
1602 // Validate arguments
1603 if (event == NULL)
1604 {
1605 return;
1606 }
1607
1608 KeSetEvent(event->event, 0, FALSE);
1609 }
1610
1611 // Release the event
NeoFreeEvent(NEO_EVENT * event)1612 void NeoFreeEvent(NEO_EVENT *event)
1613 {
1614 // Validate arguments
1615 if (event == NULL)
1616 {
1617 return;
1618 }
1619
1620 ZwClose(event->event_handle);
1621
1622 // Release the memory
1623 NeoFree(event);
1624 }
1625
1626 // Create a new event
NeoNewEvent(char * name)1627 NEO_EVENT *NeoNewEvent(char *name)
1628 {
1629 UNICODE *unicode_name;
1630 NEO_EVENT *event;
1631 // Validate arguments
1632 if (name == NULL)
1633 {
1634 return NULL;
1635 }
1636
1637 // Convert the name to Unicode
1638 unicode_name = NewUnicode(name);
1639 if (unicode_name == NULL)
1640 {
1641 return NULL;
1642 }
1643
1644 // Memory allocation
1645 event = NeoZeroMalloc(sizeof(NEO_EVENT));
1646 if (event == NULL)
1647 {
1648 FreeUnicode(unicode_name);
1649 return NULL;
1650 }
1651
1652 // Create an Event
1653 event->event = IoCreateNotificationEvent(GetUnicode(unicode_name), &event->event_handle);
1654 if (event->event == NULL)
1655 {
1656 NeoFree(event);
1657 FreeUnicode(unicode_name);
1658 return NULL;
1659 }
1660
1661 // Initialize the event
1662 KeInitializeEvent(event->event, NotificationEvent, FALSE);
1663 KeClearEvent(event->event);
1664
1665 // Release a string
1666 FreeUnicode(unicode_name);
1667
1668 return event;
1669 }
1670
1671 // Get the Unicode string
GetUnicode(UNICODE * u)1672 NDIS_STRING *GetUnicode(UNICODE *u)
1673 {
1674 // Validate arguments
1675 if (u == NULL)
1676 {
1677 return NULL;
1678 }
1679
1680 return &u->String;
1681 }
1682
1683 // Release the Unicode strings
FreeUnicode(UNICODE * u)1684 void FreeUnicode(UNICODE *u)
1685 {
1686 // Validate arguments
1687 if (u == NULL)
1688 {
1689 return;
1690 }
1691
1692 // Release a string
1693 NdisFreeString(u->String);
1694
1695 // Release the memory
1696 NeoFree(u);
1697 }
1698
1699 // Create a new Unicode string
NewUnicode(char * str)1700 UNICODE *NewUnicode(char *str)
1701 {
1702 UNICODE *u;
1703 // Validate arguments
1704 if (str == NULL)
1705 {
1706 return NULL;
1707 }
1708
1709 // Memory allocation
1710 u = NeoZeroMalloc(sizeof(UNICODE));
1711 if (u == NULL)
1712 {
1713 return NULL;
1714 }
1715
1716 // String initialization
1717 NdisInitializeString(&u->String, str);
1718
1719 return u;
1720 }
1721
1722 // Release the lock
NeoFreeLock(NEO_LOCK * lock)1723 void NeoFreeLock(NEO_LOCK *lock)
1724 {
1725 NDIS_SPIN_LOCK *spin_lock;
1726 // Validate arguments
1727 if (lock == NULL)
1728 {
1729 return;
1730 }
1731
1732 spin_lock = &lock->spin_lock;
1733 NdisFreeSpinLock(spin_lock);
1734
1735 // Release the memory
1736 NeoFree(lock);
1737 }
1738
1739 // Unlock
NeoUnlock(NEO_LOCK * lock)1740 void NeoUnlock(NEO_LOCK *lock)
1741 {
1742 NDIS_SPIN_LOCK *spin_lock;
1743 // Validate arguments
1744 if (lock == NULL)
1745 {
1746 return;
1747 }
1748
1749 spin_lock = &lock->spin_lock;
1750 NdisReleaseSpinLock(spin_lock);
1751 }
1752
1753 // Lock
NeoLock(NEO_LOCK * lock)1754 void NeoLock(NEO_LOCK *lock)
1755 {
1756 NDIS_SPIN_LOCK *spin_lock;
1757 // Validate arguments
1758 if (lock == NULL)
1759 {
1760 return;
1761 }
1762
1763 spin_lock = &lock->spin_lock;
1764 NdisAcquireSpinLock(spin_lock);
1765 }
1766
1767 // Creating a new lock
NeoNewLock()1768 NEO_LOCK *NeoNewLock()
1769 {
1770 NDIS_SPIN_LOCK *spin_lock;
1771
1772 // Memory allocation
1773 NEO_LOCK *lock = NeoZeroMalloc(sizeof(NEO_LOCK));
1774 if (lock == NULL)
1775 {
1776 return NULL;
1777 }
1778
1779 // Initialize spin lock
1780 spin_lock = &lock->spin_lock;
1781
1782 NdisAllocateSpinLock(spin_lock);
1783
1784 return lock;
1785 }
1786
1787 // Memory copy
NeoCopy(void * dst,void * src,UINT size)1788 void NeoCopy(void *dst, void *src, UINT size)
1789 {
1790 // Validate arguments
1791 if (dst == NULL || src == NULL || size == 0)
1792 {
1793 return;
1794 }
1795
1796 // Copy
1797 NdisMoveMemory(dst, src, size);
1798 }
1799
1800 // Memory clear
NeoZero(void * dst,UINT size)1801 void NeoZero(void *dst, UINT size)
1802 {
1803 // Validate arguments
1804 if (dst == NULL || size == 0)
1805 {
1806 return;
1807 }
1808
1809 // Clear
1810 NdisZeroMemory(dst, size);
1811 }
1812
1813 // Clear to zero by memory allocation
NeoZeroMalloc(UINT size)1814 void *NeoZeroMalloc(UINT size)
1815 {
1816 void *p = NeoMalloc(size);
1817 if (p == NULL)
1818 {
1819 // Memory allocation failure
1820 return NULL;
1821 }
1822 // Clear to zero
1823 NeoZero(p, size);
1824 return p;
1825 }
1826
1827 // Memory allocation
NeoMalloc(UINT size)1828 void *NeoMalloc(UINT size)
1829 {
1830 NDIS_STATUS r;
1831 void *p;
1832 if (size == 0)
1833 {
1834 size = 1;
1835 }
1836
1837 // Allocate the non-paged memory
1838 r = NdisAllocateMemoryWithTag(&p, size, 'SETH');
1839
1840 if (NG(r))
1841 {
1842 return NULL;
1843 }
1844 return p;
1845 }
1846
1847 // Release the memory
NeoFree(void * p)1848 void NeoFree(void *p)
1849 {
1850 // Validate arguments
1851 if (p == NULL)
1852 {
1853 return;
1854 }
1855
1856 // Release the memory
1857 NdisFreeMemory(p, 0, 0);
1858 }
1859
1860
1861