VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.h@ 21343

Last change on this file since 21343 was 21343, checked in by vboxsync, 15 years ago

export vboxnetflt for Windows to OSE

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 29.5 KB
Line 
1/* $Id: VBoxNetFlt-win.h 21343 2009-07-07 15:30:08Z vboxsync $ */
2/** @file
3 * VBoxNetFlt - Network Filter Driver (Host), Windows Specific Code. Integration with IntNet/NetFlt
4 */
5
6/*
7 * Copyright (C) 2008 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21/*
22 * Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample.
23 * Copyright (c) 1993-1999, Microsoft Corporation
24 */
25
26#ifndef ___VBoxNetFlt_win_h___
27#define ___VBoxNetFlt_win_h___
28
29/*
30 * globals
31 */
32
33/** global lock */
34extern NDIS_SPIN_LOCK g_GlobalLock;
35
36extern UINT g_fPacketDontLoopBack;
37extern UINT g_fPacketIsLoopedBack;
38
39/*
40 * Debug Print API
41 */
42#ifdef DEBUG
43
44#define DBGPRINT(Fmt) DbgPrint Fmt
45
46#else /* if DBG */
47
48#define DBGPRINT(Fmt)
49
50#endif /* if DBG */
51
52
53DECLHIDDEN(NTSTATUS) vboxNetFltWinPtDispatch(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp);
54DECLHIDDEN(VOID) vboxNetFltWinUnload(IN PDRIVER_OBJECT DriverObject);
55
56/*************************
57 * packet queue API *
58 *************************/
59
60
61#define LIST_ENTRY_2_PACKET_INFO(pListEntry) \
62 ( (PPACKET_INFO)((uint8_t *)(pListEntry) - RT_OFFSETOF(PACKET_INFO, ListEntry)) )
63
64/**
65 * enqueus the packet info to the tail of the queue
66 */
67DECLINLINE(void) vboxNetFltWinQuEnqueueTail(PPACKET_QUEUE pQueue, PPACKET_INFO pPacketInfo)
68{
69 InsertTailList(pQueue, &pPacketInfo->ListEntry);
70}
71
72DECLINLINE(void) vboxNetFltWinQuEnqueueHead(PPACKET_QUEUE pQueue, PPACKET_INFO pPacketInfo)
73{
74 Assert(pPacketInfo->pPool);
75 InsertHeadList(pQueue, &pPacketInfo->ListEntry);
76}
77
78/**
79 * enqueus the packet info to the tail of the queue
80 */
81DECLINLINE(void) vboxNetFltWinQuInterlockedEnqueueTail(PINTERLOCKED_PACKET_QUEUE pQueue, PPACKET_INFO pPacketInfo)
82{
83 Assert(pPacketInfo->pPool);
84 NdisAcquireSpinLock(&pQueue->Lock);
85 vboxNetFltWinQuEnqueueTail(&pQueue->Queue, pPacketInfo);
86 NdisReleaseSpinLock(&pQueue->Lock);
87}
88
89DECLINLINE(void) vboxNetFltWinQuInterlockedEnqueueHead(PINTERLOCKED_PACKET_QUEUE pQueue, PPACKET_INFO pPacketInfo)
90{
91 NdisAcquireSpinLock(&pQueue->Lock);
92 vboxNetFltWinQuEnqueueHead(&pQueue->Queue, pPacketInfo);
93 NdisReleaseSpinLock(&pQueue->Lock);
94}
95
96/**
97 * dequeus the packet info from the head of the queue
98 */
99DECLINLINE(PPACKET_INFO) vboxNetFltWinQuDequeueHead(PPACKET_QUEUE pQueue)
100{
101 PLIST_ENTRY pListEntry = RemoveHeadList(pQueue);
102 if(pListEntry != pQueue)
103 {
104 PPACKET_INFO pInfo = LIST_ENTRY_2_PACKET_INFO(pListEntry);
105 Assert(pInfo->pPool);
106 return pInfo;
107 }
108 return NULL;
109}
110
111DECLINLINE(PPACKET_INFO) vboxNetFltWinQuDequeueTail(PPACKET_QUEUE pQueue)
112{
113 PLIST_ENTRY pListEntry = RemoveTailList(pQueue);
114 if(pListEntry != pQueue)
115 {
116 PPACKET_INFO pInfo = LIST_ENTRY_2_PACKET_INFO(pListEntry);
117 Assert(pInfo->pPool);
118 return pInfo;
119 }
120 return NULL;
121}
122
123DECLINLINE(PPACKET_INFO) vboxNetFltWinQuInterlockedDequeueHead(PINTERLOCKED_PACKET_QUEUE pInterlockedQueue)
124{
125 PPACKET_INFO pInfo;
126 NdisAcquireSpinLock(&pInterlockedQueue->Lock);
127 pInfo = vboxNetFltWinQuDequeueHead(&pInterlockedQueue->Queue);
128 NdisReleaseSpinLock(&pInterlockedQueue->Lock);
129 return pInfo;
130}
131
132DECLINLINE(PPACKET_INFO) vboxNetFltWinQuInterlockedDequeueTail(PINTERLOCKED_PACKET_QUEUE pInterlockedQueue)
133{
134 PPACKET_INFO pInfo;
135 NdisAcquireSpinLock(&pInterlockedQueue->Lock);
136 pInfo = vboxNetFltWinQuDequeueTail(&pInterlockedQueue->Queue);
137 NdisReleaseSpinLock(&pInterlockedQueue->Lock);
138 return pInfo;
139}
140
141DECLINLINE(void) vboxNetFltWinQuDequeue(PPACKET_INFO pInfo)
142{
143 RemoveEntryList(&pInfo->ListEntry);
144}
145
146DECLINLINE(void) vboxNetFltWinQuInterlockedDequeue(PINTERLOCKED_PACKET_QUEUE pInterlockedQueue, PPACKET_INFO pInfo)
147{
148 NdisAcquireSpinLock(&pInterlockedQueue->Lock);
149 vboxNetFltWinQuDequeue(pInfo);
150 NdisReleaseSpinLock(&pInterlockedQueue->Lock);
151}
152
153/**
154 * allocates the packet info from the pool
155 */
156DECLINLINE(PPACKET_INFO) vboxNetFltWinPpAllocPacketInfo(PPACKET_INFO_POOL pPool)
157{
158 return vboxNetFltWinQuInterlockedDequeueHead(&pPool->Queue);
159}
160
161/**
162 * returns the packet info to the pool
163 */
164DECLINLINE(void) vboxNetFltWinPpFreePacketInfo(PPACKET_INFO pInfo)
165{
166 PPACKET_INFO_POOL pPool = pInfo->pPool;
167 vboxNetFltWinQuInterlockedEnqueueHead(&pPool->Queue, pInfo);
168}
169
170/** initializes the packet queue */
171#define INIT_PACKET_QUEUE(_pQueue) InitializeListHead((_pQueue))
172
173/** initializes the packet queue */
174#define INIT_INTERLOCKED_PACKET_QUEUE(_pQueue) \
175 { \
176 INIT_PACKET_QUEUE(&(_pQueue)->Queue); \
177 NdisAllocateSpinLock(&(_pQueue)->Lock); \
178 }
179
180/** delete the packet queue */
181#define FINI_INTERLOCKED_PACKET_QUEUE(_pQueue) NdisFreeSpinLock(&(_pQueue)->Lock)
182
183/** returns the packet the packet info contains */
184#define GET_PACKET_FROM_INFO(_pPacketInfo) (ASMAtomicUoReadPtr((void * volatile *)&(_pPacketInfo)->pPacket))
185
186/** assignes the packet to the packet info */
187#define SET_PACKET_TO_INFO(_pPacketInfo, _pPacket) (ASMAtomicUoWritePtr((void * volatile *)&(_pPacketInfo)->pPacket, (_pPacket)))
188
189/** returns the flags the packet info contains */
190#define GET_FLAGS_FROM_INFO(_pPacketInfo) (ASMAtomicUoReadU32((volatile uint32_t *)&(_pPacketInfo)->fFlags))
191
192/** sets flags to the packet info */
193#define SET_FLAGS_TO_INFO(_pPacketInfo, _fFlags) (ASMAtomicUoWriteU32((volatile uint32_t *)&(_pPacketInfo)->fFlags, (_fFlags)))
194
195DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQuEnqueuePacket(PVBOXNETFLTINS pInstance, PVOID pPacket, const UINT fPacketFlags);
196
197#ifndef VBOX_NETFLT_ONDEMAND_BIND
198DECLHIDDEN(void) vboxNetFltWinQuFiniPacketQueue(PVBOXNETFLTINS pInstance);
199
200DECLHIDDEN(NTSTATUS) vboxNetFltWinQuInitPacketQueue(PVBOXNETFLTINS pInstance);
201#endif
202
203
204/**
205 * searches the list entry in a single-linked list
206 */
207DECLINLINE(bool) vboxNetFltWinSearchListEntry(PSINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry2Search, bool bRemove)
208{
209 PSINGLE_LIST_ENTRY pHead = &pList->Head;
210 PSINGLE_LIST_ENTRY pCur;
211 PSINGLE_LIST_ENTRY pPrev;
212 for(pCur = pHead->Next, pPrev = pHead; pCur; pPrev = pCur, pCur = pCur->Next)
213 {
214 if(pEntry2Search == pCur)
215 {
216 if(bRemove)
217 {
218 pPrev->Next = pCur->Next;
219 if(pCur == pList->pTail)
220 {
221 pList->pTail = pPrev;
222 }
223 }
224 return true;
225 }
226 }
227 return false;
228}
229
230DECLINLINE(void) vboxNetFltWinPutTail(PSINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry)
231{
232 pList->pTail->Next = pEntry;
233 pList->pTail = pEntry;
234}
235
236DECLINLINE(PSINGLE_LIST_ENTRY) vboxNetFltWinGetHead(PSINGLE_LIST pList)
237{
238 PSINGLE_LIST_ENTRY pEntry = pList->Head.Next;
239 if(pEntry && pEntry == pList->pTail)
240 {
241 pList->pTail = &pList->Head;
242 }
243 return pEntry;
244}
245
246DECLINLINE(bool) vboxNetFltWinInterlockedSearchListEntry(PINTERLOCKED_SINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry2Search, bool bRemove)
247{
248 bool bFound;
249 NdisAcquireSpinLock(&pList->Lock);
250 bFound = vboxNetFltWinSearchListEntry(&pList->List, pEntry2Search, bRemove);
251 NdisReleaseSpinLock(&pList->Lock);
252 return bFound;
253}
254
255DECLINLINE(void) vboxNetFltWinInterlockedPutTail(PINTERLOCKED_SINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry)
256{
257 NdisAcquireSpinLock(&pList->Lock);
258 vboxNetFltWinPutTail(&pList->List, pEntry);
259 NdisReleaseSpinLock(&pList->Lock);
260}
261
262DECLINLINE(PSINGLE_LIST_ENTRY) vboxNetFltWinInterlockedGetHead(PINTERLOCKED_SINGLE_LIST pList)
263{
264 PSINGLE_LIST_ENTRY pEntry;
265 NdisAcquireSpinLock(&pList->Lock);
266 pEntry = vboxNetFltWinGetHead(&pList->List);
267 NdisReleaseSpinLock(&pList->Lock);
268 return pEntry;
269}
270
271/** initializes the list */
272#define INIT_SINGLE_LIST(_pList) \
273 { \
274 (_pList)->Head.Next = NULL; \
275 (_pList)->pTail = &(_pList)->Head; \
276 }
277
278/** initializes the list */
279#define INIT_INTERLOCKED_SINGLE_LIST(_pList) \
280 { \
281 INIT_SINGLE_LIST(&(_pList)->List); \
282 NdisAllocateSpinLock(&(_pList)->Lock); \
283 }
284
285/** delete the packet queue */
286#define FINI_INTERLOCKED_SINGLE_LIST(_pList) NdisFreeSpinLock(&(_pList)->Lock)
287
288/** obtains the PTRANSFERDATA_RSVD given a single list entry it contains */
289#define PT_SLE_2_TRANSFERDATA_RSVD(_pl) \
290 ( (PTRANSFERDATA_RSVD)((uint8_t *)(_pl) - RT_OFFSETOF(TRANSFERDATA_RSVD, ListEntry)))
291
292/** obtains the ndis packet given a single list entry assuming it is stored in ProtocolReserved field of the packet */
293#define PT_SLE_2_NDIS_PACKET(_pl) \
294 ( (PNDIS_PACKET)((uint8_t *)PT_SLE_2_TRANSFERDATA_RSVD(_pl) - RT_OFFSETOF(NDIS_PACKET, ProtocolReserved)))
295
296/**************************************************************************
297 * PADAPT, PVBOXNETFLTINS reference/dereference (i.e. retain/release) API *
298 **************************************************************************/
299
300/** get the PVBOXNETFLTINS from PADAPT */
301#define PADAPT_2_PVBOXNETFLTINS(_pAdapt) ( (PVBOXNETFLTINS)((uint8_t *)(_pAdapt) - RT_OFFSETOF(VBOXNETFLTINS, u.s.IfAdaptor)) )
302/** get the PADAPT from PVBOXNETFLTINS */
303#define PVBOXNETFLTINS_2_PADAPT(_pNetFlt) ( &(_pNetFlt)->u.s.IfAdaptor )
304
305DECLHIDDEN(void) vboxNetFltWinWaitDereference(PADAPT_DEVICE pState);
306
307DECLINLINE(void) vboxNetFltWinSetPowerState(PADAPT_DEVICE pState, NDIS_DEVICE_POWER_STATE State)
308{
309 ASMAtomicUoWriteU32((volatile uint32_t *)&pState->PowerState, State);
310}
311
312DECLINLINE(NDIS_DEVICE_POWER_STATE) vboxNetFltWinGetPowerState(PADAPT_DEVICE pState)
313{
314 return (NDIS_DEVICE_POWER_STATE)ASMAtomicUoReadU32((volatile uint32_t *)&pState->PowerState);
315}
316
317DECLINLINE(void) vboxNetFltWinSetOpState(PADAPT_DEVICE pState, VBOXNETDEVOPSTATE State)
318{
319 ASMAtomicUoWriteU32((volatile uint32_t *)&pState->OpState, State);
320}
321
322DECLINLINE(VBOXNETDEVOPSTATE) vboxNetFltWinGetOpState(PADAPT_DEVICE pState)
323{
324 return (VBOXNETDEVOPSTATE)ASMAtomicUoReadU32((volatile uint32_t *)&pState->OpState);
325}
326
327DECLINLINE(bool) vboxNetFltWinDoReferenceDevice(PADAPT pAdapt, PADAPT_DEVICE pState)
328{
329 if (vboxNetFltWinGetPowerState(pState) == NdisDeviceStateD0 && vboxNetFltWinGetOpState(pState) == kVBoxNetDevOpState_Initialized)
330 {
331 /** @todo r=bird: Since this is a volatile member, why don't you declare it as
332 * such and save yourself all the casting? */
333 ASMAtomicIncU32((uint32_t volatile *)&pState->cReferences);
334 return true;
335 }
336 return false;
337}
338
339#ifndef VBOXNETADP
340DECLINLINE(bool) vboxNetFltWinDoReferenceDevices(PADAPT pAdapt, PADAPT_DEVICE pState1, PADAPT_DEVICE pState2)
341{
342 if (vboxNetFltWinGetPowerState(pState1) == NdisDeviceStateD0
343 && vboxNetFltWinGetOpState(pState1) == kVBoxNetDevOpState_Initialized
344 && vboxNetFltWinGetPowerState(pState2) == NdisDeviceStateD0
345 && vboxNetFltWinGetOpState(pState2) == kVBoxNetDevOpState_Initialized)
346 {
347 ASMAtomicIncU32((uint32_t volatile *)&pState1->cReferences);
348 ASMAtomicIncU32((uint32_t volatile *)&pState2->cReferences);
349 return true;
350 }
351 return false;
352}
353#endif
354
355DECLINLINE(void) vboxNetFltWinDereferenceDevice(PADAPT pAdapt, PADAPT_DEVICE pState)
356{
357/* NdisAcquireSpinLock(&pAdapt->Lock); */
358 ASMAtomicDecU32((uint32_t volatile *)&pState->cReferences);
359 /** @todo r=bird: Add comment explaining why these cannot hit 0 or why
360 * reference are counted */
361/* NdisReleaseSpinLock(&pAdapt->Lock); */
362}
363
364#ifndef VBOXNETADP
365DECLINLINE(void) vboxNetFltWinDereferenceDevices(PADAPT pAdapt, PADAPT_DEVICE pState1, PADAPT_DEVICE pState2)
366{
367/* NdisAcquireSpinLock(&pAdapt->Lock); */
368 ASMAtomicDecU32((uint32_t volatile *)&pState1->cReferences);
369 ASMAtomicDecU32((uint32_t volatile *)&pState2->cReferences);
370/* NdisReleaseSpinLock(&pAdapt->Lock); */
371}
372#endif
373
374DECLINLINE(void) vboxNetFltWinDecReferenceDevice(PADAPT pAdapt, PADAPT_DEVICE pState, uint32_t v)
375{
376 ASMAtomicAddU32((uint32_t volatile *)&pState->cReferences, (uint32_t)(-((int32_t)v)));
377}
378
379#ifndef VBOXNETADP
380DECLINLINE(void) vboxNetFltWinDecReferenceDevices(PADAPT pAdapt, PADAPT_DEVICE pState1, PADAPT_DEVICE pState2, uint32_t v)
381{
382 ASMAtomicAddU32((uint32_t volatile *)&pState1->cReferences, (uint32_t)(-((int32_t)v)));
383 ASMAtomicAddU32((uint32_t volatile *)&pState2->cReferences, (uint32_t)(-((int32_t)v)));
384}
385#endif
386
387DECLINLINE(bool) vboxNetFltWinDoIncReferenceDevice(PADAPT pAdapt, PADAPT_DEVICE pState, uint32_t v)
388{
389 if (vboxNetFltWinGetPowerState(pState) == NdisDeviceStateD0 && vboxNetFltWinGetOpState(pState) == kVBoxNetDevOpState_Initialized)
390 {
391 ASMAtomicAddU32((uint32_t volatile *)&pState->cReferences, v);
392 return true;
393 }
394 return false;
395}
396
397#ifndef VBOXNETADP
398DECLINLINE(bool) vboxNetFltWinDoIncReferenceDevices(PADAPT pAdapt, PADAPT_DEVICE pState1, PADAPT_DEVICE pState2, uint32_t v)
399{
400 if (vboxNetFltWinGetPowerState(pState1) == NdisDeviceStateD0
401 && vboxNetFltWinGetOpState(pState1) == kVBoxNetDevOpState_Initialized
402 && vboxNetFltWinGetPowerState(pState2) == NdisDeviceStateD0
403 && vboxNetFltWinGetOpState(pState2) == kVBoxNetDevOpState_Initialized)
404 {
405 ASMAtomicAddU32((uint32_t volatile *)&pState1->cReferences, v);
406 ASMAtomicAddU32((uint32_t volatile *)&pState2->cReferences, v);
407 return true;
408 }
409 return false;
410}
411#endif
412
413#ifdef VBOX_NETFLT_ONDEMAND_BIND
414DECLINLINE(PVBOXNETFLTINS) vboxNetFltWinReferenceAdaptNetFltFromAdapt(PADAPT pAdapt)
415{
416 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
417 PVBOXNETFLTINS pNetFlt;
418
419 pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
420
421 RTSpinlockAcquire((pNetFlt)->hSpinlock, &Tmp);
422 if(!ASMAtomicUoReadBool(&(pNetFlt)->fActive))
423 {
424 RTSpinlockRelease((pNetFlt)->hSpinlock, &Tmp);
425 return NULL;
426 }
427
428 if(!vboxNetFltWinDoReferenceDevice(pAdapt, &pAdapt->PTState))
429 {
430 RTSpinlockRelease((pNetFlt)->hSpinlock, &Tmp);
431 return NULL;
432 }
433
434 vboxNetFltRetain((pNetFlt), true /* fBusy */);
435
436 RTSpinlockRelease((pNetFlt)->hSpinlock, &Tmp);
437
438 return pNetFlt;
439}
440#else
441DECLINLINE(bool) vboxNetFltWinReferenceAdaptNetFltFromAdapt(PADAPT pAdapt, PVBOXNETFLTINS *ppNetFlt)
442{
443 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
444 PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
445
446 RTSpinlockAcquire((pNetFlt)->hSpinlock, &Tmp);
447#ifndef VBOXNETADP
448 if(!vboxNetFltWinDoReferenceDevices(pAdapt, &pAdapt->MPState, &pAdapt->PTState))
449#else
450 if(!vboxNetFltWinDoReferenceDevice(pAdapt, &pAdapt->MPState))
451#endif
452 {
453 RTSpinlockRelease((pNetFlt)->hSpinlock, &Tmp);
454 *ppNetFlt = NULL;
455 return false;
456 }
457
458 if(!ASMAtomicUoReadBool(&(pNetFlt)->fActive))
459 {
460 RTSpinlockRelease((pNetFlt)->hSpinlock, &Tmp);
461 *ppNetFlt = NULL;
462 return true;
463 }
464
465 vboxNetFltRetain((pNetFlt), true /* fBusy */);
466
467 RTSpinlockRelease((pNetFlt)->hSpinlock, &Tmp);
468
469 *ppNetFlt = pNetFlt;
470 return true;
471}
472#endif
473
474#ifdef VBOX_NETFLT_ONDEMAND_BIND
475DECLINLINE(PVBOXNETFLTINS) vboxNetFltWinIncReferenceAdaptNetFltFromAdapt(PADAPT pAdapt, uint32_t v)
476{
477 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
478 PVBOXNETFLTINS pNetFlt;
479 uint32_t i;
480
481 Assert(v);
482 if(!v)
483 {
484 return NULL;
485 }
486
487 pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
488
489 RTSpinlockAcquire((pNetFlt)->hSpinlock, &Tmp);
490 if(!ASMAtomicUoReadBool(&(pNetFlt)->fActive))
491 {
492 RTSpinlockRelease((pNetFlt)->hSpinlock, &Tmp);
493 return NULL;
494 }
495
496 if(!vboxNetFltWinDoIncReferenceDevice(pAdapt, &pAdapt->PTState, v))
497 {
498 RTSpinlockRelease((pNetFlt)->hSpinlock, &Tmp);
499 return NULL;
500 }
501
502 vboxNetFltRetain((pNetFlt), true /* fBusy */);
503
504 RTSpinlockRelease((pNetFlt)->hSpinlock, &Tmp);
505
506 /* we have marked it as busy, so can do the res references outside the lock */
507 for(i = 0; i < v-1; i++)
508 {
509 vboxNetFltRetain((pNetFlt), true /* fBusy */);
510 }
511
512 return pNetFlt;
513}
514#else
515DECLINLINE(bool) vboxNetFltWinIncReferenceAdaptNetFltFromAdapt(PADAPT pAdapt, PVBOXNETFLTINS *ppNetFlt, uint32_t v)
516{
517 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
518 uint32_t i;
519 PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
520
521 Assert(v);
522 if(!v)
523 {
524 *ppNetFlt = NULL;
525 return false;
526 }
527
528 RTSpinlockAcquire((pNetFlt)->hSpinlock, &Tmp);
529#ifndef VBOXNETADP
530 if(!vboxNetFltWinDoIncReferenceDevices(pAdapt, &pAdapt->MPState, &pAdapt->PTState, v))
531#else
532 if(!vboxNetFltWinDoIncReferenceDevice(pAdapt, &pAdapt->MPState, v))
533#endif
534 {
535 RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
536 *ppNetFlt = NULL;
537 return false;
538 }
539
540 if(!ASMAtomicUoReadBool(&(pNetFlt)->fActive))
541 {
542 RTSpinlockRelease((pNetFlt)->hSpinlock, &Tmp);
543 *ppNetFlt = NULL;
544 return true;
545 }
546
547 vboxNetFltRetain(pNetFlt, true /* fBusy */);
548 RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
549
550 /* we have marked it as busy, so can do the res references outside the lock */
551 for(i = 0; i < v-1; i++)
552 {
553 vboxNetFltRetain(pNetFlt, true /* fBusy */);
554 }
555
556 *ppNetFlt = pNetFlt;
557
558 return true;
559}
560
561#endif
562
563DECLINLINE(void) vboxNetFltWinDecReferenceNetFlt(PVBOXNETFLTINS pNetFlt, uint32_t n)
564{
565 uint32_t i;
566 for(i = 0; i < n; i++)
567 {
568 vboxNetFltRelease(pNetFlt, true);
569 }
570}
571
572DECLINLINE(void) vboxNetFltWinDereferenceNetFlt(PVBOXNETFLTINS pNetFlt)
573{
574 vboxNetFltRelease(pNetFlt, true);
575}
576
577DECLINLINE(void) vboxNetFltWinDecReferenceAdapt(PADAPT pAdapt, uint32_t v)
578{
579#ifdef VBOX_NETFLT_ONDEMAND_BIND
580 vboxNetFltWinDecReferenceDevice(pAdapt, &pAdapt->PTState, v);
581#elif defined(VBOXNETADP)
582 vboxNetFltWinDecReferenceDevice(pAdapt, &pAdapt->MPState, v);
583#else
584 vboxNetFltWinDecReferenceDevices(pAdapt, &pAdapt->MPState, &pAdapt->PTState, v);
585#endif
586}
587
588DECLINLINE(void) vboxNetFltWinDereferenceAdapt(PADAPT pAdapt)
589{
590#ifdef VBOX_NETFLT_ONDEMAND_BIND
591 vboxNetFltWinDereferenceDevice(pAdapt, &pAdapt->PTState);
592#elif defined(VBOXNETADP)
593 vboxNetFltWinDereferenceDevice(pAdapt, &pAdapt->MPState);
594#else
595 vboxNetFltWinDereferenceDevices(pAdapt, &pAdapt->MPState, &pAdapt->PTState);
596#endif
597}
598
599DECLINLINE(bool) vboxNetFltWinIncReferenceAdapt(PADAPT pAdapt, uint32_t v)
600{
601 PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
602 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
603
604 Assert(v);
605 if(!v)
606 {
607 return false;
608 }
609
610 RTSpinlockAcquire(pNetFlt->hSpinlock, &Tmp);
611#ifdef VBOX_NETFLT_ONDEMAND_BIND
612 if(vboxNetFltWinDoIncReferenceDevice(pAdapt, &pAdapt->PTState))
613#elif defined(VBOXNETADP)
614 if(vboxNetFltWinDoIncReferenceDevice(pAdapt, &pAdapt->MPState, v))
615#else
616 if(vboxNetFltWinDoIncReferenceDevices(pAdapt, &pAdapt->MPState, &pAdapt->PTState, v))
617#endif
618 {
619 RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
620 return true;
621 }
622
623 RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
624 return false;
625}
626
627DECLINLINE(bool) vboxNetFltWinReferenceAdapt(PADAPT pAdapt)
628{
629 PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
630 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
631 RTSpinlockAcquire(pNetFlt->hSpinlock, &Tmp);
632#ifdef VBOX_NETFLT_ONDEMAND_BIND
633 if(vboxNetFltWinDoReferenceDevice(pAdapt, &pAdapt->PTState))
634#elif defined(VBOXNETADP)
635 if(vboxNetFltWinDoReferenceDevice(pAdapt, &pAdapt->MPState))
636#else
637 if(vboxNetFltWinDoReferenceDevices(pAdapt, &pAdapt->MPState, &pAdapt->PTState))
638#endif
639 {
640 RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
641 return true;
642 }
643
644 RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
645 return false;
646}
647
648/***********************************************
649 * methods for accessing the network card info *
650 ***********************************************/
651
652DECLHIDDEN(NDIS_STATUS) vboxNetFltWinGetMacAddress(PADAPT pAdapt, PRTMAC pMac);
653DECLHIDDEN(bool) vboxNetFltWinIsPromiscuous(PADAPT pAdapt);
654DECLHIDDEN(NDIS_STATUS) vboxNetFltWinSetPromiscuous(PADAPT pAdapt, bool bYes);
655DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQueryPhysicalMedium(PADAPT pAdapt, NDIS_PHYSICAL_MEDIUM * pMedium);
656
657/*********************
658 * mem alloc API *
659 *********************/
660
661DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMemAlloc(PVOID* ppMemBuf, UINT cbLength);
662
663DECLHIDDEN(void) vboxNetFltWinMemFree(PVOID pMemBuf);
664
665/* convenience method used which allocates and initializes the PINTNETSG containing one
666 * segment refering the buffer of size cbBufSize
667 * the allocated PINTNETSG should be freed with the vboxNetFltWinMemFree.
668 *
669 * This is used when our ProtocolReceive callback is called and we have to return the indicated NDIS_PACKET
670 * on a callback exit. This is why we allocate the PINTNETSG and put the packet info there and enqueue it
671 * for the packet queue */
672DECLHIDDEN(NDIS_STATUS) vboxNetFltWinAllocSG(UINT cbBufSize, PINTNETSG *ppSG);
673
674/************************
675 * PADAPT init/fini API *
676 ************************/
677
678#if defined(VBOX_NETFLT_ONDEMAND_BIND)
679DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PADAPT pAdapt);
680#elif defined(VBOXNETADP)
681DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PADAPT *ppAdapt, NDIS_HANDLE hMiniportAdapter, PNDIS_STRING pBindToMiniportName /* actually this is our miniport name*/, NDIS_HANDLE hWrapperConfigurationContext);
682#else
683DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PADAPT *ppAdapt, PNDIS_STRING pOurMiniportName, PNDIS_STRING pBindToMiniportName);
684#endif
685
686#ifdef VBOX_NETFLT_ONDEMAND_BIND
687DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtAllocInitPADAPT(PADAPT pAdapt);
688#else
689DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtAllocInitPADAPT(PADAPT *ppAdapt, PNDIS_STRING pOurMiniportName, PNDIS_STRING pBindToMiniportName);
690#endif
691
692DECLHIDDEN(VOID) vboxNetFltWinPtFiniPADAPT(PADAPT pAdapt);
693#ifndef VBOXNETADP
694DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitPADAPT(IN PADAPT pAdapt, IN PNDIS_STRING pOurDeviceName);
695#else
696DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitPADAPT(IN PADAPT pAdapt);
697#endif
698
699/************************************
700 * Execute Job at passive level API *
701 ************************************/
702
703typedef VOID (*JOB_ROUTINE) (PVOID pContext);
704
705DECLHIDDEN(VOID) vboxNetFltWinJobSynchExecAtPassive(JOB_ROUTINE pRoutine, PVOID pContext);
706
707/*******************************
708 * Ndis Packets processing API *
709 *******************************/
710
711#ifndef NDIS_PACKET_FIRST_NDIS_BUFFER
712#define NDIS_PACKET_FIRST_NDIS_BUFFER(_Packet) ((_Packet)->Private.Head)
713#endif
714
715#ifndef NDIS_PACKET_LAST_NDIS_BUFFER
716#define NDIS_PACKET_LAST_NDIS_BUFFER(_Packet) ((_Packet)->Private.Tail)
717#endif
718
719#ifndef NDIS_PACKET_VALID_COUNTS
720#define NDIS_PACKET_VALID_COUNTS(_Packet) ((_Packet)->Private.ValidCounts)
721#endif
722
723
724DECLHIDDEN(PNDIS_PACKET) vboxNetFltWinNdisPacketFromSG(PADAPT pAdapt, PINTNETSG pSG, PVOID pBufToFree, bool bToWire, bool bCopyMemory);
725
726DECLHIDDEN(void) vboxNetFltWinFreeSGNdisPacket(PNDIS_PACKET pPacket, bool bFreeMem);
727
728#ifdef DEBUG_NETFLT_PACKETS
729DECLHIDDEN(bool) vboxNetFltWinMatchPacketAndSG(PNDIS_PACKET pPacket, PINTNETSG pSG, const INT cbMatch);
730
731DECLHIDDEN(bool) vboxNetFltWinMatchPackets(PNDIS_PACKET pPacket1, PNDIS_PACKET pPacket2, const INT cbMatch);
732
733#endif
734
735#ifdef DEBUG_NETFLT_PACKETS
736#define DBG_CHECK_PACKETS(_p1, _p2) \
737 { \
738 bool _b = vboxNetFltWinMatchPackets(_p1, _p2, -1); \
739 Assert(_b); \
740 }
741
742#define DBG_CHECK_PACKET_AND_SG(_p, _sg) \
743 { \
744 bool _b = vboxNetFltWinMatchPacketAndSG(_p, _sg, -1); \
745 Assert(_b); \
746 }
747
748#define DBG_CHECK_SGS(_sg1, _sg2) \
749 { \
750 bool _b = vboxNetFltWinMatchSGs(_sg1, _sg2, -1); \
751 Assert(_b); \
752 }
753
754#else
755#define DBG_CHECK_PACKETS(_p1, _p2)
756#define DBG_CHECK_PACKET_AND_SG(_p, _sg)
757#define DBG_CHECK_SGS(_sg1, _sg2)
758#endif
759
760/**
761 * Ndis loops back broadcast packets posted to the wire by IntNet
762 * This routine is used in the mechanism of preventing this looping
763 *
764 * @param pAdapt
765 * @param pPacket
766 * @param bOnRecv true is we are receiving the packet from the wire
767 * false otherwise (i.e. the packet is from the host)
768 *
769 * @return true if the packet is a looped back one, false otherwise
770 */
771#ifdef DEBUG_NETFLT_LOOPBACK
772# error "implement (see comments in the sources below this #error:)"
773 /* @todo FIXME no need for the PPACKET_INFO mechanism here;
774 instead the the NDIS_PACKET.ProtocolReserved + INTERLOCKED_SINGLE_LIST mechanism \
775 similar to that used in TrasferData handling should be used;
776 */
777
778//#ifdef VBOX_NETFLT_ONDEMAND_BIND
779//DECLHIDDEN(bool) vboxNetFltWinIsLoopedBackPacket(PADAPT pAdapt, PNDIS_PACKET pPacket);
780//#else
781//DECLHIDDEN(bool) vboxNetFltWinIsLoopedBackPacket(PADAPT pAdapt, PNDIS_PACKET pPacket, bool bOnRecv);
782//#endif
783//
784//#ifdef VBOX_NETFLT_ONDEMAND_BIND
785//DECLHIDDEN(bool) vboxNetFltWinIsLoopedBackPacketSG(PADAPT pAdapt, PINTNETSG pSG);
786//#else
787//DECLHIDDEN(bool) vboxNetFltWinIsLoopedBackPacketSG(PADAPT pAdapt, PINTNETSG pSG, bool bOnRecv);
788//#endif
789#else
790DECLINLINE(bool) vboxNetFltWinIsLoopedBackPacket(PNDIS_PACKET pPacket)
791{
792 return (NdisGetPacketFlags(pPacket) & g_fPacketIsLoopedBack) == g_fPacketIsLoopedBack;
793}
794#endif
795
796#if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP)
797
798/**************************************************************
799 * utility methofs for ndis packet creation/initialization *
800 **************************************************************/
801DECLINLINE(NDIS_STATUS) vboxNetFltWinCopyPacketInfoOnRecv(PNDIS_PACKET pDstPacket, PNDIS_PACKET pSrcPacket)
802{
803 NDIS_STATUS fStatus;
804
805 /*
806 * Get the original packet (it could be the same packet as the one
807 * received or a different one based on the number of layered miniports
808 * below) and set it on the indicated packet so the OOB data is visible
809 * correctly to protocols above us.
810 */
811 NDIS_SET_ORIGINAL_PACKET(pDstPacket, NDIS_GET_ORIGINAL_PACKET(pSrcPacket));
812
813 /*
814 * Set Packet Flags
815 */
816 NdisGetPacketFlags(pDstPacket) = NdisGetPacketFlags(pSrcPacket);
817
818 fStatus = NDIS_GET_PACKET_STATUS(pSrcPacket);
819
820 NDIS_SET_PACKET_STATUS(pDstPacket, fStatus);
821 NDIS_SET_PACKET_HEADER_SIZE(pDstPacket, NDIS_GET_PACKET_HEADER_SIZE(pSrcPacket));
822
823 return fStatus;
824}
825
826DECLINLINE(void) vboxNetFltWinCopyPacketInfoOnSend(PNDIS_PACKET pDstPacket, PNDIS_PACKET pSrcPacket)
827{
828 PVOID pMediaSpecificInfo = NULL;
829 UINT fMediaSpecificInfoSize = 0;
830
831 NdisGetPacketFlags(pDstPacket) = NdisGetPacketFlags(pSrcPacket);
832
833#ifdef WIN9X
834 /*
835 * Work around the fact that NDIS does not initialize this
836 * to FALSE on Win9x.
837 */
838 NDIS_PACKET_VALID_COUNTS(pDstPacket) = FALSE;
839#endif /* WIN9X */
840
841 /*
842 * Copy the OOB data from the original packet to the new
843 * packet.
844 */
845 NdisMoveMemory(NDIS_OOB_DATA_FROM_PACKET(pDstPacket),
846 NDIS_OOB_DATA_FROM_PACKET(pSrcPacket),
847 sizeof(NDIS_PACKET_OOB_DATA));
848 /*
849 * Copy relevant parts of the per packet info into the new packet
850 */
851#ifndef WIN9X
852 NdisIMCopySendPerPacketInfo(pDstPacket, pSrcPacket);
853#endif
854
855 /*
856 * Copy the Media specific information
857 */
858 NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO(pSrcPacket,
859 &pMediaSpecificInfo,
860 &fMediaSpecificInfoSize);
861
862 if (pMediaSpecificInfo || fMediaSpecificInfoSize)
863 {
864 NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO(pDstPacket,
865 pMediaSpecificInfo,
866 fMediaSpecificInfoSize);
867 }
868}
869
870DECLHIDDEN(NDIS_STATUS)
871vboxNetFltWinPrepareSendPacket(
872 IN PADAPT pAdapt,
873 IN PNDIS_PACKET pPacket,
874 OUT PNDIS_PACKET *ppMyPacket
875 /*, IN bool bNetFltActive*/
876 );
877
878
879DECLHIDDEN(NDIS_STATUS)
880vboxNetFltWinPrepareRecvPacket(
881 IN PADAPT pAdapt,
882 IN PNDIS_PACKET pPacket,
883 OUT PNDIS_PACKET *ppMyPacket,
884 IN bool bDpr
885 );
886#endif
887
888DECLHIDDEN(void) vboxNetFltWinSleep(ULONG milis);
889
890#define MACS_EQUAL(_m1, _m2) \
891 ((_m1).au16[0] == (_m2).au16[0] \
892 && (_m1).au16[1] == (_m2).au16[1] \
893 && (_m1).au16[2] == (_m2).au16[2])
894
895
896DECLHIDDEN(NDIS_STATUS) vboxNetFltWinDetachFromInterface(PADAPT pAdapt, bool bOnUnbind);
897DECLHIDDEN(NDIS_STATUS) vboxNetFltWinCopyString(PNDIS_STRING pDst, PNDIS_STRING pSrc);
898
899
900/**
901 * Sets the enmState member atomically.
902 *
903 * Used for all updates.
904 *
905 * @param pThis The instance.
906 * @param enmNewState The new value.
907 */
908DECLINLINE(void) vboxNetFltWinSetAdaptState(PADAPT pAdapt, VBOXADAPTSTATE enmNewState)
909{
910 ASMAtomicWriteU32((uint32_t volatile *)&pAdapt->enmState, enmNewState);
911}
912
913/**
914 * Gets the enmState member atomically.
915 *
916 * Used for all reads.
917 *
918 * @returns The enmState value.
919 * @param pThis The instance.
920 */
921DECLINLINE(VBOXADAPTSTATE) vboxNetFltWinGetAdaptState(PADAPT pAdapt)
922{
923 return (VBOXADAPTSTATE)ASMAtomicUoReadU32((uint32_t volatile *)&pAdapt->enmState);
924}
925
926
927#ifndef VBOXNETADP
928# define VBOXNETFLT_PROMISCUOUS_SUPPORTED(_pAdapt) \
929 (!PADAPT_2_PVBOXNETFLTINS(_pAdapt)->fDisablePromiscuous)
930// (!((_pAdapt)->PhMedium == NdisPhysicalMediumWirelessWan \
931// || (_pAdapt)->PhMedium == NdisPhysicalMediumWirelessLan \
932// || (_pAdapt)->PhMedium == NdisPhysicalMediumNative802_11 \
933// || (_pAdapt)->PhMedium == NdisPhysicalMediumBluetooth \
934// /*|| (_pAdapt)->PhMedium == NdisPhysicalMediumWiMax */ \
935// ))
936#else
937# define STATISTIC_INCREASE(_s) ASMAtomicIncU32((uint32_t volatile *)&(_s));
938
939DECLHIDDEN(void) vboxNetFltWinGenerateMACAddress(RTMAC *pMac);
940DECLHIDDEN(int) vboxNetFltWinMAC2NdisString(RTMAC *pMac, PNDIS_STRING pNdisString);
941DECLHIDDEN(int) vboxNetFltWinMACFromNdisString(RTMAC *pMac, PNDIS_STRING pNdisString);
942
943#endif
944#endif
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette