VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltP-win.cpp@ 36184

Last change on this file since 36184 was 36184, checked in by vboxsync, 14 years ago

rework NetFlt/Adp

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 57.0 KB
Line 
1/* $Id: VBoxNetFltP-win.cpp 36184 2011-03-07 10:57:04Z vboxsync $ */
2/** @file
3 * VBoxNetFltP-win.cpp - Bridged Networking Driver, Windows Specific Code.
4 * Protocol edge
5 */
6/*
7 * Copyright (C) 2011 Oracle Corporation
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#include "VBoxNetFltCmn-win.h"
18
19#ifdef VBOXNETADP
20# error "No protocol edge"
21#endif
22
23#define VBOXNETFLT_PT_STATUS_IS_FILTERED(_s) (\
24 (_s) == NDIS_STATUS_MEDIA_CONNECT \
25 || (_s) == NDIS_STATUS_MEDIA_DISCONNECT \
26 )
27
28/**
29 * performs binding to the given adapter
30 */
31DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtDoBinding(PVBOXNETFLTINS pThis, PNDIS_STRING pOurDeviceName, PNDIS_STRING pBindToDeviceName)
32{
33 Assert(pThis->u.s.WinIf.PtState.PowerState == NdisDeviceStateD3);
34 Assert(pThis->u.s.WinIf.PtState.OpState == kVBoxNetDevOpState_Deinitialized);
35 Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
36
37 vboxNetFltWinSetOpState(&pThis->u.s.WinIf.PtState, kVBoxNetDevOpState_Initializing);
38
39 NDIS_STATUS Status = vboxNetFltWinCopyString(&pThis->u.s.WinIf.MpDeviceName, pOurDeviceName);
40 Assert (Status == NDIS_STATUS_SUCCESS);
41 if (Status == NDIS_STATUS_SUCCESS)
42 {
43 vboxNetFltWinSetPowerState(&pThis->u.s.WinIf.PtState, NdisDeviceStateD0);
44 pThis->u.s.WinIf.OpenCloseStatus = NDIS_STATUS_SUCCESS;
45
46 UINT iMedium;
47 NDIS_STATUS TmpStatus;
48 NDIS_MEDIUM aenmNdisMedium[] =
49 {
50 /* Ethernet */
51 NdisMedium802_3,
52 /* Wan */
53 NdisMediumWan
54 };
55
56 NdisResetEvent(&pThis->u.s.WinIf.OpenCloseEvent);
57
58 NdisOpenAdapter(&Status, &TmpStatus, &pThis->u.s.WinIf.hBinding, &iMedium,
59 aenmNdisMedium, RT_ELEMENTS(aenmNdisMedium),
60 g_VBoxNetFltGlobalsWin.Pt.hProtocol,
61 pThis,
62 pBindToDeviceName,
63 0, /* IN UINT OpenOptions, (reserved, should be NULL) */
64 NULL /* IN PSTRING AddressingInformation OPTIONAL */
65 );
66 Assert(Status == NDIS_STATUS_PENDING || Status == STATUS_SUCCESS);
67 if (Status == NDIS_STATUS_PENDING)
68 {
69 NdisWaitEvent(&pThis->u.s.WinIf.OpenCloseEvent, 0);
70 Status = pThis->u.s.WinIf.OpenCloseStatus;
71 }
72
73 Assert(Status == NDIS_STATUS_SUCCESS);
74 if (Status == NDIS_STATUS_SUCCESS)
75 {
76 Assert(pThis->u.s.WinIf.hBinding);
77 pThis->u.s.WinIf.enmMedium = aenmNdisMedium[iMedium];
78 vboxNetFltWinSetOpState(&pThis->u.s.WinIf.PtState, kVBoxNetDevOpState_Initialized);
79
80 Status = vboxNetFltWinMpInitializeDevideInstance(pThis);
81 Assert(Status == NDIS_STATUS_SUCCESS);
82 if (Status == NDIS_STATUS_SUCCESS)
83 {
84 return NDIS_STATUS_SUCCESS;
85 }
86 else
87 {
88 LogRel((__FUNCTION__": vboxNetFltWinMpInitializeDevideInstance failed, Status 0x%x\n", Status));
89 }
90
91 vboxNetFltWinSetOpState(&pThis->u.s.WinIf.PtState, kVBoxNetDevOpState_Deinitializing);
92 vboxNetFltWinPtCloseInterface(pThis, &TmpStatus);
93 Assert(TmpStatus == NDIS_STATUS_SUCCESS);
94 vboxNetFltWinSetOpState(&pThis->u.s.WinIf.PtState, kVBoxNetDevOpState_Deinitialized);
95 }
96 else
97 {
98 LogRel((__FUNCTION__"NdisOpenAdapter failed, Status (0x%x)", Status));
99 }
100
101 vboxNetFltWinSetOpState(&pThis->u.s.WinIf.PtState, kVBoxNetDevOpState_Deinitialized);
102 pThis->u.s.WinIf.hBinding = NULL;
103 }
104
105 return Status;
106}
107
108static VOID vboxNetFltWinPtBindAdapter(OUT PNDIS_STATUS pStatus,
109 IN NDIS_HANDLE hBindContext,
110 IN PNDIS_STRING pDeviceNameStr,
111 IN PVOID pvSystemSpecific1,
112 IN PVOID pvSystemSpecific2)
113{
114 LogFlow(("==>"__FUNCTION__"\n"));
115
116 NDIS_STATUS Status;
117 NDIS_HANDLE hConfig = NULL;
118
119 NdisOpenProtocolConfiguration(&Status, &hConfig, (PNDIS_STRING)pvSystemSpecific1);
120 Assert(Status == NDIS_STATUS_SUCCESS);
121 if (Status == NDIS_STATUS_SUCCESS)
122 {
123 PNDIS_CONFIGURATION_PARAMETER pParam;
124 NDIS_STRING UppedBindStr = NDIS_STRING_CONST("UpperBindings");
125 NdisReadConfiguration(&Status, &pParam, hConfig, &UppedBindStr, NdisParameterString);
126 Assert(Status == NDIS_STATUS_SUCCESS);
127 if (Status == NDIS_STATUS_SUCCESS)
128 {
129 PVBOXNETFLTINS pNetFlt;
130 Status = vboxNetFltWinPtInitBind(&pNetFlt, &pParam->ParameterData.StringData, pDeviceNameStr);
131 Assert(Status == NDIS_STATUS_SUCCESS);
132 }
133
134 NdisCloseConfiguration(hConfig);
135 }
136
137 *pStatus = Status;
138
139 LogFlow(("<=="__FUNCTION__": Status 0x%x\n", Status));
140}
141
142static VOID vboxNetFltWinPtOpenAdapterComplete(IN NDIS_HANDLE hProtocolBindingContext, IN NDIS_STATUS Status, IN NDIS_STATUS OpenErrorStatus)
143{
144 PVBOXNETFLTINS pNetFlt =(PVBOXNETFLTINS)hProtocolBindingContext;
145
146 LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p), Status (0x%x), OpenErrorStatus(0x%x)\n", pNetFlt, Status, OpenErrorStatus));
147 Assert(pNetFlt->u.s.WinIf.OpenCloseStatus == NDIS_STATUS_SUCCESS);
148 Assert(Status == NDIS_STATUS_SUCCESS);
149 if (pNetFlt->u.s.WinIf.OpenCloseStatus == NDIS_STATUS_SUCCESS)
150 {
151 pNetFlt->u.s.WinIf.OpenCloseStatus = Status;
152 Assert(Status == NDIS_STATUS_SUCCESS);
153 if (Status != NDIS_STATUS_SUCCESS)
154 LogRel((__FUNCTION__" : Open Complete status is 0x%x", Status));
155 }
156 else
157 LogRel((__FUNCTION__" : Adapter maintained status is 0x%x", pNetFlt->u.s.WinIf.OpenCloseStatus));
158 NdisSetEvent(&pNetFlt->u.s.WinIf.OpenCloseEvent);
159 LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), Status (0x%x), OpenErrorStatus(0x%x)\n", pNetFlt, Status, OpenErrorStatus));
160}
161
162static void vboxNetFltWinPtRequestsWaitComplete(PVBOXNETFLTINS pNetFlt)
163{
164 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
165
166 /* wait for request to complete */
167 while (vboxNetFltWinAtomicUoReadWinState(pNetFlt->u.s.WinIf.StateFlags).fRequestInfo == VBOXNDISREQUEST_INPROGRESS)
168 {
169 vboxNetFltWinSleep(2);
170 }
171
172 /*
173 * If the below miniport is going to low power state, complete the queued request
174 */
175 RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
176 if (pNetFlt->u.s.WinIf.StateFlags.fRequestInfo & VBOXNDISREQUEST_QUEUED)
177 {
178 /* mark the request as InProgress before posting it to RequestComplete */
179 pNetFlt->u.s.WinIf.StateFlags.fRequestInfo = VBOXNDISREQUEST_INPROGRESS;
180 RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
181 vboxNetFltWinPtRequestComplete(pNetFlt, &pNetFlt->u.s.WinIf.PassDownRequest, NDIS_STATUS_FAILURE);
182 }
183 else
184 {
185 RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
186 }
187}
188
189DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtDoUnbinding(PVBOXNETFLTINS pNetFlt, bool bOnUnbind)
190{
191 NDIS_STATUS Status;
192 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
193 uint64_t NanoTS = RTTimeSystemNanoTS();
194 int cPPUsage;
195
196 LogFlow(("==>"__FUNCTION__": pNetFlt 0x%p\n", pNetFlt));
197
198 Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
199
200 Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.PtState) == kVBoxNetDevOpState_Initialized);
201
202 RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
203
204 ASMAtomicUoWriteBool(&pNetFlt->fDisconnectedFromHost, true);
205 ASMAtomicUoWriteBool(&pNetFlt->fRediscoveryPending, false);
206 ASMAtomicUoWriteU64(&pNetFlt->NanoTSLastRediscovery, NanoTS);
207
208 vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.PtState, kVBoxNetDevOpState_Deinitializing);
209 if (!bOnUnbind)
210 {
211 vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitializing);
212 }
213
214 RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
215
216 vboxNetFltWinPtRequestsWaitComplete(pNetFlt);
217
218 vboxNetFltWinWaitDereference(&pNetFlt->u.s.WinIf.MpState);
219 vboxNetFltWinWaitDereference(&pNetFlt->u.s.WinIf.PtState);
220
221 /* check packet pool is empty */
222 cPPUsage = NdisPacketPoolUsage(pNetFlt->u.s.WinIf.hSendPacketPool);
223 Assert(cPPUsage == 0);
224 cPPUsage = NdisPacketPoolUsage(pNetFlt->u.s.WinIf.hRecvPacketPool);
225 Assert(cPPUsage == 0);
226 /* for debugging only, ignore the err in release */
227 NOREF(cPPUsage);
228
229 if (!bOnUnbind || !vboxNetFltWinMpDeInitializeDeviceInstance(pNetFlt, &Status))
230 {
231 vboxNetFltWinPtCloseInterface(pNetFlt, &Status);
232 vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.PtState, kVBoxNetDevOpState_Deinitialized);
233
234 if (!bOnUnbind)
235 {
236 Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitializing);
237 vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized);
238 }
239 else
240 {
241 Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized);
242 }
243 }
244 else
245 {
246 Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized);
247 }
248
249 LogFlow(("<=="__FUNCTION__": pNetFlt 0x%p\n", pNetFlt));
250
251 return Status;
252}
253
254static VOID vboxNetFltWinPtUnbindAdapter(OUT PNDIS_STATUS pStatus,
255 IN NDIS_HANDLE hContext,
256 IN NDIS_HANDLE hUnbindContext)
257{
258 PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hContext;
259
260 LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p)\n", pNetFlt));
261
262 *pStatus = vboxNetFltWinDetachFromInterface(pNetFlt, true);
263 Assert(*pStatus == NDIS_STATUS_SUCCESS);
264
265 LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p)\n", pNetFlt));
266}
267
268static VOID vboxNetFltWinPtUnloadProtocol()
269{
270 LogFlow(("==>"__FUNCTION__"\n"));
271 NDIS_STATUS Status = vboxNetFltWinPtDeregister(&g_VBoxNetFltGlobalsWin.Pt);
272 Assert(Status == NDIS_STATUS_SUCCESS);
273 LogFlow(("<=="__FUNCTION__": PtDeregister Status (0x%x)\n", Status));
274}
275
276
277static VOID vboxNetFltWinPtCloseAdapterComplete(IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status)
278{
279 PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)ProtocolBindingContext;
280
281 LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p), Status (0x%x)\n", pNetFlt, Status));
282 Assert(pNetFlt->u.s.WinIf.OpenCloseStatus == NDIS_STATUS_SUCCESS);
283 Assert(Status == NDIS_STATUS_SUCCESS);
284 Assert(pNetFlt->u.s.WinIf.OpenCloseStatus == NDIS_STATUS_SUCCESS);
285 if (pNetFlt->u.s.WinIf.OpenCloseStatus == NDIS_STATUS_SUCCESS)
286 {
287 pNetFlt->u.s.WinIf.OpenCloseStatus = Status;
288 }
289 NdisSetEvent(&pNetFlt->u.s.WinIf.OpenCloseEvent);
290 LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p), Status (0x%x)\n", pNetFlt, Status));
291}
292
293static VOID vboxNetFltWinPtResetComplete(IN NDIS_HANDLE hProtocolBindingContext, IN NDIS_STATUS Status)
294{
295 LogFlow(("==>"__FUNCTION__" : pNetFlt 0x%p, Status 0x%x\n", hProtocolBindingContext, Status));
296 /*
297 * should never be here
298 */
299 Assert(0);
300 LogFlow(("<=="__FUNCTION__" : pNetFlt 0x%p, Status 0x%x\n", hProtocolBindingContext, Status));
301}
302
303static NDIS_STATUS vboxNetFltWinPtHandleQueryInfoComplete(PVBOXNETFLTINS pNetFlt, NDIS_STATUS Status)
304{
305 PNDIS_REQUEST pRequest = &pNetFlt->u.s.WinIf.PassDownRequest;
306
307 switch (pRequest->DATA.QUERY_INFORMATION.Oid)
308 {
309 case OID_PNP_CAPABILITIES:
310 {
311 if (Status == NDIS_STATUS_SUCCESS)
312 {
313 if (pRequest->DATA.QUERY_INFORMATION.InformationBufferLength >= sizeof (NDIS_PNP_CAPABILITIES))
314 {
315 PNDIS_PNP_CAPABILITIES pPnPCaps = (PNDIS_PNP_CAPABILITIES)(pRequest->DATA.QUERY_INFORMATION.InformationBuffer);
316 PNDIS_PM_WAKE_UP_CAPABILITIES pPmWuCaps = &pPnPCaps->WakeUpCapabilities;
317 pPmWuCaps->MinMagicPacketWakeUp = NdisDeviceStateUnspecified;
318 pPmWuCaps->MinPatternWakeUp = NdisDeviceStateUnspecified;
319 pPmWuCaps->MinLinkChangeWakeUp = NdisDeviceStateUnspecified;
320 *pNetFlt->u.s.WinIf.pcPDRBytesRW = sizeof (NDIS_PNP_CAPABILITIES);
321 *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = 0;
322 Status = NDIS_STATUS_SUCCESS;
323 }
324 else
325 {
326 Assert(0);
327 *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = sizeof(NDIS_PNP_CAPABILITIES);
328 Status = NDIS_STATUS_RESOURCES;
329 }
330 }
331 break;
332 }
333
334 case OID_GEN_MAC_OPTIONS:
335 {
336 if (Status == NDIS_STATUS_SUCCESS)
337 {
338 if (pRequest->DATA.QUERY_INFORMATION.InformationBufferLength >= sizeof (ULONG))
339 {
340 pNetFlt->u.s.WinIf.fMacOptions = *(PULONG)pRequest->DATA.QUERY_INFORMATION.InformationBuffer;
341#ifndef VBOX_LOOPBACK_USEFLAGS
342 /* clearing this flag tells ndis we'll handle loopback ourselves
343 * the ndis layer or nic driver below us would loopback packets as necessary */
344 *(PULONG)pRequest->DATA.QUERY_INFORMATION.InformationBuffer &= ~NDIS_MAC_OPTION_NO_LOOPBACK;
345#else
346 /* we have to catch loopbacks from the underlying driver, so no duplications will occur,
347 * just indicate NDIS to handle loopbacks for the packets coming from the protocol */
348 *(PULONG)pRequest->DATA.QUERY_INFORMATION.InformationBuffer |= NDIS_MAC_OPTION_NO_LOOPBACK;
349#endif
350 }
351 else
352 {
353 Assert(0);
354 *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = sizeof (ULONG);
355 Status = NDIS_STATUS_RESOURCES;
356 }
357 }
358 break;
359 }
360
361 case OID_GEN_CURRENT_PACKET_FILTER:
362 {
363 if (VBOXNETFLT_PROMISCUOUS_SUPPORTED(pNetFlt))
364 {
365 /* we're here _ONLY_ in the passthru mode */
366 Assert(pNetFlt->u.s.WinIf.StateFlags.fProcessingPacketFilter && !pNetFlt->u.s.WinIf.StateFlags.fPPFNetFlt);
367 if (pNetFlt->u.s.WinIf.StateFlags.fProcessingPacketFilter && !pNetFlt->u.s.WinIf.StateFlags.fPPFNetFlt)
368 {
369 Assert(pNetFlt->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE);
370 vboxNetFltWinDereferenceModePassThru(pNetFlt);
371 vboxNetFltWinDereferenceWinIf(pNetFlt);
372 }
373
374 if (Status == NDIS_STATUS_SUCCESS)
375 {
376 if (pRequest->DATA.QUERY_INFORMATION.InformationBufferLength >= sizeof (ULONG))
377 {
378 /* the filter request is issued below only in case netflt is not active,
379 * simply update the cache here */
380 /* cache the filter used by upper protocols */
381 pNetFlt->u.s.WinIf.fUpperProtocolSetFilter = *(PULONG)pRequest->DATA.QUERY_INFORMATION.InformationBuffer;
382 pNetFlt->u.s.WinIf.StateFlags.fUpperProtSetFilterInitialized = TRUE;
383 }
384 else
385 {
386 Assert(0);
387 *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = sizeof (ULONG);
388 Status = NDIS_STATUS_RESOURCES;
389 }
390 }
391 }
392 break;
393 }
394
395 default:
396 Assert(pRequest->DATA.QUERY_INFORMATION.Oid != OID_PNP_QUERY_POWER);
397 break;
398 }
399
400 *pNetFlt->u.s.WinIf.pcPDRBytesRW = pRequest->DATA.QUERY_INFORMATION.BytesWritten;
401 *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = pRequest->DATA.QUERY_INFORMATION.BytesNeeded;
402
403 return Status;
404}
405
406static NDIS_STATUS vboxNetFltWinPtHandleSetInfoComplete(PVBOXNETFLTINS pNetFlt, NDIS_STATUS Status)
407{
408 PNDIS_REQUEST pRequest = &pNetFlt->u.s.WinIf.PassDownRequest;
409
410 switch (pRequest->DATA.SET_INFORMATION.Oid)
411 {
412 case OID_GEN_CURRENT_PACKET_FILTER:
413 {
414 if (VBOXNETFLT_PROMISCUOUS_SUPPORTED(pNetFlt))
415 {
416 Assert(Status == NDIS_STATUS_SUCCESS);
417 if (pNetFlt->u.s.WinIf.StateFlags.fProcessingPacketFilter)
418 {
419 if (pNetFlt->u.s.WinIf.StateFlags.fPPFNetFlt)
420 {
421 Assert(pNetFlt->enmTrunkState == INTNETTRUNKIFSTATE_ACTIVE);
422 pNetFlt->u.s.WinIf.StateFlags.fPPFNetFlt = 0;
423 if (Status == NDIS_STATUS_SUCCESS)
424 {
425 if (pRequest->DATA.SET_INFORMATION.InformationBufferLength >= sizeof (ULONG))
426 {
427 pNetFlt->u.s.WinIf.fOurSetFilter = *((PULONG)pRequest->DATA.SET_INFORMATION.InformationBuffer);
428 Assert(pNetFlt->u.s.WinIf.fOurSetFilter == NDIS_PACKET_TYPE_PROMISCUOUS);
429 }
430 else
431 {
432 Assert(0);
433 *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = sizeof (ULONG);
434 Status = NDIS_STATUS_RESOURCES;
435 }
436 }
437 vboxNetFltWinDereferenceNetFlt(pNetFlt);
438 }
439 else
440 {
441 Assert(pNetFlt->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE);
442
443 if (Status == NDIS_STATUS_SUCCESS)
444 {
445 if (pRequest->DATA.SET_INFORMATION.InformationBufferLength >= sizeof (ULONG))
446 {
447 /* the request was issued when the netflt was not active, simply update the cache here */
448 pNetFlt->u.s.WinIf.fUpperProtocolSetFilter = *((PULONG)pRequest->DATA.SET_INFORMATION.InformationBuffer);
449 pNetFlt->u.s.WinIf.StateFlags.fUpperProtSetFilterInitialized = TRUE;
450 }
451 else
452 {
453 Assert(0);
454 *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = sizeof (ULONG);
455 Status = NDIS_STATUS_RESOURCES;
456 }
457 }
458 vboxNetFltWinDereferenceModePassThru(pNetFlt);
459 }
460
461 pNetFlt->u.s.WinIf.StateFlags.fProcessingPacketFilter = 0;
462 vboxNetFltWinDereferenceWinIf(pNetFlt);
463 }
464#ifdef DEBUG_misha
465 else
466 {
467 Assert(0);
468 }
469#endif
470 }
471 break;
472 }
473
474 default:
475 Assert(pRequest->DATA.SET_INFORMATION.Oid != OID_PNP_SET_POWER);
476 break;
477 }
478
479 *pNetFlt->u.s.WinIf.pcPDRBytesRW = pRequest->DATA.SET_INFORMATION.BytesRead;
480 *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = pRequest->DATA.SET_INFORMATION.BytesNeeded;
481
482 return Status;
483}
484
485DECLHIDDEN(VOID) vboxNetFltWinPtRequestComplete(NDIS_HANDLE hContext, PNDIS_REQUEST pNdisRequest, NDIS_STATUS Status)
486{
487 PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hContext;
488 PNDIS_REQUEST pSynchRequest = pNetFlt->u.s.WinIf.pSynchRequest;
489 NDIS_OID Oid = pNetFlt->u.s.WinIf.PassDownRequest.DATA.SET_INFORMATION.Oid;
490
491 LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p), pNdisRequest (0x%p), Status (0x%x)\n", pNetFlt, pNdisRequest, Status));
492
493 if (pSynchRequest == pNdisRequest)
494 {
495 /* asynchronous completion of our sync request */
496 /*1.set the status */
497 pNetFlt->u.s.WinIf.SynchCompletionStatus = Status;
498 /* 2. set event */
499 KeSetEvent(&pNetFlt->u.s.WinIf.hSynchCompletionEvent, 0, FALSE);
500 /* 3. return; */
501
502 LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p), pNdisRequest (0x%p), Status (0x%x)\n", pNetFlt, pNdisRequest, Status));
503 return;
504 }
505
506 Assert(&pNetFlt->u.s.WinIf.PassDownRequest == pNdisRequest);
507 Assert(pNetFlt->u.s.WinIf.StateFlags.fRequestInfo == VBOXNDISREQUEST_INPROGRESS);
508 vboxNetFltWinMpRequestStateComplete(pNetFlt);
509
510 switch (pNdisRequest->RequestType)
511 {
512 case NdisRequestQueryInformation:
513 Status = vboxNetFltWinPtHandleQueryInfoComplete(pNetFlt, Status);
514 NdisMQueryInformationComplete(pNetFlt->u.s.WinIf.hMiniport, Status);
515 break;
516
517 case NdisRequestSetInformation:
518 Status = vboxNetFltWinPtHandleSetInfoComplete(pNetFlt, Status);
519 NdisMSetInformationComplete(pNetFlt->u.s.WinIf.hMiniport, Status);
520 break;
521
522 default:
523 Assert(0);
524 break;
525 }
526
527 LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p), pNdisRequest (0x%p), Status (0x%x)\n", pNetFlt, pNdisRequest, Status));
528}
529
530static VOID vboxNetFltWinPtStatus(IN NDIS_HANDLE hProtocolBindingContext, IN NDIS_STATUS GeneralStatus, IN PVOID pvStatusBuffer, IN UINT cbStatusBuffer)
531{
532 PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext;
533
534 LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p), GeneralStatus (0x%x)\n", pNetFlt, GeneralStatus));
535
536 if (vboxNetFltWinReferenceWinIf(pNetFlt))
537 {
538 Assert(pNetFlt->u.s.WinIf.hMiniport);
539
540 if (VBOXNETFLT_PT_STATUS_IS_FILTERED(GeneralStatus))
541 {
542 pNetFlt->u.s.WinIf.MpIndicatedMediaStatus = GeneralStatus;
543 }
544 NdisMIndicateStatus(pNetFlt->u.s.WinIf.hMiniport,
545 GeneralStatus,
546 pvStatusBuffer,
547 cbStatusBuffer);
548
549 vboxNetFltWinDereferenceWinIf(pNetFlt);
550 }
551 else
552 {
553 if (pNetFlt->u.s.WinIf.hMiniport != NULL
554 && VBOXNETFLT_PT_STATUS_IS_FILTERED(GeneralStatus)
555 )
556 {
557 pNetFlt->u.s.WinIf.MpUnindicatedMediaStatus = GeneralStatus;
558 }
559 }
560
561 LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p), GeneralStatus (0x%x)\n", pNetFlt, GeneralStatus));
562}
563
564
565static VOID vboxNetFltWinPtStatusComplete(IN NDIS_HANDLE hProtocolBindingContext)
566{
567 PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext;
568
569 LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt));
570
571 if (vboxNetFltWinReferenceWinIf(pNetFlt))
572 {
573 NdisMIndicateStatusComplete(pNetFlt->u.s.WinIf.hMiniport);
574
575 vboxNetFltWinDereferenceWinIf(pNetFlt);
576 }
577
578 LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt));
579}
580
581static VOID vboxNetFltWinPtSendComplete(IN NDIS_HANDLE hProtocolBindingContext, IN PNDIS_PACKET pPacket, IN NDIS_STATUS Status)
582{
583 PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext;
584 PVBOXNETFLT_PKTRSVD_PT pSendInfo = (PVBOXNETFLT_PKTRSVD_PT)pPacket->ProtocolReserved;
585 PNDIS_PACKET pOrigPacket = pSendInfo->pOrigPacket;
586 PVOID pBufToFree = pSendInfo->pBufToFree;
587 LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p), pPacket (0x%p), Status (0x%x)\n", pNetFlt, pPacket, Status));
588
589#if defined(DEBUG_NETFLT_PACKETS) || !defined(VBOX_LOOPBACK_USEFLAGS)
590 /* @todo: for optimization we could check only for netflt-mode packets
591 * do it for all for now */
592 vboxNetFltWinLbRemoveSendPacket(pNetFlt, pPacket);
593#endif
594
595 if (pOrigPacket)
596 {
597 NdisIMCopySendCompletePerPacketInfo(pOrigPacket, pPacket);
598 NdisFreePacket(pPacket);
599 /* the ptk was posted from the upperlying protocol */
600 NdisMSendComplete(pNetFlt->u.s.WinIf.hMiniport, pOrigPacket, Status);
601 }
602 else
603 {
604 /* if the pOrigPacket is zero - the ptk was originated by netFlt send/receive
605 * need to free packet buffers */
606 vboxNetFltWinFreeSGNdisPacket(pPacket, !pBufToFree);
607 }
608
609 if (pBufToFree)
610 {
611 vboxNetFltWinMemFree(pBufToFree);
612 }
613
614 vboxNetFltWinDereferenceWinIf(pNetFlt);
615
616 LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), pPacket (0x%p), Status (0x%x)\n", pNetFlt, pPacket, Status));
617}
618
619/**
620 * removes searches for the packet in the list and removes it if found
621 * @return true if the packet was found and removed, false - otherwise
622 */
623static bool vboxNetFltWinRemovePacketFromList(PVBOXNETFLT_INTERLOCKED_SINGLE_LIST pList, PNDIS_PACKET pPacket)
624{
625 PVBOXNETFLT_PKTRSVD_TRANSFERDATA_PT pTDR = (PVBOXNETFLT_PKTRSVD_TRANSFERDATA_PT)pPacket->ProtocolReserved;
626 return vboxNetFltWinInterlockedSearchListEntry(pList, &pTDR->ListEntry, true /* remove*/);
627}
628
629/**
630 * puts the packet to the tail of the list
631 */
632static void vboxNetFltWinPutPacketToList(PVBOXNETFLT_INTERLOCKED_SINGLE_LIST pList, PNDIS_PACKET pPacket, PNDIS_BUFFER pOrigBuffer)
633{
634 PVBOXNETFLT_PKTRSVD_TRANSFERDATA_PT pTDR = (PVBOXNETFLT_PKTRSVD_TRANSFERDATA_PT)pPacket->ProtocolReserved;
635 pTDR->pOrigBuffer = pOrigBuffer;
636 vboxNetFltWinInterlockedPutTail(pList, &pTDR->ListEntry);
637}
638
639static bool vboxNetFltWinPtTransferDataCompleteActive(PVBOXNETFLTINS pNetFltIf, PNDIS_PACKET pPacket, NDIS_STATUS Status)
640{
641 PNDIS_BUFFER pBuffer;
642 PVBOXNETFLT_PKTRSVD_TRANSFERDATA_PT pTDR;
643
644 if (!vboxNetFltWinRemovePacketFromList(&pNetFltIf->u.s.WinIf.TransferDataList, pPacket))
645 return false;
646
647 pTDR = (PVBOXNETFLT_PKTRSVD_TRANSFERDATA_PT)pPacket->ProtocolReserved;
648 Assert(pTDR);
649 Assert(pTDR->pOrigBuffer);
650
651 do
652 {
653 NdisUnchainBufferAtFront(pPacket, &pBuffer);
654
655 Assert(pBuffer);
656
657 NdisFreeBuffer(pBuffer);
658
659 pBuffer = pTDR->pOrigBuffer;
660
661 NdisChainBufferAtBack(pPacket, pBuffer);
662
663 /* data transfer was initiated when the netFlt was active
664 * the netFlt is still retained by us
665 * 1. check if loopback
666 * 2. enqueue packet
667 * 3. release netFlt */
668
669 if (Status == NDIS_STATUS_SUCCESS)
670 {
671
672#ifdef VBOX_LOOPBACK_USEFLAGS
673 if (vboxNetFltWinIsLoopedBackPacket(pPacket))
674 {
675 /* should not be here */
676 Assert(0);
677 }
678#else
679 PNDIS_PACKET pLb = vboxNetFltWinLbSearchLoopBack(pNetFltIf, pPacket, false);
680 if (pLb)
681 {
682#ifndef DEBUG_NETFLT_RECV_TRANSFERDATA
683 /* should not be here */
684 Assert(0);
685#endif
686 if (!vboxNetFltWinLbIsFromIntNet(pLb))
687 {
688 /* the packet is not from int net, need to pass it up to the host */
689 NdisMIndicateReceivePacket(pNetFltIf->u.s.WinIf.hMiniport, &pPacket, 1);
690 /* dereference NetFlt, WinIf will be dereferenced on Packet return */
691 vboxNetFltWinDereferenceNetFlt(pNetFltIf);
692 break;
693 }
694 }
695#endif
696 else
697 {
698 /* 2. enqueue */
699 /* use the same packet info to put the packet in the processing packet queue */
700 PVBOXNETFLT_PKTRSVD_MP pRecvInfo = (PVBOXNETFLT_PKTRSVD_MP)pPacket->MiniportReserved;
701
702 VBOXNETFLT_LBVERIFY(pNetFltIf, pPacket);
703
704 pRecvInfo->pOrigPacket = NULL;
705 pRecvInfo->pBufToFree = NULL;
706
707 NdisGetPacketFlags(pPacket) = 0;
708# ifdef VBOXNETFLT_NO_PACKET_QUEUE
709 if (vboxNetFltWinPostIntnet(pNetFltIf, pPacket, 0))
710 {
711 /* drop it */
712 vboxNetFltWinFreeSGNdisPacket(pPacket, true);
713 vboxNetFltWinDereferenceWinIf(pNetFltIf);
714 }
715 else
716 {
717 NdisMIndicateReceivePacket(pNetFltIf->u.s.WinIf.hMiniport, &pPacket, 1);
718 }
719 vboxNetFltWinDereferenceNetFlt(pNetFltIf);
720 break;
721# else
722 Status = vboxNetFltWinQuEnqueuePacket(pNetFltIf, pPacket, PACKET_MINE);
723 if (Status == NDIS_STATUS_SUCCESS)
724 {
725 break;
726 }
727 Assert(0);
728# endif
729 }
730 }
731 else
732 {
733 Assert(0);
734 }
735 /* we are here because of error either in data transfer or in enqueueing the packet */
736 vboxNetFltWinFreeSGNdisPacket(pPacket, true);
737 vboxNetFltWinDereferenceNetFlt(pNetFltIf);
738 vboxNetFltWinDereferenceWinIf(pNetFltIf);
739 } while (0);
740
741 return true;
742}
743
744static VOID vboxNetFltWinPtTransferDataComplete(IN NDIS_HANDLE hProtocolBindingContext,
745 IN PNDIS_PACKET pPacket,
746 IN NDIS_STATUS Status,
747 IN UINT cbTransferred)
748{
749 PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext;
750 LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p), pPacket (0x%p), Status (0x%x), cbTransfered (%d)\n", pNetFlt, pPacket, Status, cbTransferred));
751 if (!vboxNetFltWinPtTransferDataCompleteActive(pNetFlt, pPacket, Status))
752 {
753 if (pNetFlt->u.s.WinIf.hMiniport)
754 {
755 NdisMTransferDataComplete(pNetFlt->u.s.WinIf.hMiniport,
756 pPacket,
757 Status,
758 cbTransferred);
759 }
760
761 vboxNetFltWinDereferenceWinIf(pNetFlt);
762 }
763 /* else - all processing is done with vboxNetFltWinPtTransferDataCompleteActive already */
764
765 LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), pPacket (0x%p), Status (0x%x), cbTransfered (%d)\n", pNetFlt, pPacket, Status, cbTransferred));
766}
767
768static INT vboxNetFltWinRecvPacketPassThru(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket, BOOLEAN bForceIndicate)
769{
770 Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
771
772 PNDIS_PACKET pMyPacket;
773 NDIS_STATUS Status = vboxNetFltWinPrepareRecvPacket(pNetFlt, pPacket, &pMyPacket, true);
774 /* the Status holds the current packet status it will be checked for NDIS_STATUS_RESOURCES later
775 * (see below) */
776 Assert(pMyPacket);
777 if (pMyPacket)
778 {
779 NdisMIndicateReceivePacket(pNetFlt->u.s.WinIf.hMiniport, &pMyPacket, 1);
780 if (Status == NDIS_STATUS_RESOURCES)
781 {
782 NdisDprFreePacket(pMyPacket);
783 return 0;
784 }
785
786 return 1;
787 }
788
789 return 0;
790}
791
792/**
793 * process the packet receive in a "passthru" mode
794 */
795static NDIS_STATUS vboxNetFltWinRecvPassThru(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket)
796{
797 Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
798
799 NDIS_STATUS Status;
800 PNDIS_PACKET pMyPacket;
801
802 NdisDprAllocatePacket(&Status, &pMyPacket, pNetFlt->u.s.WinIf.hRecvPacketPool);
803 Assert(Status == NDIS_STATUS_SUCCESS);
804 if (Status == NDIS_STATUS_SUCCESS)
805 {
806 vboxNetFltWinCopyPacketInfoOnRecv(pMyPacket, pPacket, true /* force NDIS_STATUS_RESOURCES */);
807 Assert(NDIS_GET_PACKET_STATUS(pMyPacket) == NDIS_STATUS_RESOURCES);
808
809 NdisMIndicateReceivePacket(pNetFlt->u.s.WinIf.hMiniport, &pMyPacket, 1);
810
811 NdisDprFreePacket(pMyPacket);
812 }
813 return Status;
814}
815
816static VOID vboxNetFltWinRecvIndicatePassThru(PVBOXNETFLTINS pNetFlt, NDIS_HANDLE MacReceiveContext,
817 PVOID pHeaderBuffer, UINT cbHeaderBuffer, PVOID pLookAheadBuffer, UINT cbLookAheadBuffer, UINT cbPacket)
818{
819 /* Note: we're using KeGetCurrentProcessorNumber, which is not entirely correct in case
820 * we're running on 64bit win7+, which can handle > 64 CPUs, however since KeGetCurrentProcessorNumber
821 * always returns the number < than the number of CPUs in the first group, we're guaranteed to have CPU index < 64
822 * @todo: use KeGetCurrentProcessorNumberEx for Win7+ 64 and dynamically extended array */
823 ULONG Proc = KeGetCurrentProcessorNumber();
824 Assert(Proc < RT_ELEMENTS(pNetFlt->u.s.WinIf.abIndicateRxComplete));
825 pNetFlt->u.s.WinIf.abIndicateRxComplete[Proc] = TRUE;
826 switch (pNetFlt->u.s.WinIf.enmMedium)
827 {
828 case NdisMedium802_3:
829 case NdisMediumWan:
830 NdisMEthIndicateReceive(pNetFlt->u.s.WinIf.hMiniport,
831 MacReceiveContext,
832 (PCHAR)pHeaderBuffer,
833 cbHeaderBuffer,
834 pLookAheadBuffer,
835 cbLookAheadBuffer,
836 cbPacket);
837 break;
838 default:
839 Assert(FALSE);
840 break;
841 }
842}
843
844/**
845 * process the ProtocolReceive in an "active" mode
846 *
847 * @return NDIS_STATUS_SUCCESS - the packet is processed
848 * NDIS_STATUS_PENDING - the packet is being processed, we are waiting for the ProtocolTransferDataComplete to be called
849 * NDIS_STATUS_NOT_ACCEPTED - the packet is not needed - typically this is because this is a loopback packet
850 * NDIS_STATUS_FAILURE - packet processing failed
851 */
852static NDIS_STATUS vboxNetFltWinPtReceiveActive(PVBOXNETFLTINS pNetFlt, NDIS_HANDLE MacReceiveContext, PVOID pHeaderBuffer, UINT cbHeaderBuffer,
853 PVOID pLookaheadBuffer, UINT cbLookaheadBuffer, UINT cbPacket)
854{
855 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
856
857 do
858 {
859 if (cbHeaderBuffer != VBOXNETFLT_PACKET_ETHEADER_SIZE)
860 {
861 Status = NDIS_STATUS_NOT_ACCEPTED;
862 break;
863 }
864
865#ifndef DEBUG_NETFLT_RECV_TRANSFERDATA
866 if (cbPacket == cbLookaheadBuffer)
867 {
868 PINTNETSG pSG;
869 PUCHAR pRcvData;
870#ifndef VBOX_LOOPBACK_USEFLAGS
871 PNDIS_PACKET pLb;
872#endif
873
874 /* allocate SG buffer */
875 Status = vboxNetFltWinAllocSG(cbPacket + cbHeaderBuffer, &pSG);
876 if (Status != NDIS_STATUS_SUCCESS)
877 {
878 Assert(0);
879 break;
880 }
881
882 pRcvData = (PUCHAR)pSG->aSegs[0].pv;
883
884 NdisMoveMappedMemory(pRcvData, pHeaderBuffer, cbHeaderBuffer);
885
886 NdisCopyLookaheadData(pRcvData+cbHeaderBuffer,
887 pLookaheadBuffer,
888 cbLookaheadBuffer,
889 pNetFlt->u.s.WinIf.fMacOptions);
890#ifndef VBOX_LOOPBACK_USEFLAGS
891 pLb = vboxNetFltWinLbSearchLoopBackBySG(pNetFlt, pSG, false);
892 if (pLb)
893 {
894#ifndef DEBUG_NETFLT_RECV_NOPACKET
895 /* should not be here */
896 Assert(0);
897#endif
898 if (!vboxNetFltWinLbIsFromIntNet(pLb))
899 {
900 PNDIS_PACKET pMyPacket;
901 pMyPacket = vboxNetFltWinNdisPacketFromSG(pNetFlt, /* PVBOXNETFLTINS */
902 pSG, /* PINTNETSG */
903 pSG, /* PVOID pBufToFree */
904 false, /* bool bToWire */
905 false); /* bool bCopyMemory */
906 if (pMyPacket)
907 {
908 NdisMIndicateReceivePacket(pNetFlt->u.s.WinIf.hMiniport, &pMyPacket, 1);
909 /* dereference the NetFlt here & indicate SUCCESS, which would mean the caller would not do a dereference
910 * the WinIf dereference will be done on packet return */
911 vboxNetFltWinDereferenceNetFlt(pNetFlt);
912 Status = NDIS_STATUS_SUCCESS;
913 }
914 else
915 {
916 vboxNetFltWinMemFree(pSG);
917 Status = NDIS_STATUS_FAILURE;
918 }
919 }
920 else
921 {
922 vboxNetFltWinMemFree(pSG);
923 Status = NDIS_STATUS_NOT_ACCEPTED;
924 }
925 break;
926 }
927#endif
928 VBOXNETFLT_LBVERIFYSG(pNetFlt, pSG);
929
930 /* enqueue SG */
931# ifdef VBOXNETFLT_NO_PACKET_QUEUE
932 if (vboxNetFltWinPostIntnet(pNetFlt, pSG, VBOXNETFLT_PACKET_SG))
933 {
934 /* drop it */
935 vboxNetFltWinMemFree(pSG);
936 vboxNetFltWinDereferenceWinIf(pNetFlt);
937 }
938 else
939 {
940 PNDIS_PACKET pMyPacket = vboxNetFltWinNdisPacketFromSG(pNetFlt, /* PVBOXNETFLTINS */
941 pSG, /* PINTNETSG */
942 pSG, /* PVOID pBufToFree */
943 false, /* bool bToWire */
944 false); /* bool bCopyMemory */
945 Assert(pMyPacket);
946 if (pMyPacket)
947 {
948 NDIS_SET_PACKET_STATUS(pMyPacket, NDIS_STATUS_SUCCESS);
949
950 DBG_CHECK_PACKET_AND_SG(pMyPacket, pSG);
951
952 LogFlow(("non-ndis packet info, packet created (%p)\n", pMyPacket));
953 NdisMIndicateReceivePacket(pNetFlt->u.s.WinIf.hMiniport, &pMyPacket, 1);
954 }
955 else
956 {
957 vboxNetFltWinDereferenceWinIf(pNetFlt);
958 Status = NDIS_STATUS_RESOURCES;
959 }
960 }
961 vboxNetFltWinDereferenceNetFlt(pNetFlt);
962# else
963 Status = vboxNetFltWinQuEnqueuePacket(pNetFlt, pSG, PACKET_SG | PACKET_MINE);
964 if (Status != NDIS_STATUS_SUCCESS)
965 {
966 Assert(0);
967 vboxNetFltWinMemFree(pSG);
968 break;
969 }
970# endif
971#endif
972 }
973 else
974 {
975 PNDIS_PACKET pPacket;
976 PNDIS_BUFFER pTransferBuffer;
977 PNDIS_BUFFER pOrigBuffer;
978 PUCHAR pMemBuf;
979 UINT cbBuf = cbPacket + cbHeaderBuffer;
980 UINT cbTransferred;
981
982 /* allocate NDIS Packet buffer */
983 NdisAllocatePacket(&Status, &pPacket, pNetFlt->u.s.WinIf.hRecvPacketPool);
984 if (Status != NDIS_STATUS_SUCCESS)
985 {
986 Assert(0);
987 break;
988 }
989
990 VBOXNETFLT_OOB_INIT(pPacket);
991
992#ifdef VBOX_LOOPBACK_USEFLAGS
993 /* set "don't loopback" flags */
994 NdisGetPacketFlags(pPacket) = g_VBoxNetFltGlobalsWin.fPacketDontLoopBack;
995#else
996 NdisGetPacketFlags(pPacket) = 0;
997#endif
998
999 Status = vboxNetFltWinMemAlloc((PVOID*)(&pMemBuf), cbBuf);
1000 if (Status != NDIS_STATUS_SUCCESS)
1001 {
1002 Assert(0);
1003 NdisFreePacket(pPacket);
1004 break;
1005 }
1006 NdisAllocateBuffer(&Status, &pTransferBuffer, pNetFlt->u.s.WinIf.hRecvBufferPool, pMemBuf + cbHeaderBuffer, cbPacket);
1007 if (Status != NDIS_STATUS_SUCCESS)
1008 {
1009 Assert(0);
1010 Status = NDIS_STATUS_FAILURE;
1011 NdisFreePacket(pPacket);
1012 vboxNetFltWinMemFree(pMemBuf);
1013 break;
1014 }
1015
1016 NdisAllocateBuffer(&Status, &pOrigBuffer, pNetFlt->u.s.WinIf.hRecvBufferPool, pMemBuf, cbBuf);
1017 if (Status != NDIS_STATUS_SUCCESS)
1018 {
1019 Assert(0);
1020 Status = NDIS_STATUS_FAILURE;
1021 NdisFreeBuffer(pTransferBuffer);
1022 NdisFreePacket(pPacket);
1023 vboxNetFltWinMemFree(pMemBuf);
1024 break;
1025 }
1026
1027 NdisChainBufferAtBack(pPacket, pTransferBuffer);
1028
1029 NdisMoveMappedMemory(pMemBuf, pHeaderBuffer, cbHeaderBuffer);
1030
1031 vboxNetFltWinPutPacketToList(&pNetFlt->u.s.WinIf.TransferDataList, pPacket, pOrigBuffer);
1032
1033#ifdef DEBUG_NETFLT_RECV_TRANSFERDATA
1034 if (cbPacket == cbLookaheadBuffer)
1035 {
1036 NdisCopyLookaheadData(pMemBuf+cbHeaderBuffer,
1037 pLookaheadBuffer,
1038 cbLookaheadBuffer,
1039 pNetFlt->u.s.WinIf.fMacOptions);
1040 }
1041 else
1042#endif
1043 {
1044 Assert(cbPacket > cbLookaheadBuffer);
1045
1046 NdisTransferData(&Status, pNetFlt->u.s.WinIf.hBinding, MacReceiveContext,
1047 0, /* ByteOffset */
1048 cbPacket, pPacket, &cbTransferred);
1049 }
1050
1051 if (Status != NDIS_STATUS_PENDING)
1052 {
1053 vboxNetFltWinPtTransferDataComplete(pNetFlt, pPacket, Status, cbTransferred);
1054 }
1055 }
1056 } while (0);
1057
1058 return Status;
1059}
1060
1061static NDIS_STATUS vboxNetFltWinPtReceive(IN NDIS_HANDLE hProtocolBindingContext,
1062 IN NDIS_HANDLE MacReceiveContext,
1063 IN PVOID pHeaderBuffer,
1064 IN UINT cbHeaderBuffer,
1065 IN PVOID pLookAheadBuffer,
1066 IN UINT cbLookAheadBuffer,
1067 IN UINT cbPacket)
1068{
1069 PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext;
1070 PNDIS_PACKET pPacket = NULL;
1071 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
1072 bool bNetFltActive;
1073 bool fWinIfActive = vboxNetFltWinReferenceWinIfNetFlt(pNetFlt, &bNetFltActive);
1074 const bool bPassThruActive = !bNetFltActive;
1075
1076 LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt));
1077
1078 if (fWinIfActive)
1079 {
1080 do
1081 {
1082#ifndef DEBUG_NETFLT_RECV_NOPACKET
1083 pPacket = NdisGetReceivedPacket(pNetFlt->u.s.WinIf.hBinding, MacReceiveContext);
1084 if (pPacket)
1085 {
1086# ifndef VBOX_LOOPBACK_USEFLAGS
1087 PNDIS_PACKET pLb = NULL;
1088# else
1089 if (vboxNetFltWinIsLoopedBackPacket(pPacket))
1090 {
1091 Assert(0);
1092 /* nothing else to do here, just return the packet */
1093 //NdisReturnPackets(&pPacket, 1);
1094 Status = NDIS_STATUS_NOT_ACCEPTED;
1095 break;
1096 }
1097
1098 VBOXNETFLT_LBVERIFY(pNetFlt, pPacket);
1099# endif
1100
1101 if (bNetFltActive)
1102 {
1103# ifndef VBOX_LOOPBACK_USEFLAGS
1104 pLb = vboxNetFltWinLbSearchLoopBack(pNetFlt, pPacket, false);
1105 if (!pLb)
1106# endif
1107 {
1108 VBOXNETFLT_LBVERIFY(pNetFlt, pPacket);
1109
1110# ifdef VBOXNETFLT_NO_PACKET_QUEUE
1111 if (vboxNetFltWinPostIntnet(pNetFlt, pPacket, 0))
1112 {
1113 /* drop it */
1114 break;
1115 }
1116# else
1117 Status = vboxNetFltWinQuEnqueuePacket(pNetFlt, pPacket, PACKET_COPY);
1118 Assert(Status == NDIS_STATUS_SUCCESS);
1119 if (Status == NDIS_STATUS_SUCCESS)
1120 {
1121 //NdisReturnPackets(&pPacket, 1);
1122 fWinIfActive = false;
1123 bNetFltActive = false;
1124 break;
1125 }
1126# endif
1127 }
1128# ifndef VBOX_LOOPBACK_USEFLAGS
1129 else if (vboxNetFltWinLbIsFromIntNet(pLb))
1130 {
1131 /* nothing else to do here, just return the packet */
1132 //NdisReturnPackets(&pPacket, 1);
1133 Status = NDIS_STATUS_NOT_ACCEPTED;
1134 break;
1135 }
1136 /* we are here because this is a looped back packet set not from intnet
1137 * we will post it to the upper protocol */
1138# endif
1139 }
1140
1141 Assert(Status == STATUS_SUCCESS);
1142 if (Status == STATUS_SUCCESS)
1143 {
1144# ifndef VBOX_LOOPBACK_USEFLAGS
1145 Assert(!pLb || !vboxNetFltWinLbIsFromIntNet(pLb));
1146# endif
1147 Status = vboxNetFltWinRecvPassThru(pNetFlt, pPacket);
1148 Assert(Status == STATUS_SUCCESS);
1149 /* we are done with packet processing, and we will
1150 * not receive packet return event for this packet,
1151 * fWinIfActive should be true to ensure we release WinIf*/
1152 Assert(fWinIfActive);
1153 if (Status == STATUS_SUCCESS)
1154 break;
1155 }
1156 else
1157 {
1158 /* intnet processing failed - fall back to no-packet mode */
1159 Assert(bNetFltActive);
1160 Assert(fWinIfActive);
1161 }
1162
1163 }
1164#endif /* #ifndef DEBUG_NETFLT_RECV_NOPACKET */
1165
1166 if (bNetFltActive)
1167 {
1168 Status = vboxNetFltWinPtReceiveActive(pNetFlt, MacReceiveContext, pHeaderBuffer, cbHeaderBuffer,
1169 pLookAheadBuffer, cbLookAheadBuffer, cbPacket);
1170 if (NT_SUCCESS(Status))
1171 {
1172 if (Status != NDIS_STATUS_NOT_ACCEPTED)
1173 {
1174 fWinIfActive = false;
1175 bNetFltActive = false;
1176 }
1177 else
1178 {
1179#ifndef VBOX_LOOPBACK_USEFLAGS
1180 /* this is a loopback packet, nothing to do here */
1181#else
1182 Assert(0);
1183 /* should not be here */
1184#endif
1185 }
1186 break;
1187 }
1188 }
1189
1190 /* we are done with packet processing, and we will
1191 * not receive packet return event for this packet,
1192 * fWinIfActive should be true to ensure we release WinIf*/
1193 Assert(fWinIfActive);
1194
1195 vboxNetFltWinRecvIndicatePassThru(pNetFlt, MacReceiveContext, pHeaderBuffer, cbHeaderBuffer, pLookAheadBuffer, cbLookAheadBuffer, cbPacket);
1196 /* the status could contain an error value here in case the the IntNet recv failed,
1197 * ensure we return back success status */
1198 Status = NDIS_STATUS_SUCCESS;
1199
1200 } while (0);
1201
1202 if (bNetFltActive)
1203 {
1204 vboxNetFltWinDereferenceNetFlt(pNetFlt);
1205 }
1206 else if (bPassThruActive)
1207 {
1208 vboxNetFltWinDereferenceModePassThru(pNetFlt);
1209 }
1210 if (fWinIfActive)
1211 {
1212 vboxNetFltWinDereferenceWinIf(pNetFlt);
1213 }
1214 }
1215 else
1216 {
1217 Status = NDIS_STATUS_FAILURE;
1218 }
1219
1220 LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt));
1221
1222 return Status;
1223
1224}
1225
1226static VOID vboxNetFltWinPtReceiveComplete(NDIS_HANDLE hProtocolBindingContext)
1227{
1228 PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext;
1229 ULONG cPackets = 0;
1230 bool bNetFltActive;
1231 bool fWinIfActive = vboxNetFltWinReferenceWinIfNetFlt(pNetFlt, &bNetFltActive);
1232 NDIS_HANDLE hMiniport = pNetFlt->u.s.WinIf.hMiniport;
1233 /* Note: we're using KeGetCurrentProcessorNumber, which is not entirely correct in case
1234 * we're running on 64bit win7+, which can handle > 64 CPUs, however since KeGetCurrentProcessorNumber
1235 * always returns the number < than the number of CPUs in the first group, we're guaranteed to have CPU index < 64
1236 * @todo: use KeGetCurrentProcessorNumberEx for Win7+ 64 and dynamically extended array */
1237 ULONG iProc = KeGetCurrentProcessorNumber();
1238 Assert(iProc < RT_ELEMENTS(pNetFlt->u.s.WinIf.abIndicateRxComplete));
1239
1240 LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt));
1241
1242 if (hMiniport != NULL && pNetFlt->u.s.WinIf.abIndicateRxComplete[iProc])
1243 {
1244 switch (pNetFlt->u.s.WinIf.enmMedium)
1245 {
1246 case NdisMedium802_3:
1247 case NdisMediumWan:
1248 NdisMEthIndicateReceiveComplete(hMiniport);
1249 break;
1250 default:
1251 Assert(0);
1252 break;
1253 }
1254 }
1255
1256 pNetFlt->u.s.WinIf.abIndicateRxComplete[iProc] = FALSE;
1257
1258 if (fWinIfActive)
1259 {
1260 if (bNetFltActive)
1261 {
1262 vboxNetFltWinDereferenceNetFlt(pNetFlt);
1263 }
1264 else
1265 {
1266 vboxNetFltWinDereferenceModePassThru(pNetFlt);
1267 }
1268 vboxNetFltWinDereferenceWinIf(pNetFlt);
1269 }
1270
1271 LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt));
1272}
1273
1274static INT vboxNetFltWinPtReceivePacket(NDIS_HANDLE hProtocolBindingContext, PNDIS_PACKET pPacket)
1275{
1276 PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext;
1277 INT cRefCount = 0;
1278 bool bNetFltActive;
1279 bool fWinIfActive = vboxNetFltWinReferenceWinIfNetFlt(pNetFlt, &bNetFltActive);
1280 const bool bPassThruActive = !bNetFltActive;
1281
1282 LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt));
1283
1284 if (fWinIfActive)
1285 {
1286 do
1287 {
1288#ifdef VBOX_LOOPBACK_USEFLAGS
1289 if (vboxNetFltWinIsLoopedBackPacket(pPacket))
1290 {
1291 Assert(0);
1292 Log(("lb_rp"));
1293
1294 /* nothing else to do here, just return the packet */
1295 cRefCount = 0;
1296 //NdisReturnPackets(&pPacket, 1);
1297 break;
1298 }
1299
1300 VBOXNETFLT_LBVERIFY(pNetFlt, pPacket);
1301#endif
1302
1303 if (bNetFltActive)
1304 {
1305#ifndef VBOX_LOOPBACK_USEFLAGS
1306 PNDIS_PACKET pLb = vboxNetFltWinLbSearchLoopBack(pNetFlt, pPacket, false);
1307 if (!pLb)
1308#endif
1309 {
1310#ifndef VBOXNETFLT_NO_PACKET_QUEUE
1311 NDIS_STATUS fStatus;
1312#endif
1313 bool bResources = NDIS_GET_PACKET_STATUS(pPacket) == NDIS_STATUS_RESOURCES;
1314
1315 VBOXNETFLT_LBVERIFY(pNetFlt, pPacket);
1316#ifdef DEBUG_misha
1317 /*TODO: remove this assert.
1318 * this is a temporary assert for debugging purposes:
1319 * we're probably doing something wrong with the packets if the miniport reports NDIS_STATUS_RESOURCES */
1320 Assert(!bResources);
1321#endif
1322
1323#ifdef VBOXNETFLT_NO_PACKET_QUEUE
1324 if (vboxNetFltWinPostIntnet(pNetFlt, pPacket, 0))
1325 {
1326 /* drop it */
1327 cRefCount = 0;
1328 break;
1329 }
1330
1331#else
1332 fStatus = vboxNetFltWinQuEnqueuePacket(pNetFlt, pPacket, bResources ? PACKET_COPY : 0);
1333 if (fStatus == NDIS_STATUS_SUCCESS)
1334 {
1335 bNetFltActive = false;
1336 fWinIfActive = false;
1337 if (bResources)
1338 {
1339 cRefCount = 0;
1340 //NdisReturnPackets(&pPacket, 1);
1341 }
1342 else
1343 {
1344 cRefCount = 1;
1345 }
1346 break;
1347 }
1348 else
1349 {
1350 Assert(0);
1351 }
1352#endif
1353 }
1354#ifndef VBOX_LOOPBACK_USEFLAGS
1355 else if (vboxNetFltWinLbIsFromIntNet(pLb))
1356 {
1357 /* the packet is from intnet, it has already been set to the host,
1358 * no need for loopng it back to the host again */
1359 /* nothing else to do here, just return the packet */
1360 cRefCount = 0;
1361 //NdisReturnPackets(&pPacket, 1);
1362 break;
1363 }
1364#endif
1365 }
1366
1367 cRefCount = vboxNetFltWinRecvPacketPassThru(pNetFlt, pPacket, bNetFltActive);
1368 if (cRefCount)
1369 {
1370 Assert(cRefCount == 1);
1371 fWinIfActive = false;
1372 }
1373
1374 } while (FALSE);
1375
1376 if (bNetFltActive)
1377 {
1378 vboxNetFltWinDereferenceNetFlt(pNetFlt);
1379 }
1380 else if (bPassThruActive)
1381 {
1382 vboxNetFltWinDereferenceModePassThru(pNetFlt);
1383 }
1384 if (fWinIfActive)
1385 {
1386 vboxNetFltWinDereferenceWinIf(pNetFlt);
1387 }
1388 }
1389 else
1390 {
1391 cRefCount = 0;
1392 //NdisReturnPackets(&pPacket, 1);
1393 }
1394
1395 LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p), cRefCount (%d)\n", pNetFlt, cRefCount));
1396
1397 return cRefCount;
1398}
1399
1400DECLHIDDEN(bool) vboxNetFltWinPtCloseInterface(PVBOXNETFLTINS pNetFlt, PNDIS_STATUS pStatus)
1401{
1402 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
1403
1404 RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
1405
1406 if (pNetFlt->u.s.WinIf.StateFlags.fInterfaceClosing)
1407 {
1408 RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
1409 Assert(0);
1410 return false;
1411 }
1412 if (pNetFlt->u.s.WinIf.hBinding == NULL)
1413 {
1414 RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
1415 Assert(0);
1416 return false;
1417 }
1418
1419 pNetFlt->u.s.WinIf.StateFlags.fInterfaceClosing = TRUE;
1420 RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
1421
1422 NdisResetEvent(&pNetFlt->u.s.WinIf.OpenCloseEvent);
1423 NdisCloseAdapter(pStatus, pNetFlt->u.s.WinIf.hBinding);
1424 if (*pStatus == NDIS_STATUS_PENDING)
1425 {
1426 NdisWaitEvent(&pNetFlt->u.s.WinIf.OpenCloseEvent, 0);
1427 *pStatus = pNetFlt->u.s.WinIf.OpenCloseStatus;
1428 }
1429
1430 Assert (*pStatus == NDIS_STATUS_SUCCESS);
1431
1432 pNetFlt->u.s.WinIf.hBinding = NULL;
1433
1434 return true;
1435}
1436
1437static NDIS_STATUS vboxNetFltWinPtPnPSetPower(PVBOXNETFLTINS pNetFlt, NDIS_DEVICE_POWER_STATE enmPowerState)
1438{
1439 NDIS_DEVICE_POWER_STATE enmPrevPowerState = vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.PtState);
1440 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
1441
1442 RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp);
1443
1444 vboxNetFltWinSetPowerState(&pNetFlt->u.s.WinIf.PtState, enmPowerState);
1445
1446 if (vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.PtState) > NdisDeviceStateD0)
1447 {
1448 if (enmPrevPowerState == NdisDeviceStateD0)
1449 {
1450 pNetFlt->u.s.WinIf.StateFlags.fStandBy = TRUE;
1451 }
1452 RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
1453 vboxNetFltWinPtRequestsWaitComplete(pNetFlt);
1454 vboxNetFltWinWaitDereference(&pNetFlt->u.s.WinIf.MpState);
1455 vboxNetFltWinWaitDereference(&pNetFlt->u.s.WinIf.PtState);
1456
1457 /* check packet pool is empty */
1458 UINT cPPUsage = NdisPacketPoolUsage(pNetFlt->u.s.WinIf.hSendPacketPool);
1459 Assert(cPPUsage == 0);
1460 cPPUsage = NdisPacketPoolUsage(pNetFlt->u.s.WinIf.hRecvPacketPool);
1461 Assert(cPPUsage == 0);
1462 /* for debugging only, ignore the err in release */
1463 NOREF(cPPUsage);
1464
1465 Assert(!pNetFlt->u.s.WinIf.StateFlags.fRequestInfo);
1466 }
1467 else
1468 {
1469 if (enmPrevPowerState > NdisDeviceStateD0)
1470 {
1471 pNetFlt->u.s.WinIf.StateFlags.fStandBy = FALSE;
1472 }
1473
1474 if (pNetFlt->u.s.WinIf.StateFlags.fRequestInfo & VBOXNDISREQUEST_QUEUED)
1475 {
1476 pNetFlt->u.s.WinIf.StateFlags.fRequestInfo = VBOXNDISREQUEST_INPROGRESS;
1477 RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
1478
1479 vboxNetFltWinMpRequestPost(pNetFlt);
1480 }
1481 else
1482 {
1483 RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp);
1484 }
1485 }
1486
1487 return NDIS_STATUS_SUCCESS;
1488}
1489
1490
1491static NDIS_STATUS vboxNetFltWinPtPnPEvent(IN NDIS_HANDLE hProtocolBindingContext, IN PNET_PNP_EVENT pNetPnPEvent)
1492{
1493 PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext;
1494
1495 LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p), NetEvent (%d)\n", pNetFlt, pNetPnPEvent->NetEvent));
1496
1497 switch (pNetPnPEvent->NetEvent)
1498 {
1499 case NetEventSetPower:
1500 {
1501 NDIS_DEVICE_POWER_STATE enmPowerState = *((PNDIS_DEVICE_POWER_STATE)pNetPnPEvent->Buffer);
1502 return vboxNetFltWinPtPnPSetPower(pNetFlt, enmPowerState);
1503 }
1504 case NetEventReconfigure:
1505 {
1506 if (!pNetFlt)
1507 {
1508 NdisReEnumerateProtocolBindings(g_VBoxNetFltGlobalsWin.Pt.hProtocol);
1509 }
1510 }
1511 default:
1512 return NDIS_STATUS_SUCCESS;
1513 }
1514
1515 LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), NetEvent (%d)\n", pNetFlt, pNetPnPEvent->NetEvent));
1516}
1517
1518#ifdef __cplusplus
1519# define PTCHARS_40(_p) ((_p).Ndis40Chars)
1520#else
1521# define PTCHARS_40(_p) (_p)
1522#endif
1523
1524/**
1525 * register the protocol edge
1526 */
1527DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtRegister(PVBOXNETFLTGLOBALS_PT pGlobalsPt, PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPathStr)
1528{
1529 NDIS_PROTOCOL_CHARACTERISTICS PtChars;
1530 NDIS_STRING NameStr;
1531
1532 NdisInitUnicodeString(&NameStr, VBOXNETFLT_NAME_PROTOCOL);
1533
1534 NdisZeroMemory(&PtChars, sizeof (PtChars));
1535 PTCHARS_40(PtChars).MajorNdisVersion = VBOXNETFLT_VERSION_PT_NDIS_MAJOR;
1536 PTCHARS_40(PtChars).MinorNdisVersion = VBOXNETFLT_VERSION_PT_NDIS_MINOR;
1537
1538 PTCHARS_40(PtChars).Name = NameStr;
1539 PTCHARS_40(PtChars).OpenAdapterCompleteHandler = vboxNetFltWinPtOpenAdapterComplete;
1540 PTCHARS_40(PtChars).CloseAdapterCompleteHandler = vboxNetFltWinPtCloseAdapterComplete;
1541 PTCHARS_40(PtChars).SendCompleteHandler = vboxNetFltWinPtSendComplete;
1542 PTCHARS_40(PtChars).TransferDataCompleteHandler = vboxNetFltWinPtTransferDataComplete;
1543 PTCHARS_40(PtChars).ResetCompleteHandler = vboxNetFltWinPtResetComplete;
1544 PTCHARS_40(PtChars).RequestCompleteHandler = vboxNetFltWinPtRequestComplete;
1545 PTCHARS_40(PtChars).ReceiveHandler = vboxNetFltWinPtReceive;
1546 PTCHARS_40(PtChars).ReceiveCompleteHandler = vboxNetFltWinPtReceiveComplete;
1547 PTCHARS_40(PtChars).StatusHandler = vboxNetFltWinPtStatus;
1548 PTCHARS_40(PtChars).StatusCompleteHandler = vboxNetFltWinPtStatusComplete;
1549 PTCHARS_40(PtChars).BindAdapterHandler = vboxNetFltWinPtBindAdapter;
1550 PTCHARS_40(PtChars).UnbindAdapterHandler = vboxNetFltWinPtUnbindAdapter;
1551 PTCHARS_40(PtChars).UnloadHandler = vboxNetFltWinPtUnloadProtocol;
1552#if !defined(DEBUG_NETFLT_RECV)
1553 PTCHARS_40(PtChars).ReceivePacketHandler = vboxNetFltWinPtReceivePacket;
1554#endif
1555 PTCHARS_40(PtChars).PnPEventHandler = vboxNetFltWinPtPnPEvent;
1556
1557 NDIS_STATUS Status;
1558 NdisRegisterProtocol(&Status, &pGlobalsPt->hProtocol, &PtChars, sizeof (PtChars));
1559 Assert(Status == STATUS_SUCCESS);
1560 return Status;
1561}
1562
1563/**
1564 * deregister the protocol edge
1565 */
1566DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtDeregister(PVBOXNETFLTGLOBALS_PT pGlobalsPt)
1567{
1568 if (!pGlobalsPt->hProtocol)
1569 return NDIS_STATUS_SUCCESS;
1570
1571 NDIS_STATUS Status;
1572
1573 NdisDeregisterProtocol(&Status, pGlobalsPt->hProtocol);
1574 Assert (Status == NDIS_STATUS_SUCCESS);
1575 if (Status == NDIS_STATUS_SUCCESS)
1576 {
1577 NdisZeroMemory(pGlobalsPt, sizeof (*pGlobalsPt));
1578 }
1579 return Status;
1580}
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