2 * TAP-Win32/TAP-Win64 -- A kernel driver to provide virtual tap
3 * device functionality on Windows.
5 * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson.
7 * This source code is Copyright (C) 2002-2009 OpenVPN Technologies, Inc.,
8 * and is released under the GPL version 2 (see below).
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program (see the file COPYING included with this
21 * distribution); if not, write to the Free Software Foundation, Inc.,
22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 MemAlloc (ULONG p_Size
, BOOLEAN zero
)
32 PVOID l_Return
= NULL
;
38 if (NdisAllocateMemoryWithTag (&l_Return
, p_Size
, 'APAT')
39 == NDIS_STATUS_SUCCESS
)
42 NdisZeroMemory (l_Return
, p_Size
);
47 __except (EXCEPTION_EXECUTE_HANDLER
)
57 MemFree (PVOID p_Addr
, ULONG p_Size
)
64 NdisZeroMemory (p_Addr
, p_Size
);
66 NdisFreeMemory (p_Addr
, p_Size
, 0);
68 __except (EXCEPTION_EXECUTE_HANDLER
)
75 * Circular queue management routines.
78 #define QUEUE_BYTE_ALLOCATION(size) \
79 (sizeof (Queue) + (size * sizeof (PVOID)))
81 #define QUEUE_ADD_INDEX(var, inc) \
84 if (var >= q->capacity) \
86 MYASSERT (var < q->capacity); \
89 #define QUEUE_SANITY_CHECK() \
90 MYASSERT (q != NULL && q->base < q->capacity && q->size <= q->capacity)
92 #define QueueCount(q) (q->size)
94 #define UPDATE_MAX_SIZE() \
96 if (q->size > q->max_size) \
97 q->max_size = q->size; \
101 QueueInit (ULONG capacity
)
105 MYASSERT (capacity
> 0);
106 q
= (Queue
*) MemAlloc (QUEUE_BYTE_ALLOCATION (capacity
), TRUE
);
110 q
->base
= q
->size
= 0;
111 q
->capacity
= capacity
;
121 QUEUE_SANITY_CHECK ();
122 MemFree (q
, QUEUE_BYTE_ALLOCATION (q
->capacity
));
127 QueuePush (Queue
*q
, PVOID item
)
130 QUEUE_SANITY_CHECK ();
131 if (q
->size
== q
->capacity
)
134 QUEUE_ADD_INDEX (dest
, q
->size
);
135 q
->data
[dest
] = item
;
145 QUEUE_SANITY_CHECK ();
149 QUEUE_ADD_INDEX (q
->base
, 1);
152 return q
->data
[oldbase
];
156 QueueExtract (Queue
*q
, PVOID item
)
158 ULONG src
, dest
, count
, n
;
159 QUEUE_SANITY_CHECK ();
161 src
= dest
= q
->base
;
165 if (item
== q
->data
[src
])
172 q
->data
[dest
] = q
->data
[src
];
173 QUEUE_ADD_INDEX (dest
, 1);
175 QUEUE_ADD_INDEX (src
, 1);
183 #undef QUEUE_BYTE_ALLOCATION
184 #undef QUEUE_ADD_INDEX
185 #undef QUEUE_SANITY_CHECK
186 #undef UPDATE_MAX_SIZE