VirtualBox

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

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

Net[Flt,Adp]/win: export to OSE, disabled by default

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