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

📄 tapdrvr.c

📁 OpenVPN is a robust and highly flexible tunneling application that uses all of the encryption, authe
💻 C
📖 第 1 页 / 共 5 页
字号:
    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;  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  // to satisfy IRP requests in the IRP queue.  //  // QueueLock is used to lock the packet queue used  // for the TAP-Win32 NIC -> User Space packet flow direction.  //  // All accesses to packet or IRP queues should be  // bracketed by the QueueLock spinlock,  // in order to be SMP-safe.  //========================================================  NdisAllocateSpinLock (&p_Extension->m_QueueLock);  p_Extension->m_AllocatedSpinlocks = TRUE;  p_Extension->m_PacketQueue = QueueInit (PACKET_QUEUE_SIZE);  p_Extension->m_IrpQueue = QueueInit (IRP_QUEUE_SIZE);  if (!p_Extension->m_PacketQueue      || !p_Extension->m_IrpQueue)    {      DEBUGP (("[%s] couldn't alloc TAP queues\n", p_Name));      l_Return = NDIS_STATUS_RESOURCES;      goto cleanup;    }  //========================  // Finalize initialization  //========================  p_Extension->m_TapIsRunning = TRUE;  DEBUGP (("[%s] successfully created TAP device [%s]\n", p_Name,	    p_Extension->m_TapName)); cleanup:  if (l_FreeTapUnicode)    RtlFreeUnicodeString (&l_TapUnicode);  if (l_LinkString.Buffer)    MemFree (l_LinkString.Buffer, NAME_BUFFER_SIZE);  if (l_Dispatch)    MemFree (l_Dispatch, SIZEOF_DISPATCH);  if (l_Return != NDIS_STATUS_SUCCESS)    TapDeviceFreeResources (p_Extension);  return l_Return;}#undef SIZEOF_DISPATCH//========================================================//                      Adapter Control//========================================================NDIS_STATUSAdapterReset (OUT PBOOLEAN p_AddressingReset, IN NDIS_HANDLE p_AdapterContext){  TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext;  DEBUGP (("[%s] is resetting\n", NAME (l_Adapter)));  return NDIS_STATUS_SUCCESS;}NDIS_STATUS AdapterReceive  (OUT PNDIS_PACKET p_Packet,   OUT PUINT p_Transferred,   IN NDIS_HANDLE p_AdapterContext,   IN NDIS_HANDLE p_ReceiveContext,   IN UINT p_Offset,   IN UINT p_ToTransfer){  return NDIS_STATUS_SUCCESS;}//==============================================================//                  Adapter Option Query/Modification//==============================================================NDIS_STATUS AdapterQuery(IN NDIS_HANDLE p_AdapterContext, IN NDIS_OID p_OID, IN PVOID p_Buffer, IN ULONG p_BufferLength, OUT PULONG p_BytesWritten, OUT PULONG p_BytesNeeded){  TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext;  TapAdapterQuery l_Query, *l_QueryPtr = &l_Query;  NDIS_STATUS l_Status = NDIS_STATUS_SUCCESS;  UINT l_QueryLength = 4;  BOOLEAN lock_succeeded;  NdisZeroMemory (&l_Query, sizeof (l_Query));  switch (p_OID)    {      //===================================================================      //                       Vendor & Driver version Info      //===================================================================    case OID_GEN_VENDOR_DESCRIPTION:      l_QueryPtr = (TapAdapterQueryPointer) PRODUCT_STRING;      l_QueryLength = strlen (PRODUCT_STRING) + 1;      break;

⌨️ 快捷键说明

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