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