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

📄 instance.c

📁 OpenVPN is a robust and highly flexible tunneling application that uses all of the encryption, authe
💻 C
字号:
/* *  TAP-Win32 -- A kernel driver to provide virtual tap device *               functionality on Windows.  Originally derived *               from the CIPE-Win32 project by Damion K. Wilson, *               with extensive modifications by James Yonan. * *  All source code which derives from the CIPE-Win32 project is *  Copyright (C) Damion K. Wilson, 2003, and is released under the *  GPL version 2 (see below). * *  All other source code is Copyright (C) James Yonan, 2003-2004, *  and is released under the GPL version 2 (see below). * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program (see the file COPYING included with this *  distribution); if not, write to the Free Software Foundation, Inc., *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#define INSTANCE_KEY(a) ((PVOID)((a)->m_Extension.m_TapDevice))#define N_INSTANCE_BUCKETS 256typedef struct _INSTANCE {  struct _INSTANCE *next;  TapAdapterPointer m_Adapter;} INSTANCE;typedef struct {  INSTANCE *list;  MUTEX lock;} INSTANCE_BUCKET;typedef struct {  INSTANCE_BUCKET buckets[N_INSTANCE_BUCKETS];} INSTANCE_HASH;INSTANCE_HASH *g_InstanceHash = NULL;// must return a hash >= 0 and < N_INSTANCE_BUCKETSintInstanceHashValue (PVOID addr){  UCHAR *p = (UCHAR *) &addr;  if (sizeof (addr) == 4)    return p[0] ^ p[1] ^ p[2] ^ p[3];  else if (sizeof (addr) == 8)    return p[0] ^ p[1] ^ p[2] ^ p[3] ^ p[4] ^ p[5] ^ p[6] ^ p[7];  else    {      MYASSERT (0);    }}BOOLEANInitInstanceList (VOID){  MYASSERT (g_InstanceHash == NULL);  g_InstanceHash = MemAlloc (sizeof (INSTANCE_HASH), TRUE);  if (g_InstanceHash)    {      int i;      for (i = 0; i < N_INSTANCE_BUCKETS; ++i)	INIT_MUTEX (&g_InstanceHash->buckets[i].lock);      return TRUE;    }  else    return FALSE;}intNInstances (VOID){  int i, n = 0;  if (g_InstanceHash)    {      for (i = 0; i < N_INSTANCE_BUCKETS; ++i)	{	  BOOLEAN got_lock;	  INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[i];	  ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock);	  if (got_lock)	    {	      INSTANCE *current;	      for (current = ib->list; current != NULL; current = current->next)		++n;	      RELEASE_MUTEX (&ib->lock);	    }	  else	    return -1;	}    }  return n;}intInstanceMaxBucketSize (VOID){  int i, n = 0;  if (g_InstanceHash)    {      for (i = 0; i < N_INSTANCE_BUCKETS; ++i)	{	  BOOLEAN got_lock;	  int bucket_size = 0;	  INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[i];	  ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock);	  if (got_lock)	    {	      INSTANCE *current;	      for (current = ib->list; current != NULL; current = current->next)		  ++bucket_size;	      if (bucket_size > n)		n = bucket_size;	      RELEASE_MUTEX (&ib->lock);	    }	  else	    return -1;	}    }  return n;}VOIDFreeInstanceList (VOID){  if (g_InstanceHash)    {      MYASSERT (NInstances() == 0);      MemFree (g_InstanceHash, sizeof (INSTANCE_HASH));      g_InstanceHash = NULL;    }}BOOLEANAddAdapterToInstanceList (TapAdapterPointer p_Adapter){  BOOLEAN got_lock;  BOOLEAN ret = FALSE;  const int hash = InstanceHashValue(INSTANCE_KEY(p_Adapter));  INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[hash];  DEBUGP (("[TAP] AddAdapterToInstanceList hash=%d\n", hash));  ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock);  if (got_lock)    {      INSTANCE *i = MemAlloc (sizeof (INSTANCE), FALSE);      if (i)	{	  MYASSERT (p_Adapter);	  i->m_Adapter = p_Adapter;	  i->next = ib->list;	  ib->list = i;	  ret = TRUE;	}      RELEASE_MUTEX (&ib->lock);    }  return ret;}BOOLEANRemoveAdapterFromInstanceList (TapAdapterPointer p_Adapter){  BOOLEAN got_lock;  BOOLEAN ret = FALSE;  INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[InstanceHashValue(INSTANCE_KEY(p_Adapter))];  ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock);  if (got_lock)    {      INSTANCE *current, *prev=NULL;      for (current = ib->list; current != NULL; current = current->next)	{	  if (current->m_Adapter == p_Adapter) // found match	    {	      if (prev)		prev->next = current->next;	      else		ib->list = current->next;	      MemFree (current->m_Adapter, sizeof (TapAdapter));	      MemFree (current, sizeof (INSTANCE));	      ret = TRUE;	      break;	    }	  prev = current;	}      RELEASE_MUTEX (&ib->lock);    }  return ret;}TapAdapterPointerLookupAdapterInInstanceList (PDEVICE_OBJECT p_DeviceObject){  BOOLEAN got_lock;  TapAdapterPointer ret = NULL;  INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[InstanceHashValue((PVOID)p_DeviceObject)];  ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock);  if (got_lock)    {      INSTANCE *current, *prev=NULL;      for (current = ib->list; current != NULL; current = current->next)	{	  if (p_DeviceObject == INSTANCE_KEY (current->m_Adapter)) // found match	    {	      // move it to head of list	      if (prev)		{		  prev->next = current->next;		  current->next = ib->list;		  ib->list = current;		}	      ret = ib->list->m_Adapter;	      break;	    }	  prev = current;	}      RELEASE_MUTEX (&ib->lock);    }  return ret;}

⌨️ 快捷键说明

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