svn cleanup
[anytun.git] / openvpn / tap-win32 / mem.c
blob5df720628f706cb044bc7c9ce7b15d193dd7a01b
1 /*
2 * TAP-Win32 -- A kernel driver to provide virtual tap device functionality
3 * on Windows. Originally derived from the CIPE-Win32
4 * project by Damion K. Wilson, with extensive modifications by
5 * James Yonan.
7 * All source code which derives from the CIPE-Win32 project is
8 * Copyright (C) Damion K. Wilson, 2003, and is released under the
9 * GPL version 2 (see below).
11 * All other source code is Copyright (C) 2002-2005 OpenVPN Solutions LLC,
12 * and is released under the GPL version 2 (see below).
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2
16 * as published by the Free Software Foundation.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program (see the file COPYING included with this
25 * distribution); if not, write to the Free Software Foundation, Inc.,
26 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 //------------------
30 // Memory Management
31 //------------------
33 PVOID
34 MemAlloc (ULONG p_Size, BOOLEAN zero)
36 PVOID l_Return = NULL;
38 if (p_Size)
40 __try
42 if (NdisAllocateMemoryWithTag (&l_Return, p_Size, 'APAT')
43 == NDIS_STATUS_SUCCESS)
45 if (zero)
46 NdisZeroMemory (l_Return, p_Size);
48 else
49 l_Return = NULL;
51 __except (EXCEPTION_EXECUTE_HANDLER)
53 l_Return = NULL;
57 return l_Return;
60 VOID
61 MemFree (PVOID p_Addr, ULONG p_Size)
63 if (p_Addr && p_Size)
65 __try
67 #if DBG
68 NdisZeroMemory (p_Addr, p_Size);
69 #endif
70 NdisFreeMemory (p_Addr, p_Size, 0);
72 __except (EXCEPTION_EXECUTE_HANDLER)
79 * Circular queue management routines.
82 #define QUEUE_BYTE_ALLOCATION(size) \
83 (sizeof (Queue) + (size * sizeof (PVOID)))
85 #define QUEUE_ADD_INDEX(var, inc) \
86 { \
87 var += inc; \
88 if (var >= q->capacity) \
89 var -= q->capacity; \
90 MYASSERT (var < q->capacity); \
93 #define QUEUE_SANITY_CHECK() \
94 MYASSERT (q != NULL && q->base < q->capacity && q->size <= q->capacity)
96 #define QueueCount(q) (q->size)
98 #define UPDATE_MAX_SIZE() \
99 { \
100 if (q->size > q->max_size) \
101 q->max_size = q->size; \
104 Queue *
105 QueueInit (ULONG capacity)
107 Queue *q;
109 MYASSERT (capacity > 0);
110 q = (Queue *) MemAlloc (QUEUE_BYTE_ALLOCATION (capacity), TRUE);
111 if (!q)
112 return NULL;
114 q->base = q->size = 0;
115 q->capacity = capacity;
116 q->max_size = 0;
117 return q;
120 VOID
121 QueueFree (Queue *q)
123 if (q)
125 QUEUE_SANITY_CHECK ();
126 MemFree (q, QUEUE_BYTE_ALLOCATION (q->capacity));
130 PVOID
131 QueuePush (Queue *q, PVOID item)
133 ULONG dest;
134 QUEUE_SANITY_CHECK ();
135 if (q->size == q->capacity)
136 return NULL;
137 dest = q->base;
138 QUEUE_ADD_INDEX (dest, q->size);
139 q->data[dest] = item;
140 ++q->size;
141 UPDATE_MAX_SIZE();
142 return item;
145 PVOID
146 QueuePop (Queue *q)
148 ULONG oldbase;
149 QUEUE_SANITY_CHECK ();
150 if (!q->size)
151 return NULL;
152 oldbase = q->base;
153 QUEUE_ADD_INDEX (q->base, 1);
154 --q->size;
155 UPDATE_MAX_SIZE();
156 return q->data[oldbase];
159 PVOID
160 QueueExtract (Queue *q, PVOID item)
162 ULONG src, dest, count, n;
163 QUEUE_SANITY_CHECK ();
164 n = 0;
165 src = dest = q->base;
166 count = q->size;
167 while (count--)
169 if (item == q->data[src])
171 ++n;
172 --q->size;
174 else
176 q->data[dest] = q->data[src];
177 QUEUE_ADD_INDEX (dest, 1);
179 QUEUE_ADD_INDEX (src, 1);
181 if (n)
182 return item;
183 else
184 return NULL;
187 #undef QUEUE_BYTE_ALLOCATION
188 #undef QUEUE_ADD_INDEX
189 #undef QUEUE_SANITY_CHECK
190 #undef UPDATE_MAX_SIZE