3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/* $Id$ */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/** @file
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * VBoxNetFltP-win.cpp - Bridged Networking Driver, Windows Specific Code.
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * Protocol edge
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/*
c0b6af690ad705bddfa87c643b89770a7a0aaf5avboxsync * Copyright (C) 2011-2014 Oracle Corporation
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * available from http://www.virtualbox.org. This file is free software;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * you can redistribute it and/or modify it under the terms of the GNU
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * General Public License (GPL) as published by the Free Software
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#include "VBoxNetFltCmn-win.h"
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifdef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# error "No protocol edge"
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#define VBOXNETFLT_PT_STATUS_IS_FILTERED(_s) (\
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync (_s) == NDIS_STATUS_MEDIA_CONNECT \
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync || (_s) == NDIS_STATUS_MEDIA_DISCONNECT \
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync )
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/**
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * performs binding to the given adapter
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtDoBinding(PVBOXNETFLTINS pThis, PNDIS_STRING pOurDeviceName, PNDIS_STRING pBindToDeviceName)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pThis->u.s.WinIf.PtState.PowerState == NdisDeviceStateD3);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pThis->u.s.WinIf.PtState.OpState == kVBoxNetDevOpState_Deinitialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSetOpState(&pThis->u.s.WinIf.PtState, kVBoxNetDevOpState_Initializing);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS Status = vboxNetFltWinCopyString(&pThis->u.s.WinIf.MpDeviceName, pOurDeviceName);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert (Status == NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSetPowerState(&pThis->u.s.WinIf.PtState, NdisDeviceStateD0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pThis->u.s.WinIf.OpenCloseStatus = NDIS_STATUS_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT iMedium;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS TmpStatus;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_MEDIUM aenmNdisMedium[] =
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* Ethernet */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMedium802_3,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* Wan */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMediumWan
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync };
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisResetEvent(&pThis->u.s.WinIf.OpenCloseEvent);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisOpenAdapter(&Status, &TmpStatus, &pThis->u.s.WinIf.hBinding, &iMedium,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync aenmNdisMedium, RT_ELEMENTS(aenmNdisMedium),
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync g_VBoxNetFltGlobalsWin.Pt.hProtocol,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pThis,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pBindToDeviceName,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync 0, /* IN UINT OpenOptions, (reserved, should be NULL) */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NULL /* IN PSTRING AddressingInformation OPTIONAL */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync );
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == NDIS_STATUS_PENDING || Status == STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_PENDING)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisWaitEvent(&pThis->u.s.WinIf.OpenCloseEvent, 0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = pThis->u.s.WinIf.OpenCloseStatus;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pThis->u.s.WinIf.hBinding);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pThis->u.s.WinIf.enmMedium = aenmNdisMedium[iMedium];
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSetOpState(&pThis->u.s.WinIf.PtState, kVBoxNetDevOpState_Initialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinMpInitializeDevideInstance(pThis);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return NDIS_STATUS_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogRel((__FUNCTION__": vboxNetFltWinMpInitializeDevideInstance failed, Status 0x%x\n", Status));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSetOpState(&pThis->u.s.WinIf.PtState, kVBoxNetDevOpState_Deinitializing);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinPtCloseInterface(pThis, &TmpStatus);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(TmpStatus == NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSetOpState(&pThis->u.s.WinIf.PtState, kVBoxNetDevOpState_Deinitialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogRel((__FUNCTION__"NdisOpenAdapter failed, Status (0x%x)", Status));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSetOpState(&pThis->u.s.WinIf.PtState, kVBoxNetDevOpState_Deinitialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pThis->u.s.WinIf.hBinding = NULL;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic VOID vboxNetFltWinPtBindAdapter(OUT PNDIS_STATUS pStatus,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync IN NDIS_HANDLE hBindContext,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync IN PNDIS_STRING pDeviceNameStr,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync IN PVOID pvSystemSpecific1,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync IN PVOID pvSystemSpecific2)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("==>"__FUNCTION__"\n"));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_HANDLE hConfig = NULL;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisOpenProtocolConfiguration(&Status, &hConfig, (PNDIS_STRING)pvSystemSpecific1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_CONFIGURATION_PARAMETER pParam;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STRING UppedBindStr = NDIS_STRING_CONST("UpperBindings");
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisReadConfiguration(&Status, &pParam, hConfig, &UppedBindStr, NdisParameterString);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLTINS pNetFlt;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinPtInitBind(&pNetFlt, &pParam->ParameterData.StringData, pDeviceNameStr);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisCloseConfiguration(hConfig);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *pStatus = Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__": Status 0x%x\n", Status));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic VOID vboxNetFltWinPtOpenAdapterComplete(IN NDIS_HANDLE hProtocolBindingContext, IN NDIS_STATUS Status, IN NDIS_STATUS OpenErrorStatus)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLTINS pNetFlt =(PVBOXNETFLTINS)hProtocolBindingContext;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p), Status (0x%x), OpenErrorStatus(0x%x)\n", pNetFlt, Status, OpenErrorStatus));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pNetFlt->u.s.WinIf.OpenCloseStatus == NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pNetFlt->u.s.WinIf.OpenCloseStatus == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.OpenCloseStatus = Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status != NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogRel((__FUNCTION__" : Open Complete status is 0x%x", Status));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogRel((__FUNCTION__" : Adapter maintained status is 0x%x", pNetFlt->u.s.WinIf.OpenCloseStatus));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisSetEvent(&pNetFlt->u.s.WinIf.OpenCloseEvent);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), Status (0x%x), OpenErrorStatus(0x%x)\n", pNetFlt, Status, OpenErrorStatus));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic void vboxNetFltWinPtRequestsWaitComplete(PVBOXNETFLTINS pNetFlt)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* wait for request to complete */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync while (vboxNetFltWinAtomicUoReadWinState(pNetFlt->u.s.WinIf.StateFlags).fRequestInfo == VBOXNDISREQUEST_INPROGRESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSleep(2);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /*
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * If the below miniport is going to low power state, complete the queued request
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync RTSpinlockAcquire(pNetFlt->hSpinlock);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pNetFlt->u.s.WinIf.StateFlags.fRequestInfo & VBOXNDISREQUEST_QUEUED)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* mark the request as InProgress before posting it to RequestComplete */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.StateFlags.fRequestInfo = VBOXNDISREQUEST_INPROGRESS;
c0b6af690ad705bddfa87c643b89770a7a0aaf5avboxsync RTSpinlockRelease(pNetFlt->hSpinlock);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinPtRequestComplete(pNetFlt, &pNetFlt->u.s.WinIf.PassDownRequest, NDIS_STATUS_FAILURE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
c0b6af690ad705bddfa87c643b89770a7a0aaf5avboxsync RTSpinlockRelease(pNetFlt->hSpinlock);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtDoUnbinding(PVBOXNETFLTINS pNetFlt, bool bOnUnbind)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync uint64_t NanoTS = RTTimeSystemNanoTS();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync int cPPUsage;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("==>"__FUNCTION__": pNetFlt 0x%p\n", pNetFlt));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.PtState) == kVBoxNetDevOpState_Initialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync RTSpinlockAcquire(pNetFlt->hSpinlock);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ASMAtomicUoWriteBool(&pNetFlt->fDisconnectedFromHost, true);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ASMAtomicUoWriteBool(&pNetFlt->fRediscoveryPending, false);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ASMAtomicUoWriteU64(&pNetFlt->NanoTSLastRediscovery, NanoTS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.PtState, kVBoxNetDevOpState_Deinitializing);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!bOnUnbind)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitializing);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
c0b6af690ad705bddfa87c643b89770a7a0aaf5avboxsync RTSpinlockRelease(pNetFlt->hSpinlock);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinPtRequestsWaitComplete(pNetFlt);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinWaitDereference(&pNetFlt->u.s.WinIf.MpState);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinWaitDereference(&pNetFlt->u.s.WinIf.PtState);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* check packet pool is empty */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cPPUsage = NdisPacketPoolUsage(pNetFlt->u.s.WinIf.hSendPacketPool);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(cPPUsage == 0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cPPUsage = NdisPacketPoolUsage(pNetFlt->u.s.WinIf.hRecvPacketPool);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(cPPUsage == 0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* for debugging only, ignore the err in release */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NOREF(cPPUsage);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!bOnUnbind || !vboxNetFltWinMpDeInitializeDeviceInstance(pNetFlt, &Status))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinPtCloseInterface(pNetFlt, &Status);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.PtState, kVBoxNetDevOpState_Deinitialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!bOnUnbind)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitializing);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__": pNetFlt 0x%p\n", pNetFlt));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic VOID vboxNetFltWinPtUnbindAdapter(OUT PNDIS_STATUS pStatus,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync IN NDIS_HANDLE hContext,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync IN NDIS_HANDLE hUnbindContext)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hContext;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p)\n", pNetFlt));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *pStatus = vboxNetFltWinDetachFromInterface(pNetFlt, true);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(*pStatus == NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p)\n", pNetFlt));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic VOID vboxNetFltWinPtUnloadProtocol()
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("==>"__FUNCTION__"\n"));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS Status = vboxNetFltWinPtDeregister(&g_VBoxNetFltGlobalsWin.Pt);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__": PtDeregister Status (0x%x)\n", Status));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic VOID vboxNetFltWinPtCloseAdapterComplete(IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)ProtocolBindingContext;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p), Status (0x%x)\n", pNetFlt, Status));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pNetFlt->u.s.WinIf.OpenCloseStatus == NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pNetFlt->u.s.WinIf.OpenCloseStatus == NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pNetFlt->u.s.WinIf.OpenCloseStatus == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.OpenCloseStatus = Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisSetEvent(&pNetFlt->u.s.WinIf.OpenCloseEvent);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p), Status (0x%x)\n", pNetFlt, Status));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic VOID vboxNetFltWinPtResetComplete(IN NDIS_HANDLE hProtocolBindingContext, IN NDIS_STATUS Status)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("==>"__FUNCTION__" : pNetFlt 0x%p, Status 0x%x\n", hProtocolBindingContext, Status));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /*
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * should never be here
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__" : pNetFlt 0x%p, Status 0x%x\n", hProtocolBindingContext, Status));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic NDIS_STATUS vboxNetFltWinPtHandleQueryInfoComplete(PVBOXNETFLTINS pNetFlt, NDIS_STATUS Status)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_REQUEST pRequest = &pNetFlt->u.s.WinIf.PassDownRequest;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync switch (pRequest->DATA.QUERY_INFORMATION.Oid)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync case OID_PNP_CAPABILITIES:
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pRequest->DATA.QUERY_INFORMATION.InformationBufferLength >= sizeof (NDIS_PNP_CAPABILITIES))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_PNP_CAPABILITIES pPnPCaps = (PNDIS_PNP_CAPABILITIES)(pRequest->DATA.QUERY_INFORMATION.InformationBuffer);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_PM_WAKE_UP_CAPABILITIES pPmWuCaps = &pPnPCaps->WakeUpCapabilities;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pPmWuCaps->MinMagicPacketWakeUp = NdisDeviceStateUnspecified;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pPmWuCaps->MinPatternWakeUp = NdisDeviceStateUnspecified;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pPmWuCaps->MinLinkChangeWakeUp = NdisDeviceStateUnspecified;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *pNetFlt->u.s.WinIf.pcPDRBytesRW = sizeof (NDIS_PNP_CAPABILITIES);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = NDIS_STATUS_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = sizeof(NDIS_PNP_CAPABILITIES);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = NDIS_STATUS_RESOURCES;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync case OID_GEN_MAC_OPTIONS:
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pRequest->DATA.QUERY_INFORMATION.InformationBufferLength >= sizeof (ULONG))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.fMacOptions = *(PULONG)pRequest->DATA.QUERY_INFORMATION.InformationBuffer;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOX_LOOPBACK_USEFLAGS
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* clearing this flag tells ndis we'll handle loopback ourselves
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * the ndis layer or nic driver below us would loopback packets as necessary */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *(PULONG)pRequest->DATA.QUERY_INFORMATION.InformationBuffer &= ~NDIS_MAC_OPTION_NO_LOOPBACK;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* we have to catch loopbacks from the underlying driver, so no duplications will occur,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * just indicate NDIS to handle loopbacks for the packets coming from the protocol */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *(PULONG)pRequest->DATA.QUERY_INFORMATION.InformationBuffer |= NDIS_MAC_OPTION_NO_LOOPBACK;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = sizeof (ULONG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = NDIS_STATUS_RESOURCES;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync case OID_GEN_CURRENT_PACKET_FILTER:
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (VBOXNETFLT_PROMISCUOUS_SUPPORTED(pNetFlt))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* we're here _ONLY_ in the passthru mode */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pNetFlt->u.s.WinIf.StateFlags.fProcessingPacketFilter && !pNetFlt->u.s.WinIf.StateFlags.fPPFNetFlt);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pNetFlt->u.s.WinIf.StateFlags.fProcessingPacketFilter && !pNetFlt->u.s.WinIf.StateFlags.fPPFNetFlt)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pNetFlt->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDereferenceModePassThru(pNetFlt);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDereferenceWinIf(pNetFlt);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pRequest->DATA.QUERY_INFORMATION.InformationBufferLength >= sizeof (ULONG))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* the filter request is issued below only in case netflt is not active,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * simply update the cache here */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* cache the filter used by upper protocols */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.fUpperProtocolSetFilter = *(PULONG)pRequest->DATA.QUERY_INFORMATION.InformationBuffer;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.StateFlags.fUpperProtSetFilterInitialized = TRUE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = sizeof (ULONG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = NDIS_STATUS_RESOURCES;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync default:
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pRequest->DATA.QUERY_INFORMATION.Oid != OID_PNP_QUERY_POWER);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *pNetFlt->u.s.WinIf.pcPDRBytesRW = pRequest->DATA.QUERY_INFORMATION.BytesWritten;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = pRequest->DATA.QUERY_INFORMATION.BytesNeeded;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic NDIS_STATUS vboxNetFltWinPtHandleSetInfoComplete(PVBOXNETFLTINS pNetFlt, NDIS_STATUS Status)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_REQUEST pRequest = &pNetFlt->u.s.WinIf.PassDownRequest;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync switch (pRequest->DATA.SET_INFORMATION.Oid)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync case OID_GEN_CURRENT_PACKET_FILTER:
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (VBOXNETFLT_PROMISCUOUS_SUPPORTED(pNetFlt))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pNetFlt->u.s.WinIf.StateFlags.fProcessingPacketFilter)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pNetFlt->u.s.WinIf.StateFlags.fPPFNetFlt)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pNetFlt->enmTrunkState == INTNETTRUNKIFSTATE_ACTIVE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.StateFlags.fPPFNetFlt = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pRequest->DATA.SET_INFORMATION.InformationBufferLength >= sizeof (ULONG))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.fOurSetFilter = *((PULONG)pRequest->DATA.SET_INFORMATION.InformationBuffer);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pNetFlt->u.s.WinIf.fOurSetFilter == NDIS_PACKET_TYPE_PROMISCUOUS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = sizeof (ULONG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = NDIS_STATUS_RESOURCES;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDereferenceNetFlt(pNetFlt);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pNetFlt->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pRequest->DATA.SET_INFORMATION.InformationBufferLength >= sizeof (ULONG))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* the request was issued when the netflt was not active, simply update the cache here */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.fUpperProtocolSetFilter = *((PULONG)pRequest->DATA.SET_INFORMATION.InformationBuffer);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.StateFlags.fUpperProtSetFilterInitialized = TRUE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = sizeof (ULONG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = NDIS_STATUS_RESOURCES;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDereferenceModePassThru(pNetFlt);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.StateFlags.fProcessingPacketFilter = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDereferenceWinIf(pNetFlt);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifdef DEBUG_misha
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync default:
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pRequest->DATA.SET_INFORMATION.Oid != OID_PNP_SET_POWER);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *pNetFlt->u.s.WinIf.pcPDRBytesRW = pRequest->DATA.SET_INFORMATION.BytesRead;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = pRequest->DATA.SET_INFORMATION.BytesNeeded;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(VOID) vboxNetFltWinPtRequestComplete(NDIS_HANDLE hContext, PNDIS_REQUEST pNdisRequest, NDIS_STATUS Status)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hContext;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_REQUEST pSynchRequest = pNetFlt->u.s.WinIf.pSynchRequest;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_OID Oid = pNetFlt->u.s.WinIf.PassDownRequest.DATA.SET_INFORMATION.Oid;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p), pNdisRequest (0x%p), Status (0x%x)\n", pNetFlt, pNdisRequest, Status));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pSynchRequest == pNdisRequest)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* asynchronous completion of our sync request */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /*1.set the status */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.SynchCompletionStatus = Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* 2. set event */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync KeSetEvent(&pNetFlt->u.s.WinIf.hSynchCompletionEvent, 0, FALSE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* 3. return; */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p), pNdisRequest (0x%p), Status (0x%x)\n", pNetFlt, pNdisRequest, Status));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(&pNetFlt->u.s.WinIf.PassDownRequest == pNdisRequest);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pNetFlt->u.s.WinIf.StateFlags.fRequestInfo == VBOXNDISREQUEST_INPROGRESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinMpRequestStateComplete(pNetFlt);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync switch (pNdisRequest->RequestType)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync case NdisRequestQueryInformation:
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinPtHandleQueryInfoComplete(pNetFlt, Status);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMQueryInformationComplete(pNetFlt->u.s.WinIf.hMiniport, Status);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync case NdisRequestSetInformation:
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinPtHandleSetInfoComplete(pNetFlt, Status);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMSetInformationComplete(pNetFlt->u.s.WinIf.hMiniport, Status);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync default:
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p), pNdisRequest (0x%p), Status (0x%x)\n", pNetFlt, pNdisRequest, Status));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic VOID vboxNetFltWinPtStatus(IN NDIS_HANDLE hProtocolBindingContext, IN NDIS_STATUS GeneralStatus, IN PVOID pvStatusBuffer, IN UINT cbStatusBuffer)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p), GeneralStatus (0x%x)\n", pNetFlt, GeneralStatus));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (vboxNetFltWinReferenceWinIf(pNetFlt))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pNetFlt->u.s.WinIf.hMiniport);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (VBOXNETFLT_PT_STATUS_IS_FILTERED(GeneralStatus))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.MpIndicatedMediaStatus = GeneralStatus;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMIndicateStatus(pNetFlt->u.s.WinIf.hMiniport,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync GeneralStatus,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pvStatusBuffer,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cbStatusBuffer);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDereferenceWinIf(pNetFlt);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pNetFlt->u.s.WinIf.hMiniport != NULL
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync && VBOXNETFLT_PT_STATUS_IS_FILTERED(GeneralStatus)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync )
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.MpUnindicatedMediaStatus = GeneralStatus;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p), GeneralStatus (0x%x)\n", pNetFlt, GeneralStatus));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic VOID vboxNetFltWinPtStatusComplete(IN NDIS_HANDLE hProtocolBindingContext)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (vboxNetFltWinReferenceWinIf(pNetFlt))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMIndicateStatusComplete(pNetFlt->u.s.WinIf.hMiniport);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDereferenceWinIf(pNetFlt);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic VOID vboxNetFltWinPtSendComplete(IN NDIS_HANDLE hProtocolBindingContext, IN PNDIS_PACKET pPacket, IN NDIS_STATUS Status)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLT_PKTRSVD_PT pSendInfo = (PVBOXNETFLT_PKTRSVD_PT)pPacket->ProtocolReserved;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_PACKET pOrigPacket = pSendInfo->pOrigPacket;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVOID pBufToFree = pSendInfo->pBufToFree;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p), pPacket (0x%p), Status (0x%x)\n", pNetFlt, pPacket, Status));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#if defined(DEBUG_NETFLT_PACKETS) || !defined(VBOX_LOOPBACK_USEFLAGS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* @todo: for optimization we could check only for netflt-mode packets
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * do it for all for now */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinLbRemoveSendPacket(pNetFlt, pPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pOrigPacket)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisIMCopySendCompletePerPacketInfo(pOrigPacket, pPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisFreePacket(pPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* the ptk was posted from the upperlying protocol */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMSendComplete(pNetFlt->u.s.WinIf.hMiniport, pOrigPacket, Status);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* if the pOrigPacket is zero - the ptk was originated by netFlt send/receive
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * need to free packet buffers */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinFreeSGNdisPacket(pPacket, !pBufToFree);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pBufToFree)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinMemFree(pBufToFree);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDereferenceWinIf(pNetFlt);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), pPacket (0x%p), Status (0x%x)\n", pNetFlt, pPacket, Status));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/**
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * removes searches for the packet in the list and removes it if found
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * @return true if the packet was found and removed, false - otherwise
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic bool vboxNetFltWinRemovePacketFromList(PVBOXNETFLT_INTERLOCKED_SINGLE_LIST pList, PNDIS_PACKET pPacket)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLT_PKTRSVD_TRANSFERDATA_PT pTDR = (PVBOXNETFLT_PKTRSVD_TRANSFERDATA_PT)pPacket->ProtocolReserved;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return vboxNetFltWinInterlockedSearchListEntry(pList, &pTDR->ListEntry, true /* remove*/);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/**
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * puts the packet to the tail of the list
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic void vboxNetFltWinPutPacketToList(PVBOXNETFLT_INTERLOCKED_SINGLE_LIST pList, PNDIS_PACKET pPacket, PNDIS_BUFFER pOrigBuffer)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLT_PKTRSVD_TRANSFERDATA_PT pTDR = (PVBOXNETFLT_PKTRSVD_TRANSFERDATA_PT)pPacket->ProtocolReserved;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pTDR->pOrigBuffer = pOrigBuffer;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinInterlockedPutTail(pList, &pTDR->ListEntry);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic bool vboxNetFltWinPtTransferDataCompleteActive(PVBOXNETFLTINS pNetFltIf, PNDIS_PACKET pPacket, NDIS_STATUS Status)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_BUFFER pBuffer;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLT_PKTRSVD_TRANSFERDATA_PT pTDR;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!vboxNetFltWinRemovePacketFromList(&pNetFltIf->u.s.WinIf.TransferDataList, pPacket))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pTDR = (PVBOXNETFLT_PKTRSVD_TRANSFERDATA_PT)pPacket->ProtocolReserved;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pTDR);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pTDR->pOrigBuffer);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync do
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisUnchainBufferAtFront(pPacket, &pBuffer);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pBuffer);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisFreeBuffer(pBuffer);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pBuffer = pTDR->pOrigBuffer;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisChainBufferAtBack(pPacket, pBuffer);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* data transfer was initiated when the netFlt was active
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * the netFlt is still retained by us
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * 1. check if loopback
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * 2. enqueue packet
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * 3. release netFlt */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifdef VBOX_LOOPBACK_USEFLAGS
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (vboxNetFltWinIsLoopedBackPacket(pPacket))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* should not be here */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_PACKET pLb = vboxNetFltWinLbSearchLoopBack(pNetFltIf, pPacket, false);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pLb)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef DEBUG_NETFLT_RECV_TRANSFERDATA
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* should not be here */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!vboxNetFltWinLbIsFromIntNet(pLb))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* the packet is not from int net, need to pass it up to the host */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMIndicateReceivePacket(pNetFltIf->u.s.WinIf.hMiniport, &pPacket, 1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* dereference NetFlt, WinIf will be dereferenced on Packet return */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDereferenceNetFlt(pNetFltIf);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* 2. enqueue */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* use the same packet info to put the packet in the processing packet queue */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLT_PKTRSVD_MP pRecvInfo = (PVBOXNETFLT_PKTRSVD_MP)pPacket->MiniportReserved;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync VBOXNETFLT_LBVERIFY(pNetFltIf, pPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pRecvInfo->pOrigPacket = NULL;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pRecvInfo->pBufToFree = NULL;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisGetPacketFlags(pPacket) = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# ifdef VBOXNETFLT_NO_PACKET_QUEUE
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (vboxNetFltWinPostIntnet(pNetFltIf, pPacket, 0))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* drop it */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinFreeSGNdisPacket(pPacket, true);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDereferenceWinIf(pNetFltIf);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMIndicateReceivePacket(pNetFltIf->u.s.WinIf.hMiniport, &pPacket, 1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDereferenceNetFlt(pNetFltIf);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinQuEnqueuePacket(pNetFltIf, pPacket, PACKET_MINE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* we are here because of error either in data transfer or in enqueueing the packet */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinFreeSGNdisPacket(pPacket, true);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDereferenceNetFlt(pNetFltIf);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDereferenceWinIf(pNetFltIf);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync } while (0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return true;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic VOID vboxNetFltWinPtTransferDataComplete(IN NDIS_HANDLE hProtocolBindingContext,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync IN PNDIS_PACKET pPacket,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync IN NDIS_STATUS Status,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync IN UINT cbTransferred)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p), pPacket (0x%p), Status (0x%x), cbTransfered (%d)\n", pNetFlt, pPacket, Status, cbTransferred));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!vboxNetFltWinPtTransferDataCompleteActive(pNetFlt, pPacket, Status))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pNetFlt->u.s.WinIf.hMiniport)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMTransferDataComplete(pNetFlt->u.s.WinIf.hMiniport,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pPacket,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cbTransferred);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDereferenceWinIf(pNetFlt);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* else - all processing is done with vboxNetFltWinPtTransferDataCompleteActive already */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), pPacket (0x%p), Status (0x%x), cbTransfered (%d)\n", pNetFlt, pPacket, Status, cbTransferred));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic INT vboxNetFltWinRecvPacketPassThru(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket, BOOLEAN bForceIndicate)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_PACKET pMyPacket;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS Status = vboxNetFltWinPrepareRecvPacket(pNetFlt, pPacket, &pMyPacket, true);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* the Status holds the current packet status it will be checked for NDIS_STATUS_RESOURCES later
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * (see below) */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pMyPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pMyPacket)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMIndicateReceivePacket(pNetFlt->u.s.WinIf.hMiniport, &pMyPacket, 1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_RESOURCES)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisDprFreePacket(pMyPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return 1;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/**
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * process the packet receive in a "passthru" mode
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic NDIS_STATUS vboxNetFltWinRecvPassThru(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_PACKET pMyPacket;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisDprAllocatePacket(&Status, &pMyPacket, pNetFlt->u.s.WinIf.hRecvPacketPool);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinCopyPacketInfoOnRecv(pMyPacket, pPacket, true /* force NDIS_STATUS_RESOURCES */);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(NDIS_GET_PACKET_STATUS(pMyPacket) == NDIS_STATUS_RESOURCES);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMIndicateReceivePacket(pNetFlt->u.s.WinIf.hMiniport, &pMyPacket, 1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisDprFreePacket(pMyPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic VOID vboxNetFltWinRecvIndicatePassThru(PVBOXNETFLTINS pNetFlt, NDIS_HANDLE MacReceiveContext,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVOID pHeaderBuffer, UINT cbHeaderBuffer, PVOID pLookAheadBuffer, UINT cbLookAheadBuffer, UINT cbPacket)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* Note: we're using KeGetCurrentProcessorNumber, which is not entirely correct in case
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * we're running on 64bit win7+, which can handle > 64 CPUs, however since KeGetCurrentProcessorNumber
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * always returns the number < than the number of CPUs in the first group, we're guaranteed to have CPU index < 64
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * @todo: use KeGetCurrentProcessorNumberEx for Win7+ 64 and dynamically extended array */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ULONG Proc = KeGetCurrentProcessorNumber();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Proc < RT_ELEMENTS(pNetFlt->u.s.WinIf.abIndicateRxComplete));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.abIndicateRxComplete[Proc] = TRUE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync switch (pNetFlt->u.s.WinIf.enmMedium)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync case NdisMedium802_3:
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync case NdisMediumWan:
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMEthIndicateReceive(pNetFlt->u.s.WinIf.hMiniport,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync MacReceiveContext,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync (PCHAR)pHeaderBuffer,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cbHeaderBuffer,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pLookAheadBuffer,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cbLookAheadBuffer,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cbPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync default:
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(FALSE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/**
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * process the ProtocolReceive in an "active" mode
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * @return NDIS_STATUS_SUCCESS - the packet is processed
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * NDIS_STATUS_PENDING - the packet is being processed, we are waiting for the ProtocolTransferDataComplete to be called
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * NDIS_STATUS_NOT_ACCEPTED - the packet is not needed - typically this is because this is a loopback packet
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * NDIS_STATUS_FAILURE - packet processing failed
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic NDIS_STATUS vboxNetFltWinPtReceiveActive(PVBOXNETFLTINS pNetFlt, NDIS_HANDLE MacReceiveContext, PVOID pHeaderBuffer, UINT cbHeaderBuffer,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVOID pLookaheadBuffer, UINT cbLookaheadBuffer, UINT cbPacket)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync do
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (cbHeaderBuffer != VBOXNETFLT_PACKET_ETHEADER_SIZE)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = NDIS_STATUS_NOT_ACCEPTED;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef DEBUG_NETFLT_RECV_TRANSFERDATA
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (cbPacket == cbLookaheadBuffer)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PINTNETSG pSG;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PUCHAR pRcvData;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOX_LOOPBACK_USEFLAGS
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_PACKET pLb;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* allocate SG buffer */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinAllocSG(cbPacket + cbHeaderBuffer, &pSG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status != NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pRcvData = (PUCHAR)pSG->aSegs[0].pv;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMoveMappedMemory(pRcvData, pHeaderBuffer, cbHeaderBuffer);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisCopyLookaheadData(pRcvData+cbHeaderBuffer,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pLookaheadBuffer,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cbLookaheadBuffer,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.fMacOptions);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOX_LOOPBACK_USEFLAGS
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pLb = vboxNetFltWinLbSearchLoopBackBySG(pNetFlt, pSG, false);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pLb)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef DEBUG_NETFLT_RECV_NOPACKET
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* should not be here */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!vboxNetFltWinLbIsFromIntNet(pLb))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_PACKET pMyPacket;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pMyPacket = vboxNetFltWinNdisPacketFromSG(pNetFlt, /* PVBOXNETFLTINS */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pSG, /* PINTNETSG */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pSG, /* PVOID pBufToFree */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync false, /* bool bToWire */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync false); /* bool bCopyMemory */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pMyPacket)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMIndicateReceivePacket(pNetFlt->u.s.WinIf.hMiniport, &pMyPacket, 1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* dereference the NetFlt here & indicate SUCCESS, which would mean the caller would not do a dereference
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * the WinIf dereference will be done on packet return */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDereferenceNetFlt(pNetFlt);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = NDIS_STATUS_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinMemFree(pSG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = NDIS_STATUS_FAILURE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinMemFree(pSG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = NDIS_STATUS_NOT_ACCEPTED;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync VBOXNETFLT_LBVERIFYSG(pNetFlt, pSG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* enqueue SG */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# ifdef VBOXNETFLT_NO_PACKET_QUEUE
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (vboxNetFltWinPostIntnet(pNetFlt, pSG, VBOXNETFLT_PACKET_SG))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* drop it */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinMemFree(pSG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDereferenceWinIf(pNetFlt);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_PACKET pMyPacket = vboxNetFltWinNdisPacketFromSG(pNetFlt, /* PVBOXNETFLTINS */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pSG, /* PINTNETSG */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pSG, /* PVOID pBufToFree */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync false, /* bool bToWire */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync false); /* bool bCopyMemory */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pMyPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pMyPacket)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_SET_PACKET_STATUS(pMyPacket, NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync DBG_CHECK_PACKET_AND_SG(pMyPacket, pSG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("non-ndis packet info, packet created (%p)\n", pMyPacket));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMIndicateReceivePacket(pNetFlt->u.s.WinIf.hMiniport, &pMyPacket, 1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDereferenceWinIf(pNetFlt);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = NDIS_STATUS_RESOURCES;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDereferenceNetFlt(pNetFlt);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinQuEnqueuePacket(pNetFlt, pSG, PACKET_SG | PACKET_MINE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status != NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinMemFree(pSG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_PACKET pPacket;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_BUFFER pTransferBuffer;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_BUFFER pOrigBuffer;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PUCHAR pMemBuf;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT cbBuf = cbPacket + cbHeaderBuffer;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT cbTransferred;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* allocate NDIS Packet buffer */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisAllocatePacket(&Status, &pPacket, pNetFlt->u.s.WinIf.hRecvPacketPool);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status != NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync VBOXNETFLT_OOB_INIT(pPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifdef VBOX_LOOPBACK_USEFLAGS
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* set "don't loopback" flags */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisGetPacketFlags(pPacket) = g_VBoxNetFltGlobalsWin.fPacketDontLoopBack;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisGetPacketFlags(pPacket) = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinMemAlloc((PVOID*)(&pMemBuf), cbBuf);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status != NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisFreePacket(pPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisAllocateBuffer(&Status, &pTransferBuffer, pNetFlt->u.s.WinIf.hRecvBufferPool, pMemBuf + cbHeaderBuffer, cbPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status != NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = NDIS_STATUS_FAILURE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisFreePacket(pPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinMemFree(pMemBuf);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisAllocateBuffer(&Status, &pOrigBuffer, pNetFlt->u.s.WinIf.hRecvBufferPool, pMemBuf, cbBuf);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status != NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = NDIS_STATUS_FAILURE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisFreeBuffer(pTransferBuffer);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisFreePacket(pPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinMemFree(pMemBuf);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisChainBufferAtBack(pPacket, pTransferBuffer);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMoveMappedMemory(pMemBuf, pHeaderBuffer, cbHeaderBuffer);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinPutPacketToList(&pNetFlt->u.s.WinIf.TransferDataList, pPacket, pOrigBuffer);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifdef DEBUG_NETFLT_RECV_TRANSFERDATA
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (cbPacket == cbLookaheadBuffer)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisCopyLookaheadData(pMemBuf+cbHeaderBuffer,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pLookaheadBuffer,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cbLookaheadBuffer,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.fMacOptions);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(cbPacket > cbLookaheadBuffer);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisTransferData(&Status, pNetFlt->u.s.WinIf.hBinding, MacReceiveContext,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync 0, /* ByteOffset */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cbPacket, pPacket, &cbTransferred);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status != NDIS_STATUS_PENDING)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinPtTransferDataComplete(pNetFlt, pPacket, Status, cbTransferred);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync } while (0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic NDIS_STATUS vboxNetFltWinPtReceive(IN NDIS_HANDLE hProtocolBindingContext,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync IN NDIS_HANDLE MacReceiveContext,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync IN PVOID pHeaderBuffer,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync IN UINT cbHeaderBuffer,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync IN PVOID pLookAheadBuffer,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync IN UINT cbLookAheadBuffer,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync IN UINT cbPacket)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_PACKET pPacket = NULL;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bool bNetFltActive;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bool fWinIfActive = vboxNetFltWinReferenceWinIfNetFlt(pNetFlt, &bNetFltActive);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync const bool bPassThruActive = !bNetFltActive;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (fWinIfActive)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync do
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef DEBUG_NETFLT_RECV_NOPACKET
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pPacket = NdisGetReceivedPacket(pNetFlt->u.s.WinIf.hBinding, MacReceiveContext);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pPacket)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# ifndef VBOX_LOOPBACK_USEFLAGS
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_PACKET pLb = NULL;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (vboxNetFltWinIsLoopedBackPacket(pPacket))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* nothing else to do here, just return the packet */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync //NdisReturnPackets(&pPacket, 1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = NDIS_STATUS_NOT_ACCEPTED;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync VBOXNETFLT_LBVERIFY(pNetFlt, pPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (bNetFltActive)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# ifndef VBOX_LOOPBACK_USEFLAGS
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pLb = vboxNetFltWinLbSearchLoopBack(pNetFlt, pPacket, false);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!pLb)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync VBOXNETFLT_LBVERIFY(pNetFlt, pPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# ifdef VBOXNETFLT_NO_PACKET_QUEUE
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (vboxNetFltWinPostIntnet(pNetFlt, pPacket, 0))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* drop it */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinQuEnqueuePacket(pNetFlt, pPacket, PACKET_COPY);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync //NdisReturnPackets(&pPacket, 1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync fWinIfActive = false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bNetFltActive = false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# ifndef VBOX_LOOPBACK_USEFLAGS
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else if (vboxNetFltWinLbIsFromIntNet(pLb))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* nothing else to do here, just return the packet */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync //NdisReturnPackets(&pPacket, 1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = NDIS_STATUS_NOT_ACCEPTED;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* we are here because this is a looped back packet set not from intnet
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * we will post it to the upper protocol */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# ifndef VBOX_LOOPBACK_USEFLAGS
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(!pLb || !vboxNetFltWinLbIsFromIntNet(pLb));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinRecvPassThru(pNetFlt, pPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* we are done with packet processing, and we will
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * not receive packet return event for this packet,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * fWinIfActive should be true to ensure we release WinIf*/
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(fWinIfActive);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* intnet processing failed - fall back to no-packet mode */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(bNetFltActive);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(fWinIfActive);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif /* #ifndef DEBUG_NETFLT_RECV_NOPACKET */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (bNetFltActive)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinPtReceiveActive(pNetFlt, MacReceiveContext, pHeaderBuffer, cbHeaderBuffer,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pLookAheadBuffer, cbLookAheadBuffer, cbPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (NT_SUCCESS(Status))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status != NDIS_STATUS_NOT_ACCEPTED)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync fWinIfActive = false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bNetFltActive = false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOX_LOOPBACK_USEFLAGS
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* this is a loopback packet, nothing to do here */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* should not be here */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* we are done with packet processing, and we will
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * not receive packet return event for this packet,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * fWinIfActive should be true to ensure we release WinIf*/
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(fWinIfActive);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinRecvIndicatePassThru(pNetFlt, MacReceiveContext, pHeaderBuffer, cbHeaderBuffer, pLookAheadBuffer, cbLookAheadBuffer, cbPacket);
4bfa7b58e362a1bca0628643c352c137900bf01avboxsync /* the status could contain an error value here in case the IntNet recv failed,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * ensure we return back success status */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = NDIS_STATUS_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync } while (0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (bNetFltActive)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDereferenceNetFlt(pNetFlt);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else if (bPassThruActive)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDereferenceModePassThru(pNetFlt);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (fWinIfActive)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDereferenceWinIf(pNetFlt);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = NDIS_STATUS_FAILURE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic VOID vboxNetFltWinPtReceiveComplete(NDIS_HANDLE hProtocolBindingContext)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ULONG cPackets = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bool bNetFltActive;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bool fWinIfActive = vboxNetFltWinReferenceWinIfNetFlt(pNetFlt, &bNetFltActive);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_HANDLE hMiniport = pNetFlt->u.s.WinIf.hMiniport;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* Note: we're using KeGetCurrentProcessorNumber, which is not entirely correct in case
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * we're running on 64bit win7+, which can handle > 64 CPUs, however since KeGetCurrentProcessorNumber
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * always returns the number < than the number of CPUs in the first group, we're guaranteed to have CPU index < 64
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * @todo: use KeGetCurrentProcessorNumberEx for Win7+ 64 and dynamically extended array */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ULONG iProc = KeGetCurrentProcessorNumber();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(iProc < RT_ELEMENTS(pNetFlt->u.s.WinIf.abIndicateRxComplete));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (hMiniport != NULL && pNetFlt->u.s.WinIf.abIndicateRxComplete[iProc])
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync switch (pNetFlt->u.s.WinIf.enmMedium)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync case NdisMedium802_3:
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync case NdisMediumWan:
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMEthIndicateReceiveComplete(hMiniport);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync default:
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.abIndicateRxComplete[iProc] = FALSE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (fWinIfActive)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (bNetFltActive)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDereferenceNetFlt(pNetFlt);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDereferenceModePassThru(pNetFlt);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDereferenceWinIf(pNetFlt);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic INT vboxNetFltWinPtReceivePacket(NDIS_HANDLE hProtocolBindingContext, PNDIS_PACKET pPacket)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync INT cRefCount = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bool bNetFltActive;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bool fWinIfActive = vboxNetFltWinReferenceWinIfNetFlt(pNetFlt, &bNetFltActive);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync const bool bPassThruActive = !bNetFltActive;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (fWinIfActive)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync do
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifdef VBOX_LOOPBACK_USEFLAGS
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (vboxNetFltWinIsLoopedBackPacket(pPacket))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Log(("lb_rp"));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* nothing else to do here, just return the packet */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cRefCount = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync //NdisReturnPackets(&pPacket, 1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync VBOXNETFLT_LBVERIFY(pNetFlt, pPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (bNetFltActive)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOX_LOOPBACK_USEFLAGS
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_PACKET pLb = vboxNetFltWinLbSearchLoopBack(pNetFlt, pPacket, false);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!pLb)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETFLT_NO_PACKET_QUEUE
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS fStatus;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bool bResources = NDIS_GET_PACKET_STATUS(pPacket) == NDIS_STATUS_RESOURCES;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync VBOXNETFLT_LBVERIFY(pNetFlt, pPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifdef DEBUG_misha
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /*TODO: remove this assert.
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * this is a temporary assert for debugging purposes:
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * we're probably doing something wrong with the packets if the miniport reports NDIS_STATUS_RESOURCES */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(!bResources);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifdef VBOXNETFLT_NO_PACKET_QUEUE
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (vboxNetFltWinPostIntnet(pNetFlt, pPacket, 0))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* drop it */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cRefCount = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync fStatus = vboxNetFltWinQuEnqueuePacket(pNetFlt, pPacket, bResources ? PACKET_COPY : 0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (fStatus == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bNetFltActive = false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync fWinIfActive = false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (bResources)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cRefCount = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync //NdisReturnPackets(&pPacket, 1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cRefCount = 1;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOX_LOOPBACK_USEFLAGS
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else if (vboxNetFltWinLbIsFromIntNet(pLb))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* the packet is from intnet, it has already been set to the host,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * no need for loopng it back to the host again */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* nothing else to do here, just return the packet */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cRefCount = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync //NdisReturnPackets(&pPacket, 1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cRefCount = vboxNetFltWinRecvPacketPassThru(pNetFlt, pPacket, bNetFltActive);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (cRefCount)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(cRefCount == 1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync fWinIfActive = false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync } while (FALSE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (bNetFltActive)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDereferenceNetFlt(pNetFlt);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else if (bPassThruActive)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDereferenceModePassThru(pNetFlt);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (fWinIfActive)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDereferenceWinIf(pNetFlt);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cRefCount = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync //NdisReturnPackets(&pPacket, 1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p), cRefCount (%d)\n", pNetFlt, cRefCount));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return cRefCount;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(bool) vboxNetFltWinPtCloseInterface(PVBOXNETFLTINS pNetFlt, PNDIS_STATUS pStatus)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync RTSpinlockAcquire(pNetFlt->hSpinlock);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pNetFlt->u.s.WinIf.StateFlags.fInterfaceClosing)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
c0b6af690ad705bddfa87c643b89770a7a0aaf5avboxsync RTSpinlockRelease(pNetFlt->hSpinlock);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pNetFlt->u.s.WinIf.hBinding == NULL)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
c0b6af690ad705bddfa87c643b89770a7a0aaf5avboxsync RTSpinlockRelease(pNetFlt->hSpinlock);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.StateFlags.fInterfaceClosing = TRUE;
c0b6af690ad705bddfa87c643b89770a7a0aaf5avboxsync RTSpinlockRelease(pNetFlt->hSpinlock);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisResetEvent(&pNetFlt->u.s.WinIf.OpenCloseEvent);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisCloseAdapter(pStatus, pNetFlt->u.s.WinIf.hBinding);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (*pStatus == NDIS_STATUS_PENDING)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisWaitEvent(&pNetFlt->u.s.WinIf.OpenCloseEvent, 0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *pStatus = pNetFlt->u.s.WinIf.OpenCloseStatus;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert (*pStatus == NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.hBinding = NULL;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return true;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic NDIS_STATUS vboxNetFltWinPtPnPSetPower(PVBOXNETFLTINS pNetFlt, NDIS_DEVICE_POWER_STATE enmPowerState)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_DEVICE_POWER_STATE enmPrevPowerState = vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.PtState);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync RTSpinlockAcquire(pNetFlt->hSpinlock);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSetPowerState(&pNetFlt->u.s.WinIf.PtState, enmPowerState);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.PtState) > NdisDeviceStateD0)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (enmPrevPowerState == NdisDeviceStateD0)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.StateFlags.fStandBy = TRUE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
c0b6af690ad705bddfa87c643b89770a7a0aaf5avboxsync RTSpinlockRelease(pNetFlt->hSpinlock);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinPtRequestsWaitComplete(pNetFlt);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinWaitDereference(&pNetFlt->u.s.WinIf.MpState);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinWaitDereference(&pNetFlt->u.s.WinIf.PtState);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* check packet pool is empty */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT cPPUsage = NdisPacketPoolUsage(pNetFlt->u.s.WinIf.hSendPacketPool);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(cPPUsage == 0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cPPUsage = NdisPacketPoolUsage(pNetFlt->u.s.WinIf.hRecvPacketPool);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(cPPUsage == 0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* for debugging only, ignore the err in release */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NOREF(cPPUsage);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(!pNetFlt->u.s.WinIf.StateFlags.fRequestInfo);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (enmPrevPowerState > NdisDeviceStateD0)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.StateFlags.fStandBy = FALSE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pNetFlt->u.s.WinIf.StateFlags.fRequestInfo & VBOXNDISREQUEST_QUEUED)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.StateFlags.fRequestInfo = VBOXNDISREQUEST_INPROGRESS;
c0b6af690ad705bddfa87c643b89770a7a0aaf5avboxsync RTSpinlockRelease(pNetFlt->hSpinlock);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinMpRequestPost(pNetFlt);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
c0b6af690ad705bddfa87c643b89770a7a0aaf5avboxsync RTSpinlockRelease(pNetFlt->hSpinlock);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return NDIS_STATUS_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic NDIS_STATUS vboxNetFltWinPtPnPEvent(IN NDIS_HANDLE hProtocolBindingContext, IN PNET_PNP_EVENT pNetPnPEvent)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p), NetEvent (%d)\n", pNetFlt, pNetPnPEvent->NetEvent));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync switch (pNetPnPEvent->NetEvent)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync case NetEventSetPower:
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_DEVICE_POWER_STATE enmPowerState = *((PNDIS_DEVICE_POWER_STATE)pNetPnPEvent->Buffer);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return vboxNetFltWinPtPnPSetPower(pNetFlt, enmPowerState);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync case NetEventReconfigure:
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!pNetFlt)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisReEnumerateProtocolBindings(g_VBoxNetFltGlobalsWin.Pt.hProtocol);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync default:
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return NDIS_STATUS_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), NetEvent (%d)\n", pNetFlt, pNetPnPEvent->NetEvent));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifdef __cplusplus
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# define PTCHARS_40(_p) ((_p).Ndis40Chars)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# define PTCHARS_40(_p) (_p)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/**
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * register the protocol edge
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtRegister(PVBOXNETFLTGLOBALS_PT pGlobalsPt, PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPathStr)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_PROTOCOL_CHARACTERISTICS PtChars;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STRING NameStr;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisInitUnicodeString(&NameStr, VBOXNETFLT_NAME_PROTOCOL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisZeroMemory(&PtChars, sizeof (PtChars));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PTCHARS_40(PtChars).MajorNdisVersion = VBOXNETFLT_VERSION_PT_NDIS_MAJOR;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PTCHARS_40(PtChars).MinorNdisVersion = VBOXNETFLT_VERSION_PT_NDIS_MINOR;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PTCHARS_40(PtChars).Name = NameStr;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PTCHARS_40(PtChars).OpenAdapterCompleteHandler = vboxNetFltWinPtOpenAdapterComplete;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PTCHARS_40(PtChars).CloseAdapterCompleteHandler = vboxNetFltWinPtCloseAdapterComplete;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PTCHARS_40(PtChars).SendCompleteHandler = vboxNetFltWinPtSendComplete;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PTCHARS_40(PtChars).TransferDataCompleteHandler = vboxNetFltWinPtTransferDataComplete;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PTCHARS_40(PtChars).ResetCompleteHandler = vboxNetFltWinPtResetComplete;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PTCHARS_40(PtChars).RequestCompleteHandler = vboxNetFltWinPtRequestComplete;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PTCHARS_40(PtChars).ReceiveHandler = vboxNetFltWinPtReceive;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PTCHARS_40(PtChars).ReceiveCompleteHandler = vboxNetFltWinPtReceiveComplete;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PTCHARS_40(PtChars).StatusHandler = vboxNetFltWinPtStatus;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PTCHARS_40(PtChars).StatusCompleteHandler = vboxNetFltWinPtStatusComplete;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PTCHARS_40(PtChars).BindAdapterHandler = vboxNetFltWinPtBindAdapter;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PTCHARS_40(PtChars).UnbindAdapterHandler = vboxNetFltWinPtUnbindAdapter;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PTCHARS_40(PtChars).UnloadHandler = vboxNetFltWinPtUnloadProtocol;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#if !defined(DEBUG_NETFLT_RECV)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PTCHARS_40(PtChars).ReceivePacketHandler = vboxNetFltWinPtReceivePacket;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PTCHARS_40(PtChars).PnPEventHandler = vboxNetFltWinPtPnPEvent;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisRegisterProtocol(&Status, &pGlobalsPt->hProtocol, &PtChars, sizeof (PtChars));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/**
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * deregister the protocol edge
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtDeregister(PVBOXNETFLTGLOBALS_PT pGlobalsPt)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!pGlobalsPt->hProtocol)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return NDIS_STATUS_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisDeregisterProtocol(&Status, pGlobalsPt->hProtocol);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert (Status == NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisZeroMemory(pGlobalsPt, sizeof (*pGlobalsPt));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}