VirtualBox

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

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

netflt/win: wait for pending ops to complete before switching netflt mode on/off

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 31.0 KB
Line 
1/* $Id: VBoxNetFlt-win.h 22441 2009-08-25 15:38:53Z 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) vboxNetFltWinReferenceModeNetFlt(PVBOXNETFLTINS pIns)
308{
309 ASMAtomicIncU32((volatile uint32_t *)&pIns->u.s.cModeNetFltRefs);
310}
311
312DECLINLINE(void) vboxNetFltWinReferenceModePassThru(PVBOXNETFLTINS pIns)
313{
314 ASMAtomicIncU32((volatile uint32_t *)&pIns->u.s.cModePassThruRefs);
315}
316
317DECLINLINE(void) vboxNetFltWinIncReferenceModeNetFlt(PVBOXNETFLTINS pIns, uint32_t v)
318{
319 ASMAtomicAddU32((volatile uint32_t *)&pIns->u.s.cModeNetFltRefs, v);
320}
321
322DECLINLINE(void) vboxNetFltWinIncReferenceModePassThru(PVBOXNETFLTINS pIns, uint32_t v)
323{
324 ASMAtomicAddU32((volatile uint32_t *)&pIns->u.s.cModePassThruRefs, v);
325}
326
327DECLINLINE(void) vboxNetFltWinDereferenceModeNetFlt(PVBOXNETFLTINS pIns)
328{
329 ASMAtomicDecU32((volatile uint32_t *)&pIns->u.s.cModeNetFltRefs);
330}
331
332DECLINLINE(void) vboxNetFltWinDereferenceModePassThru(PVBOXNETFLTINS pIns)
333{
334 ASMAtomicDecU32((volatile uint32_t *)&pIns->u.s.cModePassThruRefs);
335}
336
337DECLINLINE(void) vboxNetFltWinDecReferenceModeNetFlt(PVBOXNETFLTINS pIns, uint32_t v)
338{
339 Assert(v);
340 ASMAtomicAddU32((volatile uint32_t *)&pIns->u.s.cModeNetFltRefs, (uint32_t)(-((int32_t)v)));
341}
342
343DECLINLINE(void) vboxNetFltWinDecReferenceModePassThru(PVBOXNETFLTINS pIns, uint32_t v)
344{
345 Assert(v);
346 ASMAtomicAddU32((volatile uint32_t *)&pIns->u.s.cModePassThruRefs, (uint32_t)(-((int32_t)v)));
347}
348
349DECLINLINE(void) vboxNetFltWinSetPowerState(PADAPT_DEVICE pState, NDIS_DEVICE_POWER_STATE State)
350{
351 ASMAtomicUoWriteU32((volatile uint32_t *)&pState->PowerState, State);
352}
353
354DECLINLINE(NDIS_DEVICE_POWER_STATE) vboxNetFltWinGetPowerState(PADAPT_DEVICE pState)
355{
356 return (NDIS_DEVICE_POWER_STATE)ASMAtomicUoReadU32((volatile uint32_t *)&pState->PowerState);
357}
358
359DECLINLINE(void) vboxNetFltWinSetOpState(PADAPT_DEVICE pState, VBOXNETDEVOPSTATE State)
360{
361 ASMAtomicUoWriteU32((volatile uint32_t *)&pState->OpState, State);
362}
363
364DECLINLINE(VBOXNETDEVOPSTATE) vboxNetFltWinGetOpState(PADAPT_DEVICE pState)
365{
366 return (VBOXNETDEVOPSTATE)ASMAtomicUoReadU32((volatile uint32_t *)&pState->OpState);
367}
368
369DECLINLINE(bool) vboxNetFltWinDoReferenceDevice(PADAPT pAdapt, PADAPT_DEVICE pState)
370{
371 if (vboxNetFltWinGetPowerState(pState) == NdisDeviceStateD0 && vboxNetFltWinGetOpState(pState) == kVBoxNetDevOpState_Initialized)
372 {
373 /** @todo r=bird: Since this is a volatile member, why don't you declare it as
374 * such and save yourself all the casting? */
375 ASMAtomicIncU32((uint32_t volatile *)&pState->cReferences);
376 return true;
377 }
378 return false;
379}
380
381#ifndef VBOXNETADP
382DECLINLINE(bool) vboxNetFltWinDoReferenceDevices(PADAPT pAdapt, PADAPT_DEVICE pState1, PADAPT_DEVICE pState2)
383{
384 if (vboxNetFltWinGetPowerState(pState1) == NdisDeviceStateD0
385 && vboxNetFltWinGetOpState(pState1) == kVBoxNetDevOpState_Initialized
386 && vboxNetFltWinGetPowerState(pState2) == NdisDeviceStateD0
387 && vboxNetFltWinGetOpState(pState2) == kVBoxNetDevOpState_Initialized)
388 {
389 ASMAtomicIncU32((uint32_t volatile *)&pState1->cReferences);
390 ASMAtomicIncU32((uint32_t volatile *)&pState2->cReferences);
391 return true;
392 }
393 return false;
394}
395#endif
396
397DECLINLINE(void) vboxNetFltWinDereferenceDevice(PADAPT pAdapt, PADAPT_DEVICE pState)
398{
399/* NdisAcquireSpinLock(&pAdapt->Lock); */
400 ASMAtomicDecU32((uint32_t volatile *)&pState->cReferences);
401 /** @todo r=bird: Add comment explaining why these cannot hit 0 or why
402 * reference are counted */
403/* NdisReleaseSpinLock(&pAdapt->Lock); */
404}
405
406#ifndef VBOXNETADP
407DECLINLINE(void) vboxNetFltWinDereferenceDevices(PADAPT pAdapt, PADAPT_DEVICE pState1, PADAPT_DEVICE pState2)
408{
409/* NdisAcquireSpinLock(&pAdapt->Lock); */
410 ASMAtomicDecU32((uint32_t volatile *)&pState1->cReferences);
411 ASMAtomicDecU32((uint32_t volatile *)&pState2->cReferences);
412/* NdisReleaseSpinLock(&pAdapt->Lock); */
413}
414#endif
415
416DECLINLINE(void) vboxNetFltWinDecReferenceDevice(PADAPT pAdapt, PADAPT_DEVICE pState, uint32_t v)
417{
418 Assert(v);
419 ASMAtomicAddU32((uint32_t volatile *)&pState->cReferences, (uint32_t)(-((int32_t)v)));
420}
421
422#ifndef VBOXNETADP
423DECLINLINE(void) vboxNetFltWinDecReferenceDevices(PADAPT pAdapt, PADAPT_DEVICE pState1, PADAPT_DEVICE pState2, uint32_t v)
424{
425 ASMAtomicAddU32((uint32_t volatile *)&pState1->cReferences, (uint32_t)(-((int32_t)v)));
426 ASMAtomicAddU32((uint32_t volatile *)&pState2->cReferences, (uint32_t)(-((int32_t)v)));
427}
428#endif
429
430DECLINLINE(bool) vboxNetFltWinDoIncReferenceDevice(PADAPT pAdapt, PADAPT_DEVICE pState, uint32_t v)
431{
432 Assert(v);
433 if (vboxNetFltWinGetPowerState(pState) == NdisDeviceStateD0 && vboxNetFltWinGetOpState(pState) == kVBoxNetDevOpState_Initialized)
434 {
435 ASMAtomicAddU32((uint32_t volatile *)&pState->cReferences, v);
436 return true;
437 }
438 return false;
439}
440
441#ifndef VBOXNETADP
442DECLINLINE(bool) vboxNetFltWinDoIncReferenceDevices(PADAPT pAdapt, PADAPT_DEVICE pState1, PADAPT_DEVICE pState2, uint32_t v)
443{
444 if (vboxNetFltWinGetPowerState(pState1) == NdisDeviceStateD0
445 && vboxNetFltWinGetOpState(pState1) == kVBoxNetDevOpState_Initialized
446 && vboxNetFltWinGetPowerState(pState2) == NdisDeviceStateD0
447 && vboxNetFltWinGetOpState(pState2) == kVBoxNetDevOpState_Initialized)
448 {
449 ASMAtomicAddU32((uint32_t volatile *)&pState1->cReferences, v);
450 ASMAtomicAddU32((uint32_t volatile *)&pState2->cReferences, v);
451 return true;
452 }
453 return false;
454}
455#endif
456
457#ifdef VBOX_NETFLT_ONDEMAND_BIND
458DECLINLINE(PVBOXNETFLTINS) vboxNetFltWinReferenceAdaptNetFltFromAdapt(PADAPT pAdapt)
459{
460 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
461 PVBOXNETFLTINS pNetFlt;
462
463 pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
464
465 RTSpinlockAcquire((pNetFlt)->hSpinlock, &Tmp);
466 if(!ASMAtomicUoReadBool(&(pNetFlt)->fActive))
467 {
468 RTSpinlockRelease((pNetFlt)->hSpinlock, &Tmp);
469 return NULL;
470 }
471
472 if(!vboxNetFltWinDoReferenceDevice(pAdapt, &pAdapt->PTState))
473 {
474 RTSpinlockRelease((pNetFlt)->hSpinlock, &Tmp);
475 return NULL;
476 }
477
478 vboxNetFltRetain((pNetFlt), true /* fBusy */);
479
480 RTSpinlockRelease((pNetFlt)->hSpinlock, &Tmp);
481
482 return pNetFlt;
483}
484#else
485DECLINLINE(bool) vboxNetFltWinReferenceAdaptNetFlt(PVBOXNETFLTINS pNetFlt, PADAPT pAdapt, bool * pbNetFltActive)
486{
487 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
488
489 RTSpinlockAcquire((pNetFlt)->hSpinlock, &Tmp);
490#ifndef VBOXNETADP
491 if(!vboxNetFltWinDoReferenceDevices(pAdapt, &pAdapt->MPState, &pAdapt->PTState))
492#else
493 if(!vboxNetFltWinDoReferenceDevice(pAdapt, &pAdapt->MPState))
494#endif
495 {
496 RTSpinlockRelease((pNetFlt)->hSpinlock, &Tmp);
497 *pbNetFltActive = false;
498 return false;
499 }
500
501 if(!ASMAtomicUoReadBool(&(pNetFlt)->fActive))
502 {
503 vboxNetFltWinReferenceModePassThru(pNetFlt);
504 RTSpinlockRelease((pNetFlt)->hSpinlock, &Tmp);
505 *pbNetFltActive = false;
506 return true;
507 }
508
509 vboxNetFltRetain((pNetFlt), true /* fBusy */);
510 vboxNetFltWinReferenceModeNetFlt(pNetFlt);
511 RTSpinlockRelease((pNetFlt)->hSpinlock, &Tmp);
512
513 *pbNetFltActive = true;
514 return true;
515}
516#endif
517
518#ifdef VBOX_NETFLT_ONDEMAND_BIND
519DECLINLINE(PVBOXNETFLTINS) vboxNetFltWinIncReferenceAdaptNetFltFromAdapt(PADAPT pAdapt, uint32_t v)
520{
521 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
522 PVBOXNETFLTINS pNetFlt;
523 uint32_t i;
524
525 Assert(v);
526 if(!v)
527 {
528 return NULL;
529 }
530
531 pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
532
533 RTSpinlockAcquire((pNetFlt)->hSpinlock, &Tmp);
534 if(!ASMAtomicUoReadBool(&(pNetFlt)->fActive))
535 {
536 RTSpinlockRelease((pNetFlt)->hSpinlock, &Tmp);
537 return NULL;
538 }
539
540 if(!vboxNetFltWinDoIncReferenceDevice(pAdapt, &pAdapt->PTState, v))
541 {
542 RTSpinlockRelease((pNetFlt)->hSpinlock, &Tmp);
543 return NULL;
544 }
545
546 vboxNetFltRetain((pNetFlt), true /* fBusy */);
547
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 return pNetFlt;
557}
558#else
559DECLINLINE(bool) vboxNetFltWinIncReferenceAdaptNetFlt(PVBOXNETFLTINS pNetFlt, PADAPT pAdapt, uint32_t v, bool *pbNetFltActive)
560{
561 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
562 uint32_t i;
563
564 Assert(v);
565 if(!v)
566 {
567 *pbNetFltActive = false;
568 return false;
569 }
570
571 RTSpinlockAcquire((pNetFlt)->hSpinlock, &Tmp);
572#ifndef VBOXNETADP
573 if(!vboxNetFltWinDoIncReferenceDevices(pAdapt, &pAdapt->MPState, &pAdapt->PTState, v))
574#else
575 if(!vboxNetFltWinDoIncReferenceDevice(pAdapt, &pAdapt->MPState, v))
576#endif
577 {
578 RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
579 *pbNetFltActive = false;
580 return false;
581 }
582
583 if(!ASMAtomicUoReadBool(&(pNetFlt)->fActive))
584 {
585 vboxNetFltWinIncReferenceModePassThru(pNetFlt, v);
586
587 RTSpinlockRelease((pNetFlt)->hSpinlock, &Tmp);
588 *pbNetFltActive = false;
589 return true;
590 }
591
592 vboxNetFltRetain(pNetFlt, true /* fBusy */);
593
594 vboxNetFltWinIncReferenceModeNetFlt(pNetFlt, v);
595
596 RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
597
598 /* we have marked it as busy, so can do the res references outside the lock */
599 for(i = 0; i < v-1; i++)
600 {
601 vboxNetFltRetain(pNetFlt, true /* fBusy */);
602 }
603
604 *pbNetFltActive = true;
605
606 return true;
607}
608
609#endif
610
611DECLINLINE(void) vboxNetFltWinDecReferenceNetFlt(PVBOXNETFLTINS pNetFlt, uint32_t n)
612{
613 uint32_t i;
614 for(i = 0; i < n; i++)
615 {
616 vboxNetFltRelease(pNetFlt, true);
617 }
618
619 vboxNetFltWinDecReferenceModeNetFlt(pNetFlt, n);
620}
621
622DECLINLINE(void) vboxNetFltWinDereferenceNetFlt(PVBOXNETFLTINS pNetFlt)
623{
624 vboxNetFltRelease(pNetFlt, true);
625
626 vboxNetFltWinDereferenceModeNetFlt(pNetFlt);
627}
628
629DECLINLINE(void) vboxNetFltWinDecReferenceAdapt(PADAPT pAdapt, uint32_t v)
630{
631#ifdef VBOX_NETFLT_ONDEMAND_BIND
632 vboxNetFltWinDecReferenceDevice(pAdapt, &pAdapt->PTState, v);
633#elif defined(VBOXNETADP)
634 vboxNetFltWinDecReferenceDevice(pAdapt, &pAdapt->MPState, v);
635#else
636 vboxNetFltWinDecReferenceDevices(pAdapt, &pAdapt->MPState, &pAdapt->PTState, v);
637#endif
638}
639
640DECLINLINE(void) vboxNetFltWinDereferenceAdapt(PADAPT pAdapt)
641{
642#ifdef VBOX_NETFLT_ONDEMAND_BIND
643 vboxNetFltWinDereferenceDevice(pAdapt, &pAdapt->PTState);
644#elif defined(VBOXNETADP)
645 vboxNetFltWinDereferenceDevice(pAdapt, &pAdapt->MPState);
646#else
647 vboxNetFltWinDereferenceDevices(pAdapt, &pAdapt->MPState, &pAdapt->PTState);
648#endif
649}
650
651DECLINLINE(bool) vboxNetFltWinIncReferenceAdapt(PADAPT pAdapt, uint32_t v)
652{
653 PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
654 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
655
656 Assert(v);
657 if(!v)
658 {
659 return false;
660 }
661
662 RTSpinlockAcquire(pNetFlt->hSpinlock, &Tmp);
663#ifdef VBOX_NETFLT_ONDEMAND_BIND
664 if(vboxNetFltWinDoIncReferenceDevice(pAdapt, &pAdapt->PTState))
665#elif defined(VBOXNETADP)
666 if(vboxNetFltWinDoIncReferenceDevice(pAdapt, &pAdapt->MPState, v))
667#else
668 if(vboxNetFltWinDoIncReferenceDevices(pAdapt, &pAdapt->MPState, &pAdapt->PTState, v))
669#endif
670 {
671 RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
672 return true;
673 }
674
675 RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
676 return false;
677}
678
679DECLINLINE(bool) vboxNetFltWinReferenceAdapt(PADAPT pAdapt)
680{
681 PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
682 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
683 RTSpinlockAcquire(pNetFlt->hSpinlock, &Tmp);
684#ifdef VBOX_NETFLT_ONDEMAND_BIND
685 if(vboxNetFltWinDoReferenceDevice(pAdapt, &pAdapt->PTState))
686#elif defined(VBOXNETADP)
687 if(vboxNetFltWinDoReferenceDevice(pAdapt, &pAdapt->MPState))
688#else
689 if(vboxNetFltWinDoReferenceDevices(pAdapt, &pAdapt->MPState, &pAdapt->PTState))
690#endif
691 {
692 RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
693 return true;
694 }
695
696 RTSpinlockRelease(pNetFlt->hSpinlock, &Tmp);
697 return false;
698}
699
700/***********************************************
701 * methods for accessing the network card info *
702 ***********************************************/
703
704DECLHIDDEN(NDIS_STATUS) vboxNetFltWinGetMacAddress(PADAPT pAdapt, PRTMAC pMac);
705DECLHIDDEN(bool) vboxNetFltWinIsPromiscuous(PADAPT pAdapt);
706DECLHIDDEN(NDIS_STATUS) vboxNetFltWinSetPromiscuous(PADAPT pAdapt, bool bYes);
707DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQueryPhysicalMedium(PADAPT pAdapt, NDIS_PHYSICAL_MEDIUM * pMedium);
708
709/*********************
710 * mem alloc API *
711 *********************/
712
713DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMemAlloc(PVOID* ppMemBuf, UINT cbLength);
714
715DECLHIDDEN(void) vboxNetFltWinMemFree(PVOID pMemBuf);
716
717/* convenience method used which allocates and initializes the PINTNETSG containing one
718 * segment refering the buffer of size cbBufSize
719 * the allocated PINTNETSG should be freed with the vboxNetFltWinMemFree.
720 *
721 * This is used when our ProtocolReceive callback is called and we have to return the indicated NDIS_PACKET
722 * on a callback exit. This is why we allocate the PINTNETSG and put the packet info there and enqueue it
723 * for the packet queue */
724DECLHIDDEN(NDIS_STATUS) vboxNetFltWinAllocSG(UINT cbBufSize, PINTNETSG *ppSG);
725
726/************************
727 * PADAPT init/fini API *
728 ************************/
729
730#if defined(VBOX_NETFLT_ONDEMAND_BIND)
731DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PADAPT pAdapt);
732#elif defined(VBOXNETADP)
733DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PADAPT *ppAdapt, NDIS_HANDLE hMiniportAdapter, PNDIS_STRING pBindToMiniportName /* actually this is our miniport name*/, NDIS_HANDLE hWrapperConfigurationContext);
734#else
735DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PADAPT *ppAdapt, PNDIS_STRING pOurMiniportName, PNDIS_STRING pBindToMiniportName);
736#endif
737
738#ifdef VBOX_NETFLT_ONDEMAND_BIND
739DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtAllocInitPADAPT(PADAPT pAdapt);
740#else
741DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtAllocInitPADAPT(PADAPT *ppAdapt, PNDIS_STRING pOurMiniportName, PNDIS_STRING pBindToMiniportName);
742#endif
743
744DECLHIDDEN(VOID) vboxNetFltWinPtFiniPADAPT(PADAPT pAdapt);
745#ifndef VBOXNETADP
746DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitPADAPT(IN PADAPT pAdapt, IN PNDIS_STRING pOurDeviceName);
747#else
748DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitPADAPT(IN PADAPT pAdapt);
749#endif
750
751/************************************
752 * Execute Job at passive level API *
753 ************************************/
754
755typedef VOID (*JOB_ROUTINE) (PVOID pContext);
756
757DECLHIDDEN(VOID) vboxNetFltWinJobSynchExecAtPassive(JOB_ROUTINE pRoutine, PVOID pContext);
758
759/*******************************
760 * Ndis Packets processing API *
761 *******************************/
762
763#ifndef NDIS_PACKET_FIRST_NDIS_BUFFER
764#define NDIS_PACKET_FIRST_NDIS_BUFFER(_Packet) ((_Packet)->Private.Head)
765#endif
766
767#ifndef NDIS_PACKET_LAST_NDIS_BUFFER
768#define NDIS_PACKET_LAST_NDIS_BUFFER(_Packet) ((_Packet)->Private.Tail)
769#endif
770
771#ifndef NDIS_PACKET_VALID_COUNTS
772#define NDIS_PACKET_VALID_COUNTS(_Packet) ((_Packet)->Private.ValidCounts)
773#endif
774
775
776DECLHIDDEN(PNDIS_PACKET) vboxNetFltWinNdisPacketFromSG(PADAPT pAdapt, PINTNETSG pSG, PVOID pBufToFree, bool bToWire, bool bCopyMemory);
777
778DECLHIDDEN(void) vboxNetFltWinFreeSGNdisPacket(PNDIS_PACKET pPacket, bool bFreeMem);
779
780#ifdef DEBUG_NETFLT_PACKETS
781DECLHIDDEN(bool) vboxNetFltWinMatchPacketAndSG(PNDIS_PACKET pPacket, PINTNETSG pSG, const INT cbMatch);
782
783DECLHIDDEN(bool) vboxNetFltWinMatchPackets(PNDIS_PACKET pPacket1, PNDIS_PACKET pPacket2, const INT cbMatch);
784
785#endif
786
787#ifdef DEBUG_NETFLT_PACKETS
788#define DBG_CHECK_PACKETS(_p1, _p2) \
789 { \
790 bool _b = vboxNetFltWinMatchPackets(_p1, _p2, -1); \
791 Assert(_b); \
792 }
793
794#define DBG_CHECK_PACKET_AND_SG(_p, _sg) \
795 { \
796 bool _b = vboxNetFltWinMatchPacketAndSG(_p, _sg, -1); \
797 Assert(_b); \
798 }
799
800#define DBG_CHECK_SGS(_sg1, _sg2) \
801 { \
802 bool _b = vboxNetFltWinMatchSGs(_sg1, _sg2, -1); \
803 Assert(_b); \
804 }
805
806#else
807#define DBG_CHECK_PACKETS(_p1, _p2)
808#define DBG_CHECK_PACKET_AND_SG(_p, _sg)
809#define DBG_CHECK_SGS(_sg1, _sg2)
810#endif
811
812/**
813 * Ndis loops back broadcast packets posted to the wire by IntNet
814 * This routine is used in the mechanism of preventing this looping
815 *
816 * @param pAdapt
817 * @param pPacket
818 * @param bOnRecv true is we are receiving the packet from the wire
819 * false otherwise (i.e. the packet is from the host)
820 *
821 * @return true if the packet is a looped back one, false otherwise
822 */
823#ifdef DEBUG_NETFLT_LOOPBACK
824# error "implement (see comments in the sources below this #error:)"
825 /* @todo FIXME no need for the PPACKET_INFO mechanism here;
826 instead the the NDIS_PACKET.ProtocolReserved + INTERLOCKED_SINGLE_LIST mechanism \
827 similar to that used in TrasferData handling should be used;
828 */
829
830//#ifdef VBOX_NETFLT_ONDEMAND_BIND
831//DECLHIDDEN(bool) vboxNetFltWinIsLoopedBackPacket(PADAPT pAdapt, PNDIS_PACKET pPacket);
832//#else
833//DECLHIDDEN(bool) vboxNetFltWinIsLoopedBackPacket(PADAPT pAdapt, PNDIS_PACKET pPacket, bool bOnRecv);
834//#endif
835//
836//#ifdef VBOX_NETFLT_ONDEMAND_BIND
837//DECLHIDDEN(bool) vboxNetFltWinIsLoopedBackPacketSG(PADAPT pAdapt, PINTNETSG pSG);
838//#else
839//DECLHIDDEN(bool) vboxNetFltWinIsLoopedBackPacketSG(PADAPT pAdapt, PINTNETSG pSG, bool bOnRecv);
840//#endif
841#else
842DECLINLINE(bool) vboxNetFltWinIsLoopedBackPacket(PNDIS_PACKET pPacket)
843{
844 return (NdisGetPacketFlags(pPacket) & g_fPacketIsLoopedBack) == g_fPacketIsLoopedBack;
845}
846#endif
847
848#if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP)
849
850/**************************************************************
851 * utility methofs for ndis packet creation/initialization *
852 **************************************************************/
853DECLINLINE(NDIS_STATUS) vboxNetFltWinCopyPacketInfoOnRecv(PNDIS_PACKET pDstPacket, PNDIS_PACKET pSrcPacket)
854{
855 NDIS_STATUS fStatus;
856
857 /*
858 * Get the original packet (it could be the same packet as the one
859 * received or a different one based on the number of layered miniports
860 * below) and set it on the indicated packet so the OOB data is visible
861 * correctly to protocols above us.
862 */
863 NDIS_SET_ORIGINAL_PACKET(pDstPacket, NDIS_GET_ORIGINAL_PACKET(pSrcPacket));
864
865 /*
866 * Set Packet Flags
867 */
868 NdisGetPacketFlags(pDstPacket) = NdisGetPacketFlags(pSrcPacket);
869
870 fStatus = NDIS_GET_PACKET_STATUS(pSrcPacket);
871
872 NDIS_SET_PACKET_STATUS(pDstPacket, fStatus);
873 NDIS_SET_PACKET_HEADER_SIZE(pDstPacket, NDIS_GET_PACKET_HEADER_SIZE(pSrcPacket));
874
875 return fStatus;
876}
877
878DECLINLINE(void) vboxNetFltWinCopyPacketInfoOnSend(PNDIS_PACKET pDstPacket, PNDIS_PACKET pSrcPacket)
879{
880 PVOID pMediaSpecificInfo = NULL;
881 UINT fMediaSpecificInfoSize = 0;
882
883 NdisGetPacketFlags(pDstPacket) = NdisGetPacketFlags(pSrcPacket);
884
885#ifdef WIN9X
886 /*
887 * Work around the fact that NDIS does not initialize this
888 * to FALSE on Win9x.
889 */
890 NDIS_PACKET_VALID_COUNTS(pDstPacket) = FALSE;
891#endif /* WIN9X */
892
893 /*
894 * Copy the OOB data from the original packet to the new
895 * packet.
896 */
897 NdisMoveMemory(NDIS_OOB_DATA_FROM_PACKET(pDstPacket),
898 NDIS_OOB_DATA_FROM_PACKET(pSrcPacket),
899 sizeof(NDIS_PACKET_OOB_DATA));
900 /*
901 * Copy relevant parts of the per packet info into the new packet
902 */
903#ifndef WIN9X
904 NdisIMCopySendPerPacketInfo(pDstPacket, pSrcPacket);
905#endif
906
907 /*
908 * Copy the Media specific information
909 */
910 NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO(pSrcPacket,
911 &pMediaSpecificInfo,
912 &fMediaSpecificInfoSize);
913
914 if (pMediaSpecificInfo || fMediaSpecificInfoSize)
915 {
916 NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO(pDstPacket,
917 pMediaSpecificInfo,
918 fMediaSpecificInfoSize);
919 }
920}
921
922DECLHIDDEN(NDIS_STATUS)
923vboxNetFltWinPrepareSendPacket(
924 IN PADAPT pAdapt,
925 IN PNDIS_PACKET pPacket,
926 OUT PNDIS_PACKET *ppMyPacket
927 /*, IN bool bNetFltActive*/
928 );
929
930
931DECLHIDDEN(NDIS_STATUS)
932vboxNetFltWinPrepareRecvPacket(
933 IN PADAPT pAdapt,
934 IN PNDIS_PACKET pPacket,
935 OUT PNDIS_PACKET *ppMyPacket,
936 IN bool bDpr
937 );
938#endif
939
940DECLHIDDEN(void) vboxNetFltWinSleep(ULONG milis);
941
942#define MACS_EQUAL(_m1, _m2) \
943 ((_m1).au16[0] == (_m2).au16[0] \
944 && (_m1).au16[1] == (_m2).au16[1] \
945 && (_m1).au16[2] == (_m2).au16[2])
946
947
948DECLHIDDEN(NDIS_STATUS) vboxNetFltWinDetachFromInterface(PADAPT pAdapt, bool bOnUnbind);
949DECLHIDDEN(NDIS_STATUS) vboxNetFltWinCopyString(PNDIS_STRING pDst, PNDIS_STRING pSrc);
950
951
952/**
953 * Sets the enmState member atomically.
954 *
955 * Used for all updates.
956 *
957 * @param pThis The instance.
958 * @param enmNewState The new value.
959 */
960DECLINLINE(void) vboxNetFltWinSetAdaptState(PADAPT pAdapt, VBOXADAPTSTATE enmNewState)
961{
962 ASMAtomicWriteU32((uint32_t volatile *)&pAdapt->enmState, enmNewState);
963}
964
965/**
966 * Gets the enmState member atomically.
967 *
968 * Used for all reads.
969 *
970 * @returns The enmState value.
971 * @param pThis The instance.
972 */
973DECLINLINE(VBOXADAPTSTATE) vboxNetFltWinGetAdaptState(PADAPT pAdapt)
974{
975 return (VBOXADAPTSTATE)ASMAtomicUoReadU32((uint32_t volatile *)&pAdapt->enmState);
976}
977
978
979#ifndef VBOXNETADP
980# define VBOXNETFLT_PROMISCUOUS_SUPPORTED(_pAdapt) \
981 (!PADAPT_2_PVBOXNETFLTINS(_pAdapt)->fDisablePromiscuous)
982// (!((_pAdapt)->PhMedium == NdisPhysicalMediumWirelessWan \
983// || (_pAdapt)->PhMedium == NdisPhysicalMediumWirelessLan \
984// || (_pAdapt)->PhMedium == NdisPhysicalMediumNative802_11 \
985// || (_pAdapt)->PhMedium == NdisPhysicalMediumBluetooth \
986// /*|| (_pAdapt)->PhMedium == NdisPhysicalMediumWiMax */ \
987// ))
988#else
989# define STATISTIC_INCREASE(_s) ASMAtomicIncU32((uint32_t volatile *)&(_s));
990
991DECLHIDDEN(void) vboxNetFltWinGenerateMACAddress(RTMAC *pMac);
992DECLHIDDEN(int) vboxNetFltWinMAC2NdisString(RTMAC *pMac, PNDIS_STRING pNdisString);
993DECLHIDDEN(int) vboxNetFltWinMACFromNdisString(RTMAC *pMac, PNDIS_STRING pNdisString);
994
995#endif
996#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