125
129
IN PUNICODE_STRING p_RegistryPath)
127
131
NDIS_STATUS l_Status = NDIS_STATUS_FAILURE;
129
//==============================
130
// Allocate debugging text space
131
//==============================
132
NDIS_MINIPORT_CHARACTERISTICS *l_Properties = NULL;
136
134
//========================================================
137
135
// Notify NDIS that a new miniport driver is initializing.
138
136
//========================================================
140
138
NdisMInitializeWrapper (&g_NdisWrapperHandle,
141
g_TapDriverObject = p_DriverObject,
142
140
p_RegistryPath, NULL);
142
//======================
143
// Global initialization
144
//======================
147
MyDebugInit (10000); // Allocate debugging text space
150
if (!InitInstanceList ())
152
DEBUGP (("[TAP] Allocation failed for adapter instance list\n"));
144
156
//=======================================
145
157
// Set and register miniport entry points
146
158
//=======================================
148
NdisZeroMemory (&g_Properties, sizeof (g_Properties));
150
g_Properties.MajorNdisVersion = TAP_NDIS_MAJOR_VERSION;
151
g_Properties.MinorNdisVersion = TAP_NDIS_MINOR_VERSION;
152
g_Properties.InitializeHandler = AdapterCreate;
153
g_Properties.HaltHandler = AdapterHalt;
154
g_Properties.ResetHandler = AdapterReset;
155
g_Properties.TransferDataHandler = AdapterReceive;
156
g_Properties.SendHandler = AdapterTransmit;
157
g_Properties.QueryInformationHandler = AdapterQuery;
158
g_Properties.SetInformationHandler = AdapterModify;
159
g_Properties.DisableInterruptHandler = NULL;
160
g_Properties.EnableInterruptHandler = NULL;
161
g_Properties.HandleInterruptHandler = NULL;
162
g_Properties.ISRHandler = NULL;
163
g_Properties.ReconfigureHandler = NULL;
164
g_Properties.CheckForHangHandler = NULL;
165
g_Properties.ReturnPacketHandler = NULL;
166
g_Properties.SendPacketsHandler = NULL;
167
g_Properties.AllocateCompleteHandler = NULL;
169
g_Properties.CoCreateVcHandler = NULL;
170
g_Properties.CoDeleteVcHandler = NULL;
171
g_Properties.CoActivateVcHandler = NULL;
172
g_Properties.CoDeactivateVcHandler = NULL;
173
g_Properties.CoSendPacketsHandler = NULL;
174
g_Properties.CoRequestHandler = NULL;
176
#ifndef ENABLE_RANDOM_MAC
177
ConvertMacInfo (g_MAC, TAP_MAC_ROOT_ADDRESS, strlen (TAP_MAC_ROOT_ADDRESS));
160
l_Properties = MemAlloc (sizeof (NDIS_MINIPORT_CHARACTERISTICS), TRUE);
162
if (l_Properties == NULL)
164
DEBUGP (("[TAP] Allocation failed for miniport entry points\n"));
168
l_Properties->MajorNdisVersion = TAP_NDIS_MAJOR_VERSION;
169
l_Properties->MinorNdisVersion = TAP_NDIS_MINOR_VERSION;
170
l_Properties->InitializeHandler = AdapterCreate;
171
l_Properties->HaltHandler = AdapterHalt;
172
l_Properties->ResetHandler = AdapterReset; /* DISPATCH_LEVEL */
173
l_Properties->TransferDataHandler = AdapterReceive; /* DISPATCH_LEVEL */
174
l_Properties->SendHandler = AdapterTransmit; /* DISPATCH_LEVEL */
175
l_Properties->QueryInformationHandler = AdapterQuery; /* DISPATCH_LEVEL */
176
l_Properties->SetInformationHandler = AdapterModify; /* DISPATCH_LEVEL */
180
178
switch (l_Status =
181
NdisMRegisterMiniport (g_NdisWrapperHandle, &g_Properties,
182
sizeof (g_Properties)))
179
NdisMRegisterMiniport (g_NdisWrapperHandle, l_Properties,
180
sizeof (NDIS_MINIPORT_CHARACTERISTICS)))
184
182
case NDIS_STATUS_SUCCESS:
186
DEBUGP (("[TAP] version [%d.%d] registered miniport successfully\n",
187
TAP_DRIVER_MAJOR_VERSION, TAP_DRIVER_MINOR_VERSION));
184
DEBUGP (("[TAP] version [%d.%d] %s %s registered miniport successfully\n",
185
TAP_DRIVER_MAJOR_VERSION,
186
TAP_DRIVER_MINOR_VERSION,
189
DEBUGP (("Registry Path: '%S'\n", p_RegistryPath->Buffer));
309
343
NdisMRegisterAdapterShutdownHandler (p_AdapterHandle, l_Adapter,
311
l_Adapter->m_MiniportAdapterHandle = p_AdapterHandle;
312
345
l_Adapter->m_RegisteredAdapterShutdownHandler = TRUE;
314
//===========================================================
315
// Allocate spinlocks used to control access to
316
// shared data structures by concurrent threads of execution.
317
// QueueLock is used to lock the packet queue used
318
// for the TAP-Win32 NIC -> User Space packet flow direction.
319
// This code is designed to be fully SMP-safe.
320
//===========================================================
322
NdisAllocateSpinLock (&l_Adapter->m_Lock);
323
NdisAllocateSpinLock (&l_Adapter->m_QueueLock);
324
l_Adapter->m_AllocatedSpinlocks = TRUE;
326
347
//====================================
327
348
// Allocate and construct adapter name
328
349
//====================================
330
l_AdapterString.MaximumLength =
331
((PNDIS_MINIPORT_BLOCK) p_AdapterHandle)->MiniportName.Length + 5;
333
if ((l_Adapter->m_Name = l_AdapterString.Buffer =
334
ExAllocatePoolWithTag (NonPagedPool,
335
l_AdapterString.MaximumLength,
351
if (RtlUnicodeStringToAnsiString (
352
&l_Adapter->m_NameAnsi,
353
&((PNDIS_MINIPORT_BLOCK) p_AdapterHandle)->MiniportName,
354
TRUE) != STATUS_SUCCESS)
338
356
AdapterFreeResources (l_Adapter);
339
357
return NDIS_STATUS_RESOURCES;
342
RtlUnicodeStringToAnsiString (
344
&((PNDIS_MINIPORT_BLOCK) p_AdapterHandle)->MiniportName,
346
l_AdapterString.Buffer[l_AdapterString.Length] = 0;
348
//==================================
349
// Store and update MAC address info
350
//==================================
352
#ifdef ENABLE_RANDOM_MAC
353
GenerateRandomMac (g_MAC, l_Adapter->m_Name);
354
COPY_MAC (l_Adapter->m_MAC, g_MAC);
356
COPY_MAC (l_Adapter->m_MAC, g_MAC);
361
++(*((unsigned short *) l_MAC));
367
DEBUGP (("[%s] Using MAC %x:%x:%x:%x:%x:%x\n",
369
l_Adapter->m_MAC[0], l_Adapter->m_MAC[1], l_Adapter->m_MAC[2],
370
l_Adapter->m_MAC[3], l_Adapter->m_MAC[4], l_Adapter->m_MAC[5]));
377
for (i = 0; i < sizeof (MACADDR); ++i)
378
l_Adapter->m_MAC_Broadcast[i] = 0xFF;
381
360
//============================================
382
361
// Get parameters from registry which were set
383
362
// in the adapter advanced properties dialog.
414
/* Read optional MAC setting from registry */
416
NDIS_STRING key = NDIS_STRING_CONST("MAC");
417
ANSI_STRING mac_string;
418
NdisReadConfiguration (&status, &parm, configHandle,
419
&key, NdisParameterString);
420
if (status == NDIS_STATUS_SUCCESS)
422
if (parm->ParameterType == NdisParameterString)
424
if (RtlUnicodeStringToAnsiString (&mac_string, &parm->ParameterData.StringData, TRUE) == STATUS_SUCCESS)
426
l_MacFromRegistry = ParseMAC (l_Adapter->m_MAC, mac_string.Buffer);
427
RtlFreeAnsiString (&mac_string);
435
433
NdisCloseConfiguration (configHandle);
438
DEBUGP (("[%s] MTU=%d\n", l_Adapter->m_Name, l_Adapter->m_MTU));
436
DEBUGP (("[%s] MTU=%d\n", NAME (l_Adapter), l_Adapter->m_MTU));
439
//==================================
440
// Store and update MAC address info
441
//==================================
443
if (!l_MacFromRegistry)
444
GenerateRandomMac (l_Adapter->m_MAC, NAME (l_Adapter));
446
DEBUGP (("[%s] Using MAC %x:%x:%x:%x:%x:%x\n",
448
l_Adapter->m_MAC[0], l_Adapter->m_MAC[1], l_Adapter->m_MAC[2],
449
l_Adapter->m_MAC[3], l_Adapter->m_MAC[4], l_Adapter->m_MAC[5]));
456
for (i = 0; i < sizeof (MACADDR); ++i)
457
l_Adapter->m_MAC_Broadcast[i] = 0xFF;
441
460
//====================================
479
518
MYASSERT (!p_Adapter->m_CalledAdapterFreeResources);
480
519
p_Adapter->m_CalledAdapterFreeResources = TRUE;
482
if (p_Adapter->m_Name)
484
ExFreePool (p_Adapter->m_Name);
485
p_Adapter->m_Name = NULL;
488
if (p_Adapter->m_AllocatedSpinlocks)
490
NdisFreeSpinLock (&p_Adapter->m_Lock);
491
NdisFreeSpinLock (&p_Adapter->m_QueueLock);
492
p_Adapter->m_AllocatedSpinlocks = FALSE;
521
if (p_Adapter->m_NameAnsi.Buffer)
522
RtlFreeAnsiString (&p_Adapter->m_NameAnsi);
495
524
if (p_Adapter->m_RegisteredAdapterShutdownHandler)
525
NdisMDeregisterAdapterShutdownHandler (p_Adapter->m_MiniportAdapterHandle);
527
if (p_Adapter->m_MCLockAllocated)
528
NdisFreeSpinLock (&l_Adapter->m_MCLock);
532
DestroyTapDevice (TapExtensionPointer p_Extension)
534
DEBUGP (("[%s] Destroying tap device\n", p_Extension->m_TapName));
536
//======================================
537
// Let clients know we are shutting down
538
//======================================
539
p_Extension->m_TapIsRunning = FALSE;
540
p_Extension->m_TapOpens = 0;
541
p_Extension->m_Halt = TRUE;
543
//=====================================
544
// If we are concurrently executing in
545
// TapDeviceHook or AdapterTransmit,
546
// give those calls time to finish.
547
// Note that we must be running at IRQL
548
// < DISPATCH_LEVEL in order to call
550
//=====================================
553
//===========================================================
554
// Exhaust IRP and packet queues. Any pending IRPs will
555
// be cancelled, causing user-space to get this error
556
// on overlapped reads:
557
// The I/O operation has been aborted because of either a
558
// thread exit or an application request. (code=995)
559
// It's important that user-space close the device handle
560
// when this code is returned, so that when we finally
561
// do a NdisMDeregisterDevice, the device reference count
562
// is 0. Otherwise the driver will not unload even if the
563
// the last adapter has been halted.
564
//===========================================================
565
FlushQueues (p_Extension);
566
NdisMSleep (500000); // give user space time to respond to IRP cancel
568
TapDeviceFreeResources (p_Extension);
572
TapDeviceFreeResources (TapExtensionPointer p_Extension)
574
MYASSERT (p_Extension);
575
MYASSERT (!p_Extension->m_CalledTapDeviceFreeResources);
576
p_Extension->m_CalledTapDeviceFreeResources = TRUE;
578
if (p_Extension->m_PacketQueue)
579
QueueFree (p_Extension->m_PacketQueue);
580
if (p_Extension->m_IrpQueue)
581
QueueFree (p_Extension->m_IrpQueue);
583
if (p_Extension->m_CreatedUnicodeLinkName)
584
RtlFreeUnicodeString (&p_Extension->m_UnicodeLinkName);
586
//==========================================================
587
// According to DDK docs, the device is not actually deleted
588
// until its reference count falls to zero. That means we
589
// still need to gracefully fail TapDeviceHook requests
590
// after this point, otherwise ugly things would happen if
591
// the device was disabled (e.g. in the network connections
592
// control panel) while a userspace app still held an open
593
// file handle to it.
594
//==========================================================
596
if (p_Extension->m_TapDevice)
497
NdisMDeregisterAdapterShutdownHandler
498
(p_Adapter->m_MiniportAdapterHandle);
499
p_Adapter->m_RegisteredAdapterShutdownHandler = FALSE;
599
status = (NdisMDeregisterDevice (p_Extension->m_TapDeviceHandle)
600
== NDIS_STATUS_SUCCESS);
601
DEBUGP (("[TAP] Deregistering TAP device, status=%d\n", (int)status));
502
NdisZeroMemory ((PVOID) p_Adapter, sizeof (TapAdapter));
503
NdisFreeMemory ((PVOID) p_Adapter, sizeof (TapAdapter), 0);
505
//==============================
506
// Free debugging text space
507
//==============================
604
if (p_Extension->m_TapName)
605
MemFree (p_Extension->m_TapName, NAME_BUFFER_SIZE);
607
if (p_Extension->m_AllocatedSpinlocks)
608
NdisFreeSpinLock (&p_Extension->m_QueueLock);
513
611
//========================================================================
514
612
// Tap Device Initialization
515
613
//========================================================================
517
CreateTapDevice (TapAdapterPointer p_Adapter)
616
CreateTapDevice (TapExtensionPointer p_Extension, const char *p_Name)
519
unsigned short l_AdapterLength =
520
(unsigned short) strlen (p_Adapter->m_Name);
618
# define SIZEOF_DISPATCH (sizeof(PDRIVER_DISPATCH) * (IRP_MJ_MAXIMUM_FUNCTION + 1))
619
PDRIVER_DISPATCH *l_Dispatch = NULL;
521
620
ANSI_STRING l_TapString, l_LinkString;
522
TapExtensionPointer l_Extension;
523
621
UNICODE_STRING l_TapUnicode;
524
622
BOOLEAN l_FreeTapUnicode = FALSE;
525
623
NTSTATUS l_Status, l_Return = NDIS_STATUS_SUCCESS;
624
const char *l_UsableName;
626
DEBUGP (("[TAP] version [%d.%d] creating tap device: %s\n",
627
TAP_DRIVER_MAJOR_VERSION,
628
TAP_DRIVER_MINOR_VERSION,
631
NdisZeroMemory (p_Extension, sizeof (TapExtension));
633
INIT_MUTEX (&p_Extension->m_OpenCloseMutex);
527
635
l_LinkString.Buffer = NULL;
529
l_TapString.MaximumLength = l_LinkString.MaximumLength =
530
l_AdapterLength + strlen (TAPSUFFIX);
532
DEBUGP (("[TAP] version [%d.%d] creating tap device: %s\n",
533
TAP_DRIVER_MAJOR_VERSION,
534
TAP_DRIVER_MINOR_VERSION,
636
l_TapString.Buffer = NULL;
638
l_TapString.MaximumLength = l_LinkString.MaximumLength = NAME_BUFFER_SIZE;
640
//=======================================
641
// Set TAP device entry points
642
//=======================================
644
if ((l_Dispatch = MemAlloc (SIZEOF_DISPATCH, TRUE)) == NULL)
646
DEBUGP (("[%s] couldn't alloc TAP dispatch table\n", p_Name));
647
l_Return = NDIS_STATUS_RESOURCES;
651
l_Dispatch[IRP_MJ_DEVICE_CONTROL] = TapDeviceHook;
652
l_Dispatch[IRP_MJ_READ] = TapDeviceHook;
653
l_Dispatch[IRP_MJ_WRITE] = TapDeviceHook;
654
l_Dispatch[IRP_MJ_CREATE] = TapDeviceHook;
655
l_Dispatch[IRP_MJ_CLOSE] = TapDeviceHook;
657
//==================================
658
// Find the beginning of the GUID
659
//==================================
660
l_UsableName = p_Name;
661
while (*l_UsableName != '{')
663
if (*l_UsableName == '\0')
665
DEBUGP (("[%s] couldn't find leading '{' in name\n", p_Name));
666
l_Return = NDIS_STATUS_RESOURCES;
537
672
//==================================
538
673
// Allocate pool for TAP device name
539
674
//==================================
541
if ((p_Adapter->m_TapName = l_TapString.Buffer =
542
ExAllocatePoolWithTag (NonPagedPool,
543
l_TapString.MaximumLength,
676
if ((p_Extension->m_TapName = l_TapString.Buffer =
677
MemAlloc (NAME_BUFFER_SIZE, TRUE)) == NULL)
546
DEBUGP (("[%s] couldn't alloc TAP name buffer\n", p_Adapter->m_Name));
679
DEBUGP (("[%s] couldn't alloc TAP name buffer\n", p_Name));
547
680
l_Return = NDIS_STATUS_RESOURCES;
553
686
//================================================
555
688
if ((l_LinkString.Buffer =
556
ExAllocatePoolWithTag (NonPagedPool,
557
l_LinkString.MaximumLength,
689
MemAlloc (NAME_BUFFER_SIZE, TRUE)) == NULL)
560
691
DEBUGP (("[%s] couldn't alloc TAP symbolic link name buffer\n",
562
l_Return = NDIS_STATUS_RESOURCES;
566
//=======================================================
567
// Modify for tap device name ("\Device\TAPn.tap")
568
//=======================================================
569
NdisMoveMemory (l_TapString.Buffer, p_Adapter->m_Name, l_AdapterLength);
570
NdisMoveMemory (l_TapString.Buffer + l_AdapterLength, TAPSUFFIX,
571
strlen (TAPSUFFIX) + 1);
572
NdisMoveMemory (l_TapString.Buffer, "\\Device", 7); // For Win2K problem
573
l_TapString.Length = l_AdapterLength + strlen (TAPSUFFIX);
693
l_Return = NDIS_STATUS_RESOURCES;
697
//=======================================================
698
// Set TAP device name
699
//=======================================================
701
l_Status = RtlStringCchPrintfExA
703
l_TapString.MaximumLength,
706
STRSAFE_FILL_BEHIND_NULL | STRSAFE_IGNORE_NULLS,
712
if (l_Status != STATUS_SUCCESS)
714
DEBUGP (("[%s] couldn't format TAP device name\n",
716
l_Return = NDIS_STATUS_RESOURCES;
719
l_TapString.Length = (USHORT) strlen (l_TapString.Buffer);
575
721
DEBUGP (("TAP DEV NAME: '%s'\n", l_TapString.Buffer));
577
723
//=======================================================
578
// And modify for tap link name ("\??\TAPn.tap")
579
725
//=======================================================
580
NdisMoveMemory (l_LinkString.Buffer, l_TapString.Buffer,
582
NdisMoveMemory (l_LinkString.Buffer, USERDEVICEDIR, strlen (USERDEVICEDIR));
585
(l_LinkString.Buffer + strlen (USERDEVICEDIR),
586
l_LinkString.Buffer + strlen (SYSDEVICEDIR),
587
l_TapString.Length - strlen (SYSDEVICEDIR));
589
l_LinkString.Buffer[l_LinkString.Length =
590
l_TapString.Length - (strlen (SYSDEVICEDIR) -
591
strlen (USERDEVICEDIR))] = 0;
727
l_Status = RtlStringCchPrintfExA
728
(l_LinkString.Buffer,
729
l_LinkString.MaximumLength,
732
STRSAFE_FILL_BEHIND_NULL | STRSAFE_IGNORE_NULLS,
738
if (l_Status != STATUS_SUCCESS)
740
DEBUGP (("[%s] couldn't format TAP device symbolic link\n",
742
l_Return = NDIS_STATUS_RESOURCES;
745
l_LinkString.Length = (USHORT) strlen (l_LinkString.Buffer);
593
747
DEBUGP (("TAP LINK NAME: '%s'\n", l_LinkString.Buffer));
595
749
//==================================================
596
// Create new tap device and associate with adapter
750
// Convert strings to unicode
597
751
//==================================================
598
752
if (RtlAnsiStringToUnicodeString (&l_TapUnicode, &l_TapString, TRUE) !=
601
755
DEBUGP (("[%s] couldn't alloc TAP unicode name buffer\n",
603
757
l_Return = NDIS_STATUS_RESOURCES;
606
760
l_FreeTapUnicode = TRUE;
608
l_Status = IoCreateDevice
610
sizeof (TapExtension),
612
FILE_DEVICE_PHYSICAL_NETCARD | 0x8000,
613
0, FALSE, &(p_Adapter->m_TapDevice));
615
if (l_Status != STATUS_SUCCESS)
617
DEBUGP (("[%s] couldn't be created\n", p_Adapter->m_TapName));
618
l_Return = NDIS_STATUS_RESOURCES;
622
762
if (RtlAnsiStringToUnicodeString
623
(&p_Adapter->m_UnicodeLinkName, &l_LinkString, TRUE)
763
(&p_Extension->m_UnicodeLinkName, &l_LinkString, TRUE)
624
764
!= STATUS_SUCCESS)
627
767
(("[%s] Couldn't allocate unicode string for symbolic link name\n",
629
769
l_Return = NDIS_STATUS_RESOURCES;
632
p_Adapter->m_CreatedUnicodeLinkName = TRUE;
634
//==================================================
635
// Associate symbolic link with new device
636
//==================================================
638
(IoCreateSymbolicLink (&p_Adapter->m_UnicodeLinkName, &l_TapUnicode)))
772
p_Extension->m_CreatedUnicodeLinkName = TRUE;
774
//==================================================
775
// Create new TAP device with symbolic
776
// link and associate with adapter.
777
//==================================================
779
l_Status = NdisMRegisterDevice
780
(g_NdisWrapperHandle,
782
&p_Extension->m_UnicodeLinkName,
784
&p_Extension->m_TapDevice,
785
&p_Extension->m_TapDeviceHandle
788
if (l_Status != STATUS_SUCCESS)
640
DEBUGP (("[%s] symbolic link couldn't be created\n",
641
l_LinkString.Buffer));
790
DEBUGP (("[%s] couldn't be created\n", p_Name));
642
791
l_Return = NDIS_STATUS_RESOURCES;
645
p_Adapter->m_CreatedSymbolLink = TRUE;
647
//==================================================
648
// Initialize device extension (basically a kind
649
// of private data area containing our state info).
650
//==================================================
653
((TapExtensionPointer) p_Adapter->m_TapDevice->DeviceExtension);
655
NdisZeroMemory (l_Extension, sizeof (TapExtension));
657
p_Adapter->m_DeviceExtensionIsAccessible = TRUE;
659
l_Extension->m_Adapter = p_Adapter;
660
l_Extension->m_halt = FALSE;
795
/* Set TAP device flags */
796
p_Extension->m_TapDevice->Flags |= DO_DIRECT_IO;
662
798
//========================================================
663
799
// Initialize Packet and IRP queues.
694
836
// Finalize initialization
695
837
//========================
697
p_Adapter->m_TapIsRunning = TRUE;
699
/* instead of DO_BUFFERED_IO */
700
p_Adapter->m_TapDevice->Flags |= DO_DIRECT_IO;
702
p_Adapter->m_TapDevice->Flags &= ~DO_DEVICE_INITIALIZING;
704
DEBUGP (("[%s] successfully created TAP device [%s]\n", p_Adapter->m_Name,
705
p_Adapter->m_TapName));
839
p_Extension->m_TapIsRunning = TRUE;
841
DEBUGP (("[%s] successfully created TAP device [%s]\n", p_Name,
842
p_Extension->m_TapName));
708
845
if (l_FreeTapUnicode)
709
846
RtlFreeUnicodeString (&l_TapUnicode);
710
847
if (l_LinkString.Buffer)
711
ExFreePool (l_LinkString.Buffer);
848
MemFree (l_LinkString.Buffer, NAME_BUFFER_SIZE);
850
MemFree (l_Dispatch, SIZEOF_DISPATCH);
713
852
if (l_Return != NDIS_STATUS_SUCCESS)
714
TapDeviceFreeResources (p_Adapter);
853
TapDeviceFreeResources (p_Extension);
720
DestroyTapDevice (TapAdapterPointer p_Adapter)
722
TapExtensionPointer l_Extension =
723
(TapExtensionPointer) p_Adapter->m_TapDevice->DeviceExtension;
725
DEBUGP (("[%s] Destroying tap device\n", p_Adapter->m_TapName));
727
//======================================
728
// Let clients know we are shutting down
729
//======================================
730
p_Adapter->m_TapIsRunning = FALSE;
731
p_Adapter->m_TapOpens = 0;
732
l_Extension->m_halt = TRUE;
734
//====================================
735
// Give clients time to finish up.
736
// Note that we must be running at IRQL
737
// < DISPATCH_LEVEL in order to call
739
//====================================
742
//================================
743
// Exhaust IRP and packet queues
744
//================================
745
FlushQueues (p_Adapter);
747
TapDeviceFreeResources (p_Adapter);
751
TapDeviceFreeResources (TapAdapterPointer p_Adapter)
753
MYASSERT (p_Adapter);
754
MYASSERT (!p_Adapter->m_CalledTapDeviceFreeResources);
755
p_Adapter->m_CalledTapDeviceFreeResources = TRUE;
757
if (p_Adapter->m_DeviceExtensionIsAccessible)
759
TapExtensionPointer l_Extension;
761
MYASSERT (p_Adapter->m_TapDevice);
762
l_Extension = (TapExtensionPointer)
763
p_Adapter->m_TapDevice->DeviceExtension;
764
MYASSERT (l_Extension);
766
if (l_Extension->m_PacketQueue)
767
QueueFree (l_Extension->m_PacketQueue);
768
if (l_Extension->m_IrpQueue)
769
QueueFree (l_Extension->m_IrpQueue);
771
p_Adapter->m_DeviceExtensionIsAccessible = FALSE;
774
if (p_Adapter->m_CreatedSymbolLink)
775
IoDeleteSymbolicLink (&p_Adapter->m_UnicodeLinkName);
777
if (p_Adapter->m_CreatedUnicodeLinkName)
778
RtlFreeUnicodeString (&p_Adapter->m_UnicodeLinkName);
780
//==========================================================
781
// According to DDK docs, the device is not actually deleted
782
// until its reference count falls to zero. That means we
783
// still need to gracefully fail TapDeviceHook requests
784
// after this point, otherwise ugly things would happen if
785
// the device was disabled (e.g. in the network connections
786
// control panel) while a userspace app still held an open
787
// file handle to it.
788
//==========================================================
790
if (p_Adapter->m_TapDevice)
792
IoDeleteDevice (p_Adapter->m_TapDevice);
793
p_Adapter->m_TapDevice = NULL;
796
if (p_Adapter->m_TapName)
798
ExFreePool (p_Adapter->m_TapName);
799
p_Adapter->m_TapName = NULL;
857
#undef SIZEOF_DISPATCH
803
859
//========================================================
804
860
// Adapter Control
1064
1122
NdisMoveMemory (p_Buffer, (PVOID) l_QueryPtr,
1065
1123
(*p_BytesWritten = l_QueryLength));
1067
NdisReleaseSpinLock (&l_Adapter->m_Lock);
1069
1125
return l_Status;
1072
1128
NDIS_STATUS AdapterModify
1073
(IN NDIS_HANDLE p_AdapterContext,
1076
IN ULONG p_BufferLength,
1077
OUT PULONG p_BytesRead,
1078
OUT PULONG p_BytesNeeded)
1129
(IN NDIS_HANDLE p_AdapterContext,
1132
IN ULONG p_BufferLength,
1133
OUT PULONG p_BytesRead,
1134
OUT PULONG p_BytesNeeded)
1080
1136
TapAdapterQueryPointer l_Query = (TapAdapterQueryPointer) p_Buffer;
1081
1137
TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext;
1082
1138
NDIS_STATUS l_Status = NDIS_STATUS_INVALID_OID;
1085
NdisAcquireSpinLock (&l_Adapter->m_Lock);
1089
1143
//==================================================================
1091
1145
//==================================================================
1092
1146
case OID_802_3_MULTICAST_LIST:
1093
DEBUGP (("[%s] Setting [OID_802_3_MAXIMUM_LIST_SIZE]\n",
1094
l_Adapter->m_Name));
1095
l_Status = NDIS_STATUS_SUCCESS;
1147
DEBUGP (("[%s] Setting [OID_802_3_MULTICAST_LIST]\n",
1150
*p_BytesNeeded = sizeof (ETH_ADDR);
1151
*p_BytesRead = p_BufferLength;
1153
if (p_BufferLength % sizeof (ETH_ADDR))
1154
l_Status = NDIS_STATUS_INVALID_LENGTH;
1155
else if (p_BufferLength > sizeof (MC_LIST))
1157
l_Status = NDIS_STATUS_MULTICAST_FULL;
1158
*p_BytesNeeded = sizeof (MC_LIST);
1162
NdisAcquireSpinLock (&l_Adapter->m_MCLock);
1164
NdisZeroMemory(&l_Adapter->m_MCList, sizeof (MC_LIST));
1166
NdisMoveMemory(&l_Adapter->m_MCList,
1170
l_Adapter->m_MCListSize = p_BufferLength / sizeof (ETH_ADDR);
1172
NdisReleaseSpinLock (&l_Adapter->m_MCLock);
1174
l_Status = NDIS_STATUS_SUCCESS;
1098
1178
case OID_GEN_CURRENT_PACKET_FILTER:
1466
1531
NdisFreeMemory (l_PacketBuffer,
1467
1532
TAP_PACKET_SIZE (l_PacketLength),
1469
1536
return NDIS_STATUS_SUCCESS;
1539
return NDIS_STATUS_FAILURE;
1542
return NDIS_STATUS_RESOURCES;
1472
1545
//======================================================================
1473
// Hook for catching tap device IRP's.
1474
// Network adapter requests are forwarded on to NDIS
1546
// Hooks for catching TAP device IRP's.
1475
1547
//======================================================================
1477
1550
TapDeviceHook (IN PDEVICE_OBJECT p_DeviceObject, IN PIRP p_IRP)
1552
TapAdapterPointer l_Adapter = LookupAdapterInInstanceList (p_DeviceObject);
1479
1553
PIO_STACK_LOCATION l_IrpSp;
1480
TapExtensionPointer l_Extension;
1481
1554
NTSTATUS l_Status = STATUS_SUCCESS;
1482
TapAdapterPointer l_Adapter;
1484
//=======================================================================
1485
// If it's not the private data device type, call the original handler
1486
//=======================================================================
1487
1557
l_IrpSp = IoGetCurrentIrpStackLocation (p_IRP);
1488
if (p_DeviceObject->DeviceType != (FILE_DEVICE_PHYSICAL_NETCARD | 0x8000))
1490
return (*g_DispatchHook[l_IrpSp->MajorFunction]) (p_DeviceObject,
1494
//=============================================================
1495
// Only TAP device I/O requests get handled below here
1496
//=============================================================
1497
l_Extension = (TapExtensionPointer) p_DeviceObject->DeviceExtension;
1498
l_Adapter = l_Extension->m_Adapter;
1500
1559
p_IRP->IoStatus.Status = STATUS_SUCCESS;
1501
1560
p_IRP->IoStatus.Information = 0;
1503
if (l_Extension->m_halt)
1562
if (!l_Adapter || l_Adapter->m_Extension.m_Halt)
1505
DEBUGP (("TapDeviceHook called when TAP device is halted\n"));
1506
p_IRP->IoStatus.Status = STATUS_NO_SUCH_DEVICE;
1507
IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
1508
return STATUS_NO_SUCH_DEVICE;
1564
DEBUGP (("TapDeviceHook called when TAP device is halted, MajorFunction=%d\n",
1565
(int)l_IrpSp->MajorFunction));
1567
if (l_IrpSp->MajorFunction == IRP_MJ_CLOSE)
1569
IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
1570
return STATUS_SUCCESS;
1574
p_IRP->IoStatus.Status = STATUS_NO_SUCH_DEVICE;
1575
IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
1576
return STATUS_NO_SUCH_DEVICE;
1511
1580
switch (l_IrpSp->MajorFunction)
2049
2069
//--------------------------------------------------------------
2050
2070
case IRP_MJ_CREATE:
2052
if (l_Adapter->m_TapIsRunning
2053
#ifdef DISABLE_DEVICE_SHARING
2054
&& l_Adapter->m_TapOpens < 1
2072
BOOLEAN succeeded = FALSE;
2073
BOOLEAN mutex_succeeded;
2076
(("[%s] [TAP] release [%d.%d] open request (m_TapOpens=%d)\n",
2077
NAME (l_Adapter), TAP_DRIVER_MAJOR_VERSION,
2078
TAP_DRIVER_MINOR_VERSION, l_Adapter->m_Extension.m_TapOpens));
2080
ACQUIRE_MUTEX_ADAPTIVE (&l_Adapter->m_Extension.m_OpenCloseMutex, mutex_succeeded);
2081
if (mutex_succeeded)
2061
(("[%s] [TAP] release [%d.%d] open request (m_TapOpens=%d)\n",
2062
l_Adapter->m_Name, TAP_DRIVER_MAJOR_VERSION,
2063
TAP_DRIVER_MINOR_VERSION, l_Adapter->m_TapOpens));
2065
NdisAcquireSpinLock (&l_Adapter->m_Lock);
2066
++l_Adapter->m_TapOpens;
2067
first_open = (l_Adapter->m_TapOpens == 1);
2069
ResetTapDevState (l_Adapter);
2070
NdisReleaseSpinLock (&l_Adapter->m_Lock);
2072
#ifdef SET_MEDIA_STATUS_ON_OPEN
2074
SetMediaStatus (l_Adapter, TRUE);
2077
INCREMENT_STAT (l_Adapter->m_NumTapOpens);
2078
p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS;
2079
p_IRP->IoStatus.Information = 0;
2083
if (l_Adapter->m_Extension.m_TapIsRunning && !l_Adapter->m_Extension.m_TapOpens)
2085
ResetTapAdapterState (l_Adapter);
2086
l_Adapter->m_Extension.m_TapOpens = 1;
2092
INCREMENT_STAT (l_Adapter->m_Extension.m_NumTapOpens);
2093
p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS;
2094
p_IRP->IoStatus.Information = 0;
2098
DEBUGP (("[%s] TAP is presently unavailable (m_TapOpens=%d)\n",
2099
NAME (l_Adapter), l_Adapter->m_Extension.m_TapOpens));
2101
p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
2102
p_IRP->IoStatus.Information = 0;
2105
RELEASE_MUTEX (&l_Adapter->m_Extension.m_OpenCloseMutex);
2083
DEBUGP (("[%s] TAP is presently unavailable (m_TapOpens=%d)\n",
2084
l_Adapter->m_Name, l_Adapter->m_TapOpens));
2085
NOTE_ERROR (l_Adapter);
2109
DEBUGP (("[%s] TAP is presently locked (m_TapOpens=%d)\n",
2110
NAME (l_Adapter), l_Adapter->m_Extension.m_TapOpens));
2086
2112
p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
2087
2113
p_IRP->IoStatus.Information = 0;
2096
2122
//-----------------------------------------------------------
2097
2123
case IRP_MJ_CLOSE:
2099
BOOLEAN fully_closed = FALSE;
2101
DEBUGP (("[%s] [TAP] release [%d.%d] close request\n",
2102
l_Adapter->m_Name, TAP_DRIVER_MAJOR_VERSION,
2103
TAP_DRIVER_MINOR_VERSION));
2105
NdisAcquireSpinLock (&l_Adapter->m_Lock);
2106
if (l_Adapter->m_TapOpens)
2108
--l_Adapter->m_TapOpens;
2109
if (l_Adapter->m_TapOpens == 0)
2111
fully_closed = TRUE;
2112
ResetTapDevState (l_Adapter);
2115
NdisReleaseSpinLock (&l_Adapter->m_Lock);
2119
FlushQueues (l_Adapter);
2125
BOOLEAN mutex_succeeded;
2127
DEBUGP (("[%s] [TAP] release [%d.%d] close/cleanup request\n",
2128
NAME (l_Adapter), TAP_DRIVER_MAJOR_VERSION,
2129
TAP_DRIVER_MINOR_VERSION));
2131
ACQUIRE_MUTEX_ADAPTIVE (&l_Adapter->m_Extension.m_OpenCloseMutex, mutex_succeeded);
2132
if (mutex_succeeded)
2134
l_Adapter->m_Extension.m_TapOpens = 0;
2135
ResetTapAdapterState (l_Adapter);
2136
FlushQueues (&l_Adapter->m_Extension);
2120
2137
SetMediaStatus (l_Adapter, FALSE);
2138
RELEASE_MUTEX (&l_Adapter->m_Extension.m_OpenCloseMutex);
2142
DEBUGP (("[%s] TAP is presently locked (m_TapOpens=%d)\n",
2143
NAME (l_Adapter), l_Adapter->m_Extension.m_TapOpens));
2145
p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
2146
p_IRP->IoStatus.Information = 0;
2123
2149
IoCompleteRequest (p_IRP, IO_NO_INCREMENT);