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(&current_time);
803 
804 		current_time_bytes = (UCHAR *)&current_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, &param, 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 = &param->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, &param, 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, &param, 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, &param, 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