diff options
author | Alberto Gonzalez Iniesta <agi@inittab.org> | 2012-02-21 15:53:40 +0100 |
---|---|---|
committer | Alberto Gonzalez Iniesta <agi@inittab.org> | 2012-02-21 15:53:40 +0100 |
commit | 349cfa7acb95abe865209a28e417ec74b56f9bba (patch) | |
tree | ad65334821b587c4ecdd461be84c94305ffdb888 /tap-win32/mem.c |
Imported Upstream version 2.2.1upstream/2.2.1
Diffstat (limited to 'tap-win32/mem.c')
-rwxr-xr-x | tap-win32/mem.c | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/tap-win32/mem.c b/tap-win32/mem.c new file mode 100755 index 0000000..6fbbed5 --- /dev/null +++ b/tap-win32/mem.c @@ -0,0 +1,186 @@ +/* + * TAP-Win32/TAP-Win64 -- A kernel driver to provide virtual tap + * device functionality on Windows. + * + * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. + * + * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., + * 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 version 2 + * as published by the Free Software Foundation. + * + * 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 + */ + +//------------------ +// Memory Management +//------------------ + +PVOID +MemAlloc (ULONG p_Size, BOOLEAN zero) +{ + PVOID l_Return = NULL; + + if (p_Size) + { + __try + { + if (NdisAllocateMemoryWithTag (&l_Return, p_Size, 'APAT') + == NDIS_STATUS_SUCCESS) + { + if (zero) + NdisZeroMemory (l_Return, p_Size); + } + else + l_Return = NULL; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + l_Return = NULL; + } + } + + return l_Return; +} + +VOID +MemFree (PVOID p_Addr, ULONG p_Size) +{ + if (p_Addr && p_Size) + { + __try + { +#if DBG + NdisZeroMemory (p_Addr, p_Size); +#endif + NdisFreeMemory (p_Addr, p_Size, 0); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + } + } +} + +/* + * Circular queue management routines. + */ + +#define QUEUE_BYTE_ALLOCATION(size) \ + (sizeof (Queue) + (size * sizeof (PVOID))) + +#define QUEUE_ADD_INDEX(var, inc) \ +{ \ + var += inc; \ + if (var >= q->capacity) \ + var -= q->capacity; \ + MYASSERT (var < q->capacity); \ +} + +#define QUEUE_SANITY_CHECK() \ + MYASSERT (q != NULL && q->base < q->capacity && q->size <= q->capacity) + +#define QueueCount(q) (q->size) + +#define UPDATE_MAX_SIZE() \ +{ \ + if (q->size > q->max_size) \ + q->max_size = q->size; \ +} + +Queue * +QueueInit (ULONG capacity) +{ + Queue *q; + + MYASSERT (capacity > 0); + q = (Queue *) MemAlloc (QUEUE_BYTE_ALLOCATION (capacity), TRUE); + if (!q) + return NULL; + + q->base = q->size = 0; + q->capacity = capacity; + q->max_size = 0; + return q; +} + +VOID +QueueFree (Queue *q) +{ + if (q) + { + QUEUE_SANITY_CHECK (); + MemFree (q, QUEUE_BYTE_ALLOCATION (q->capacity)); + } +} + +PVOID +QueuePush (Queue *q, PVOID item) +{ + ULONG dest; + QUEUE_SANITY_CHECK (); + if (q->size == q->capacity) + return NULL; + dest = q->base; + QUEUE_ADD_INDEX (dest, q->size); + q->data[dest] = item; + ++q->size; + UPDATE_MAX_SIZE(); + return item; +} + +PVOID +QueuePop (Queue *q) +{ + ULONG oldbase; + QUEUE_SANITY_CHECK (); + if (!q->size) + return NULL; + oldbase = q->base; + QUEUE_ADD_INDEX (q->base, 1); + --q->size; + UPDATE_MAX_SIZE(); + return q->data[oldbase]; +} + +PVOID +QueueExtract (Queue *q, PVOID item) +{ + ULONG src, dest, count, n; + QUEUE_SANITY_CHECK (); + n = 0; + src = dest = q->base; + count = q->size; + while (count--) + { + if (item == q->data[src]) + { + ++n; + --q->size; + } + else + { + q->data[dest] = q->data[src]; + QUEUE_ADD_INDEX (dest, 1); + } + QUEUE_ADD_INDEX (src, 1); + } + if (n) + return item; + else + return NULL; +} + +#undef QUEUE_BYTE_ALLOCATION +#undef QUEUE_ADD_INDEX +#undef QUEUE_SANITY_CHECK +#undef UPDATE_MAX_SIZE |