⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tapdrvr.c

📁 一个Windows下的Linux专用虚拟机
💻 C
📖 第 1 页 / 共 5 页
字号:
		{		  int mtu = parm->ParameterData.IntegerData;		  if (mtu < MINIMUM_MTU)		    mtu = MINIMUM_MTU;		  if (mtu > MAXIMUM_MTU)		    mtu = MAXIMUM_MTU;		  l_Adapter->m_MTU = mtu;		}	    }	}	/* Read Media Status setting from registry */	{	  NDIS_STRING key = NDIS_STRING_CONST("MediaStatus");	  NdisReadConfiguration (&status, &parm, configHandle,				 &key, NdisParameterInteger);	  if (status == NDIS_STATUS_SUCCESS)	    {	      if (parm->ParameterType == NdisParameterInteger)		{		  if (parm->ParameterData.IntegerData)		    {		      l_Adapter->m_MediaStateAlwaysConnected = TRUE;		      l_Adapter->m_MediaState = TRUE;		    }		}	    }	}#if ENABLE_NONADMIN	/* Read AllowNonAdmin setting from registry */	{	  NDIS_STRING key = NDIS_STRING_CONST("AllowNonAdmin");	  NdisReadConfiguration (&status, &parm, configHandle,				 &key, NdisParameterInteger);	  if (status == NDIS_STATUS_SUCCESS)	    {	      if (parm->ParameterType == NdisParameterInteger)		{		  if (parm->ParameterData.IntegerData)		    {			enable_non_admin = TRUE;		    }		}	    }	}#endif	/* Read optional MAC setting from registry */	{	  NDIS_STRING key = NDIS_STRING_CONST("MAC");	  ANSI_STRING mac_string;	  NdisReadConfiguration (&status, &parm, configHandle,				 &key, NdisParameterString);	  if (status == NDIS_STATUS_SUCCESS)	    {	      if (parm->ParameterType == NdisParameterString)		{		  if (RtlUnicodeStringToAnsiString (&mac_string, &parm->ParameterData.StringData, TRUE) == STATUS_SUCCESS)		    {		      l_MacFromRegistry = ParseMAC (l_Adapter->m_MAC, mac_string.Buffer);		      RtlFreeAnsiString (&mac_string);		    }		}	    }	}	NdisCloseConfiguration (configHandle);    DEBUGP (("[%s] MTU=%d\n", NAME (l_Adapter), l_Adapter->m_MTU));  }  //==================================  // Store and update MAC address info  //==================================  if (!l_MacFromRegistry)    GenerateRandomMac (l_Adapter->m_MAC, NAME (l_Adapter));  DEBUGP (("[%s] Using MAC %x:%x:%x:%x:%x:%x\n",	    NAME (l_Adapter),	    l_Adapter->m_MAC[0], l_Adapter->m_MAC[1], l_Adapter->m_MAC[2],	    l_Adapter->m_MAC[3], l_Adapter->m_MAC[4], l_Adapter->m_MAC[5]));  //==================  // Set broadcast MAC  //==================  {    int i;    for (i = 0; i < sizeof (MACADDR); ++i)      l_Adapter->m_MAC_Broadcast[i] = 0xFF;  }  //====================================  // Initialize TAP device  //====================================  {    NDIS_STATUS tap_status;    tap_status = CreateTapDevice (&l_Adapter->m_Extension, NAME (l_Adapter));    if (tap_status != NDIS_STATUS_SUCCESS)      {	AdapterFreeResources (l_Adapter);	return tap_status;      }  }  if (!AddAdapterToInstanceList (l_Adapter))    {      NOTE_ERROR ();      TapDeviceFreeResources (&l_Adapter->m_Extension);      AdapterFreeResources (l_Adapter);      return NDIS_STATUS_RESOURCES;    }  l_Adapter->m_InterfaceIsRunning = TRUE;#if ENABLE_NONADMIN  if (enable_non_admin)    AllowNonAdmin (&l_Adapter->m_Extension);#endif  return NDIS_STATUS_SUCCESS;}VOIDAdapterHalt (IN NDIS_HANDLE p_AdapterContext){  BOOLEAN status;  TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext;  NOTE_ERROR ();  l_Adapter->m_InterfaceIsRunning = FALSE;  DEBUGP (("[%s] is being halted\n", NAME (l_Adapter)));    DestroyTapDevice (&l_Adapter->m_Extension);  // Free resources  DEBUGP (("[%s] Freeing Resources\n", NAME (l_Adapter)));  AdapterFreeResources (l_Adapter);  status = RemoveAdapterFromInstanceList (l_Adapter);  DEBUGP (("[TAP] RemoveAdapterFromInstanceList returned %d\n", (int) status));  DEBUGP (("[TAP] version [%d.%d] %s %s AdapterHalt returning\n",	   TAP_DRIVER_MAJOR_VERSION,	   TAP_DRIVER_MINOR_VERSION,	   __DATE__,	   __TIME__));}VOIDAdapterFreeResources (TapAdapterPointer p_Adapter){  MYASSERT (!p_Adapter->m_CalledAdapterFreeResources);  p_Adapter->m_CalledAdapterFreeResources = TRUE;  if (p_Adapter->m_NameAnsi.Buffer)    RtlFreeAnsiString (&p_Adapter->m_NameAnsi);    if (p_Adapter->m_RegisteredAdapterShutdownHandler)    NdisMDeregisterAdapterShutdownHandler (p_Adapter->m_MiniportAdapterHandle);  if (p_Adapter->m_MCLockAllocated)    NdisFreeSpinLock (&l_Adapter->m_MCLock);}VOIDDestroyTapDevice (TapExtensionPointer p_Extension){  DEBUGP (("[%s] Destroying tap device\n", p_Extension->m_TapName));  //======================================  // Let clients know we are shutting down  //======================================  p_Extension->m_TapIsRunning = FALSE;  p_Extension->m_TapOpens = 0;  p_Extension->m_Halt = TRUE;  //=====================================  // If we are concurrently executing in  // TapDeviceHook or AdapterTransmit,  // give those calls time to finish.  // Note that we must be running at IRQL  // < DISPATCH_LEVEL in order to call  // NdisMSleep.  //=====================================  NdisMSleep (500000);  //===========================================================  // Exhaust IRP and packet queues.  Any pending IRPs will  // be cancelled, causing user-space to get this error  // on overlapped reads:  //   The I/O operation has been aborted because of either a  //   thread exit or an application request.   (code=995)  // It's important that user-space close the device handle  // when this code is returned, so that when we finally  // do a NdisMDeregisterDevice, the device reference count  // is 0.  Otherwise the driver will not unload even if the  // the last adapter has been halted.  //===========================================================  FlushQueues (p_Extension);  NdisMSleep (500000); // give user space time to respond to IRP cancel  TapDeviceFreeResources (p_Extension);}VOIDTapDeviceFreeResources (TapExtensionPointer p_Extension){  MYASSERT (p_Extension);  MYASSERT (!p_Extension->m_CalledTapDeviceFreeResources);  p_Extension->m_CalledTapDeviceFreeResources = TRUE;  if (p_Extension->m_PacketQueue)    QueueFree (p_Extension->m_PacketQueue);  if (p_Extension->m_IrpQueue)    QueueFree (p_Extension->m_IrpQueue);  if (p_Extension->m_CreatedUnicodeLinkName)    RtlFreeUnicodeString (&p_Extension->m_UnicodeLinkName);  //==========================================================  // According to DDK docs, the device is not actually deleted  // until its reference count falls to zero.  That means we  // still need to gracefully fail TapDeviceHook requests  // after this point, otherwise ugly things would happen if  // the device was disabled (e.g. in the network connections  // control panel) while a userspace app still held an open  // file handle to it.  //==========================================================    if (p_Extension->m_TapDevice)    {      BOOLEAN status;      status = (NdisMDeregisterDevice (p_Extension->m_TapDeviceHandle)		== NDIS_STATUS_SUCCESS);      DEBUGP (("[TAP] Deregistering TAP device, status=%d\n", (int)status));    }  if (p_Extension->m_TapName)    MemFree (p_Extension->m_TapName, NAME_BUFFER_SIZE);    if (p_Extension->m_AllocatedSpinlocks)    NdisFreeSpinLock (&p_Extension->m_QueueLock);}//========================================================================//                             Tap Device Initialization//========================================================================NDIS_STATUSCreateTapDevice (TapExtensionPointer p_Extension, const char *p_Name){# define SIZEOF_DISPATCH (sizeof(PDRIVER_DISPATCH) * (IRP_MJ_MAXIMUM_FUNCTION + 1))  PDRIVER_DISPATCH *l_Dispatch = NULL;  ANSI_STRING l_TapString, l_LinkString;  UNICODE_STRING l_TapUnicode;  BOOLEAN l_FreeTapUnicode = FALSE;  NTSTATUS l_Status, l_Return = NDIS_STATUS_SUCCESS;  const char *l_UsableName;  DEBUGP (("[TAP] version [%d.%d] creating tap device: %s\n",	   TAP_DRIVER_MAJOR_VERSION,	   TAP_DRIVER_MINOR_VERSION,	   p_Name));  NdisZeroMemory (p_Extension, sizeof (TapExtension));  INIT_MUTEX (&p_Extension->m_OpenCloseMutex);  l_LinkString.Buffer = NULL;  l_TapString.Buffer = NULL;  l_TapString.MaximumLength = l_LinkString.MaximumLength = NAME_BUFFER_SIZE;  //=======================================  // Set TAP device entry points  //=======================================  if ((l_Dispatch = MemAlloc (SIZEOF_DISPATCH, TRUE)) == NULL)    {      DEBUGP (("[%s] couldn't alloc TAP dispatch table\n", p_Name));      l_Return = NDIS_STATUS_RESOURCES;      goto cleanup;    }  l_Dispatch[IRP_MJ_DEVICE_CONTROL] = TapDeviceHook;  l_Dispatch[IRP_MJ_READ] = TapDeviceHook;  l_Dispatch[IRP_MJ_WRITE] = TapDeviceHook;  l_Dispatch[IRP_MJ_CREATE] = TapDeviceHook;  l_Dispatch[IRP_MJ_CLOSE] = TapDeviceHook;  //==================================  // Find the beginning of the GUID  //==================================  l_UsableName = p_Name;  while (*l_UsableName != '{')    {      if (*l_UsableName == '\0')	{	  DEBUGP (("[%s] couldn't find leading '{' in name\n", p_Name));	  l_Return = NDIS_STATUS_RESOURCES;	  goto cleanup;	}      ++l_UsableName;    }  //==================================  // Allocate pool for TAP device name  //==================================  if ((p_Extension->m_TapName = l_TapString.Buffer =       MemAlloc (NAME_BUFFER_SIZE, TRUE)) == NULL)    {      DEBUGP (("[%s] couldn't alloc TAP name buffer\n", p_Name));      l_Return = NDIS_STATUS_RESOURCES;      goto cleanup;    }  //================================================  // Allocate pool for TAP symbolic link name buffer  //================================================  if ((l_LinkString.Buffer =       MemAlloc (NAME_BUFFER_SIZE, TRUE)) == NULL)    {      DEBUGP (("[%s] couldn't alloc TAP symbolic link name buffer\n",	       p_Name));      l_Return = NDIS_STATUS_RESOURCES;      goto cleanup;    }  //=======================================================  // Set TAP device name  //=======================================================  l_Status = RtlStringCchPrintfExA    (l_TapString.Buffer,     l_TapString.MaximumLength,     NULL,     NULL,     STRSAFE_FILL_BEHIND_NULL | STRSAFE_IGNORE_NULLS,     "%s%s%s",     SYSDEVICEDIR,     l_UsableName,     TAPSUFFIX);  if (l_Status != STATUS_SUCCESS)    {      DEBUGP (("[%s] couldn't format TAP device name\n",	       p_Name));      l_Return = NDIS_STATUS_RESOURCES;      goto cleanup;    }  l_TapString.Length = (USHORT) strlen (l_TapString.Buffer);  DEBUGP (("TAP DEV NAME: '%s'\n", l_TapString.Buffer));  //=======================================================  // Set TAP link name  //=======================================================  l_Status = RtlStringCchPrintfExA    (l_LinkString.Buffer,     l_LinkString.MaximumLength,     NULL,     NULL,     STRSAFE_FILL_BEHIND_NULL | STRSAFE_IGNORE_NULLS,     "%s%s%s",     USERDEVICEDIR,     l_UsableName,     TAPSUFFIX);  if (l_Status != STATUS_SUCCESS)    {      DEBUGP (("[%s] couldn't format TAP device symbolic link\n",	       p_Name));      l_Return = NDIS_STATUS_RESOURCES;      goto cleanup;    }  l_LinkString.Length = (USHORT) strlen (l_LinkString.Buffer);  DEBUGP (("TAP LINK NAME: '%s'\n", l_LinkString.Buffer));  //==================================================  // Convert strings to unicode  //==================================================  if (RtlAnsiStringToUnicodeString (&l_TapUnicode, &l_TapString, TRUE) !=      STATUS_SUCCESS)    {      DEBUGP (("[%s] couldn't alloc TAP unicode name buffer\n",		p_Name));      l_Return = NDIS_STATUS_RESOURCES;      goto cleanup;    }  l_FreeTapUnicode = TRUE;  if (RtlAnsiStringToUnicodeString      (&p_Extension->m_UnicodeLinkName, &l_LinkString, TRUE)      != STATUS_SUCCESS)    {      DEBUGP	(("[%s] Couldn't allocate unicode string for symbolic link name\n",	 p_Name));      l_Return = NDIS_STATUS_RESOURCES;      goto cleanup;    }  p_Extension->m_CreatedUnicodeLinkName = TRUE;  //==================================================  // Create new TAP device with symbolic  // link and associate with adapter.  //==================================================  l_Status = NdisMRegisterDevice    (g_NdisWrapperHandle,     &l_TapUnicode,     &p_Extension->m_UnicodeLinkName,     l_Dispatch,     &p_Extension->m_TapDevice,     &p_Extension->m_TapDeviceHandle     );  if (l_Status != STATUS_SUCCESS)    {      DEBUGP (("[%s] couldn't be created\n", p_Name));      l_Return = NDIS_STATUS_RESOURCES;      goto cleanup;    }  /* Set TAP device flags */  p_Extension->m_TapDevice->Flags |= DO_DIRECT_IO;  //========================================================  // Initialize Packet and IRP queues.  //  // The packet queue is used to buffer data which has been  // "transmitted" by the virtual NIC, before user space  // has had a chance to read it.  //  // The IRP queue is used to buffer pending I/O requests  // from userspace, i.e. read requests on the TAP device  // waiting for the system to "transmit" something through  // the virtual NIC.  //  // Basically, packets in the packet queue are used

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -