VirtualBox

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

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

netflt-adp/win: additional bugfix

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