VBoxNetFltP-win.cpp revision 4bfa7b58e362a1bca0628643c352c137900bf01a
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * VBoxNetFltP-win.cpp - Bridged Networking Driver, Windows Specific Code.
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * Protocol edge
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * Copyright (C) 2011 Oracle Corporation
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 * performs binding to the given adapter
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtDoBinding(PVBOXNETFLTINS pThis, PNDIS_STRING pOurDeviceName, PNDIS_STRING pBindToDeviceName)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pThis->u.s.WinIf.PtState.PowerState == NdisDeviceStateD3);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pThis->u.s.WinIf.PtState.OpState == kVBoxNetDevOpState_Deinitialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSetOpState(&pThis->u.s.WinIf.PtState, kVBoxNetDevOpState_Initializing);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS Status = vboxNetFltWinCopyString(&pThis->u.s.WinIf.MpDeviceName, pOurDeviceName);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSetPowerState(&pThis->u.s.WinIf.PtState, NdisDeviceStateD0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pThis->u.s.WinIf.OpenCloseStatus = NDIS_STATUS_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* Ethernet */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisOpenAdapter(&Status, &TmpStatus, &pThis->u.s.WinIf.hBinding, &iMedium,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync 0, /* IN UINT OpenOptions, (reserved, should be NULL) */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NULL /* IN PSTRING AddressingInformation OPTIONAL */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == NDIS_STATUS_PENDING || Status == STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisWaitEvent(&pThis->u.s.WinIf.OpenCloseEvent, 0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pThis->u.s.WinIf.enmMedium = aenmNdisMedium[iMedium];
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSetOpState(&pThis->u.s.WinIf.PtState, kVBoxNetDevOpState_Initialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinMpInitializeDevideInstance(pThis);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogRel((__FUNCTION__": vboxNetFltWinMpInitializeDevideInstance failed, Status 0x%x\n", Status));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSetOpState(&pThis->u.s.WinIf.PtState, kVBoxNetDevOpState_Deinitializing);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSetOpState(&pThis->u.s.WinIf.PtState, kVBoxNetDevOpState_Deinitialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogRel((__FUNCTION__"NdisOpenAdapter failed, Status (0x%x)", Status));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSetOpState(&pThis->u.s.WinIf.PtState, kVBoxNetDevOpState_Deinitialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic VOID vboxNetFltWinPtBindAdapter(OUT PNDIS_STATUS pStatus,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisOpenProtocolConfiguration(&Status, &hConfig, (PNDIS_STRING)pvSystemSpecific1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STRING UppedBindStr = NDIS_STRING_CONST("UpperBindings");
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisReadConfiguration(&Status, &pParam, hConfig, &UppedBindStr, NdisParameterString);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinPtInitBind(&pNetFlt, &pParam->ParameterData.StringData, pDeviceNameStr);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__": Status 0x%x\n", Status));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic VOID vboxNetFltWinPtOpenAdapterComplete(IN NDIS_HANDLE hProtocolBindingContext, IN NDIS_STATUS Status, IN NDIS_STATUS OpenErrorStatus)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLTINS pNetFlt =(PVBOXNETFLTINS)hProtocolBindingContext;
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 if (pNetFlt->u.s.WinIf.OpenCloseStatus == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogRel((__FUNCTION__" : Open Complete status is 0x%x", Status));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogRel((__FUNCTION__" : Adapter maintained status is 0x%x", pNetFlt->u.s.WinIf.OpenCloseStatus));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), Status (0x%x), OpenErrorStatus(0x%x)\n", pNetFlt, Status, OpenErrorStatus));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic void vboxNetFltWinPtRequestsWaitComplete(PVBOXNETFLTINS pNetFlt)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* wait for request to complete */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync while (vboxNetFltWinAtomicUoReadWinState(pNetFlt->u.s.WinIf.StateFlags).fRequestInfo == VBOXNDISREQUEST_INPROGRESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * If the below miniport is going to low power state, complete the queued request
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pNetFlt->u.s.WinIf.StateFlags.fRequestInfo & VBOXNDISREQUEST_QUEUED)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* mark the request as InProgress before posting it to RequestComplete */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.StateFlags.fRequestInfo = VBOXNDISREQUEST_INPROGRESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinPtRequestComplete(pNetFlt, &pNetFlt->u.s.WinIf.PassDownRequest, NDIS_STATUS_FAILURE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtDoUnbinding(PVBOXNETFLTINS pNetFlt, bool bOnUnbind)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("==>"__FUNCTION__": pNetFlt 0x%p\n", pNetFlt));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.PtState) == kVBoxNetDevOpState_Initialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ASMAtomicUoWriteBool(&pNetFlt->fDisconnectedFromHost, true);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ASMAtomicUoWriteBool(&pNetFlt->fRediscoveryPending, false);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ASMAtomicUoWriteU64(&pNetFlt->NanoTSLastRediscovery, NanoTS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.PtState, kVBoxNetDevOpState_Deinitializing);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitializing);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinWaitDereference(&pNetFlt->u.s.WinIf.MpState);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinWaitDereference(&pNetFlt->u.s.WinIf.PtState);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* check packet pool is empty */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cPPUsage = NdisPacketPoolUsage(pNetFlt->u.s.WinIf.hSendPacketPool);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cPPUsage = NdisPacketPoolUsage(pNetFlt->u.s.WinIf.hRecvPacketPool);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* for debugging only, ignore the err in release */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!bOnUnbind || !vboxNetFltWinMpDeInitializeDeviceInstance(pNetFlt, &Status))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.PtState, kVBoxNetDevOpState_Deinitialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitializing);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__": pNetFlt 0x%p\n", pNetFlt));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic VOID vboxNetFltWinPtUnbindAdapter(OUT PNDIS_STATUS pStatus,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p)\n", pNetFlt));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *pStatus = vboxNetFltWinDetachFromInterface(pNetFlt, true);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p)\n", pNetFlt));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS Status = vboxNetFltWinPtDeregister(&g_VBoxNetFltGlobalsWin.Pt);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__": PtDeregister Status (0x%x)\n", Status));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic VOID vboxNetFltWinPtCloseAdapterComplete(IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)ProtocolBindingContext;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p), Status (0x%x)\n", pNetFlt, Status));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pNetFlt->u.s.WinIf.OpenCloseStatus == NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pNetFlt->u.s.WinIf.OpenCloseStatus == NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pNetFlt->u.s.WinIf.OpenCloseStatus == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p), Status (0x%x)\n", pNetFlt, Status));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic VOID vboxNetFltWinPtResetComplete(IN NDIS_HANDLE hProtocolBindingContext, IN NDIS_STATUS Status)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("==>"__FUNCTION__" : pNetFlt 0x%p, Status 0x%x\n", hProtocolBindingContext, Status));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * should never be here
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__" : pNetFlt 0x%p, Status 0x%x\n", hProtocolBindingContext, Status));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic NDIS_STATUS vboxNetFltWinPtHandleQueryInfoComplete(PVBOXNETFLTINS pNetFlt, NDIS_STATUS Status)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_REQUEST pRequest = &pNetFlt->u.s.WinIf.PassDownRequest;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pRequest->DATA.QUERY_INFORMATION.InformationBufferLength >= sizeof (NDIS_PNP_CAPABILITIES))
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 = sizeof(NDIS_PNP_CAPABILITIES);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pRequest->DATA.QUERY_INFORMATION.InformationBufferLength >= sizeof (ULONG))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.fMacOptions = *(PULONG)pRequest->DATA.QUERY_INFORMATION.InformationBuffer;
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 /* 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 *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = sizeof (ULONG);
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 Assert(pNetFlt->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pRequest->DATA.QUERY_INFORMATION.InformationBufferLength >= sizeof (ULONG))
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 *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = sizeof (ULONG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pRequest->DATA.QUERY_INFORMATION.Oid != OID_PNP_QUERY_POWER);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *pNetFlt->u.s.WinIf.pcPDRBytesRW = pRequest->DATA.QUERY_INFORMATION.BytesWritten;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = pRequest->DATA.QUERY_INFORMATION.BytesNeeded;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic NDIS_STATUS vboxNetFltWinPtHandleSetInfoComplete(PVBOXNETFLTINS pNetFlt, NDIS_STATUS Status)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_REQUEST pRequest = &pNetFlt->u.s.WinIf.PassDownRequest;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pNetFlt->u.s.WinIf.StateFlags.fProcessingPacketFilter)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pNetFlt->enmTrunkState == INTNETTRUNKIFSTATE_ACTIVE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pRequest->DATA.SET_INFORMATION.InformationBufferLength >= sizeof (ULONG))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.fOurSetFilter = *((PULONG)pRequest->DATA.SET_INFORMATION.InformationBuffer);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pNetFlt->u.s.WinIf.fOurSetFilter == NDIS_PACKET_TYPE_PROMISCUOUS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = sizeof (ULONG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pNetFlt->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pRequest->DATA.SET_INFORMATION.InformationBufferLength >= sizeof (ULONG))
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 *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = sizeof (ULONG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.StateFlags.fProcessingPacketFilter = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pRequest->DATA.SET_INFORMATION.Oid != OID_PNP_SET_POWER);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *pNetFlt->u.s.WinIf.pcPDRBytesRW = pRequest->DATA.SET_INFORMATION.BytesRead;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = pRequest->DATA.SET_INFORMATION.BytesNeeded;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(VOID) vboxNetFltWinPtRequestComplete(NDIS_HANDLE hContext, PNDIS_REQUEST pNdisRequest, NDIS_STATUS Status)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_REQUEST pSynchRequest = pNetFlt->u.s.WinIf.pSynchRequest;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_OID Oid = pNetFlt->u.s.WinIf.PassDownRequest.DATA.SET_INFORMATION.Oid;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p), pNdisRequest (0x%p), Status (0x%x)\n", pNetFlt, pNdisRequest, Status));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* asynchronous completion of our sync request */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /*1.set the status */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* 2. set event */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync KeSetEvent(&pNetFlt->u.s.WinIf.hSynchCompletionEvent, 0, FALSE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* 3. return; */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p), pNdisRequest (0x%p), Status (0x%x)\n", pNetFlt, pNdisRequest, Status));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(&pNetFlt->u.s.WinIf.PassDownRequest == pNdisRequest);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pNetFlt->u.s.WinIf.StateFlags.fRequestInfo == VBOXNDISREQUEST_INPROGRESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinPtHandleQueryInfoComplete(pNetFlt, Status);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMQueryInformationComplete(pNetFlt->u.s.WinIf.hMiniport, Status);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinPtHandleSetInfoComplete(pNetFlt, Status);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMSetInformationComplete(pNetFlt->u.s.WinIf.hMiniport, Status);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p), pNdisRequest (0x%p), Status (0x%x)\n", pNetFlt, pNdisRequest, Status));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic VOID vboxNetFltWinPtStatus(IN NDIS_HANDLE hProtocolBindingContext, IN NDIS_STATUS GeneralStatus, IN PVOID pvStatusBuffer, IN UINT cbStatusBuffer)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p), GeneralStatus (0x%x)\n", pNetFlt, GeneralStatus));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (VBOXNETFLT_PT_STATUS_IS_FILTERED(GeneralStatus))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.MpIndicatedMediaStatus = GeneralStatus;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.MpUnindicatedMediaStatus = GeneralStatus;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p), GeneralStatus (0x%x)\n", pNetFlt, GeneralStatus));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic VOID vboxNetFltWinPtStatusComplete(IN NDIS_HANDLE hProtocolBindingContext)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMIndicateStatusComplete(pNetFlt->u.s.WinIf.hMiniport);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic VOID vboxNetFltWinPtSendComplete(IN NDIS_HANDLE hProtocolBindingContext, IN PNDIS_PACKET pPacket, IN NDIS_STATUS Status)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLT_PKTRSVD_PT pSendInfo = (PVBOXNETFLT_PKTRSVD_PT)pPacket->ProtocolReserved;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p), pPacket (0x%p), Status (0x%x)\n", pNetFlt, pPacket, Status));
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 NdisIMCopySendCompletePerPacketInfo(pOrigPacket, pPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* the ptk was posted from the upperlying protocol */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMSendComplete(pNetFlt->u.s.WinIf.hMiniport, pOrigPacket, Status);
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 LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), pPacket (0x%p), Status (0x%x)\n", pNetFlt, pPacket, Status));
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
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic bool vboxNetFltWinRemovePacketFromList(PVBOXNETFLT_INTERLOCKED_SINGLE_LIST pList, PNDIS_PACKET pPacket)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLT_PKTRSVD_TRANSFERDATA_PT pTDR = (PVBOXNETFLT_PKTRSVD_TRANSFERDATA_PT)pPacket->ProtocolReserved;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return vboxNetFltWinInterlockedSearchListEntry(pList, &pTDR->ListEntry, true /* remove*/);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * puts the packet to the tail of the list
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic void vboxNetFltWinPutPacketToList(PVBOXNETFLT_INTERLOCKED_SINGLE_LIST pList, PNDIS_PACKET pPacket, PNDIS_BUFFER pOrigBuffer)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLT_PKTRSVD_TRANSFERDATA_PT pTDR = (PVBOXNETFLT_PKTRSVD_TRANSFERDATA_PT)pPacket->ProtocolReserved;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinInterlockedPutTail(pList, &pTDR->ListEntry);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic bool vboxNetFltWinPtTransferDataCompleteActive(PVBOXNETFLTINS pNetFltIf, PNDIS_PACKET pPacket, NDIS_STATUS Status)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!vboxNetFltWinRemovePacketFromList(&pNetFltIf->u.s.WinIf.TransferDataList, pPacket))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pTDR = (PVBOXNETFLT_PKTRSVD_TRANSFERDATA_PT)pPacket->ProtocolReserved;
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 /* should not be here */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_PACKET pLb = vboxNetFltWinLbSearchLoopBack(pNetFltIf, pPacket, false);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* should not be here */
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 /* 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 if (vboxNetFltWinPostIntnet(pNetFltIf, pPacket, 0))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* drop it */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMIndicateReceivePacket(pNetFltIf->u.s.WinIf.hMiniport, &pPacket, 1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinQuEnqueuePacket(pNetFltIf, pPacket, PACKET_MINE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* we are here because of error either in data transfer or in enqueueing the packet */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync } while (0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return true;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic VOID vboxNetFltWinPtTransferDataComplete(IN NDIS_HANDLE hProtocolBindingContext,
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 NdisMTransferDataComplete(pNetFlt->u.s.WinIf.hMiniport,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* else - all processing is done with vboxNetFltWinPtTransferDataCompleteActive already */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), pPacket (0x%p), Status (0x%x), cbTransfered (%d)\n", pNetFlt, pPacket, Status, cbTransferred));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic INT vboxNetFltWinRecvPacketPassThru(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket, BOOLEAN bForceIndicate)
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 NdisMIndicateReceivePacket(pNetFlt->u.s.WinIf.hMiniport, &pMyPacket, 1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * process the packet receive in a "passthru" mode
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic NDIS_STATUS vboxNetFltWinRecvPassThru(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisDprAllocatePacket(&Status, &pMyPacket, pNetFlt->u.s.WinIf.hRecvPacketPool);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinCopyPacketInfoOnRecv(pMyPacket, pPacket, true /* force NDIS_STATUS_RESOURCES */);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(NDIS_GET_PACKET_STATUS(pMyPacket) == NDIS_STATUS_RESOURCES);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMIndicateReceivePacket(pNetFlt->u.s.WinIf.hMiniport, &pMyPacket, 1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic VOID vboxNetFltWinRecvIndicatePassThru(PVBOXNETFLTINS pNetFlt, NDIS_HANDLE MacReceiveContext,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVOID pHeaderBuffer, UINT cbHeaderBuffer, PVOID pLookAheadBuffer, UINT cbLookAheadBuffer, UINT cbPacket)
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 Assert(Proc < RT_ELEMENTS(pNetFlt->u.s.WinIf.abIndicateRxComplete));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.abIndicateRxComplete[Proc] = TRUE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMEthIndicateReceive(pNetFlt->u.s.WinIf.hMiniport,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * process the ProtocolReceive in an "active" mode
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
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic NDIS_STATUS vboxNetFltWinPtReceiveActive(PVBOXNETFLTINS pNetFlt, NDIS_HANDLE MacReceiveContext, PVOID pHeaderBuffer, UINT cbHeaderBuffer,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVOID pLookaheadBuffer, UINT cbLookaheadBuffer, UINT cbPacket)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (cbHeaderBuffer != VBOXNETFLT_PACKET_ETHEADER_SIZE)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* allocate SG buffer */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinAllocSG(cbPacket + cbHeaderBuffer, &pSG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMoveMappedMemory(pRcvData, pHeaderBuffer, cbHeaderBuffer);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pLb = vboxNetFltWinLbSearchLoopBackBySG(pNetFlt, pSG, false);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* should not be here */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pMyPacket = vboxNetFltWinNdisPacketFromSG(pNetFlt, /* PVBOXNETFLTINS */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync false, /* bool bToWire */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync false); /* bool bCopyMemory */
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 /* enqueue SG */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (vboxNetFltWinPostIntnet(pNetFlt, pSG, VBOXNETFLT_PACKET_SG))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* drop it */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_PACKET pMyPacket = vboxNetFltWinNdisPacketFromSG(pNetFlt, /* PVBOXNETFLTINS */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync false, /* bool bToWire */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync false); /* bool bCopyMemory */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_SET_PACKET_STATUS(pMyPacket, NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("non-ndis packet info, packet created (%p)\n", pMyPacket));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMIndicateReceivePacket(pNetFlt->u.s.WinIf.hMiniport, &pMyPacket, 1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinQuEnqueuePacket(pNetFlt, pSG, PACKET_SG | PACKET_MINE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* allocate NDIS Packet buffer */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisAllocatePacket(&Status, &pPacket, pNetFlt->u.s.WinIf.hRecvPacketPool);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* set "don't loopback" flags */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisGetPacketFlags(pPacket) = g_VBoxNetFltGlobalsWin.fPacketDontLoopBack;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinMemAlloc((PVOID*)(&pMemBuf), cbBuf);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisAllocateBuffer(&Status, &pTransferBuffer, pNetFlt->u.s.WinIf.hRecvBufferPool, pMemBuf + cbHeaderBuffer, cbPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisAllocateBuffer(&Status, &pOrigBuffer, pNetFlt->u.s.WinIf.hRecvBufferPool, pMemBuf, cbBuf);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMoveMappedMemory(pMemBuf, pHeaderBuffer, cbHeaderBuffer);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinPutPacketToList(&pNetFlt->u.s.WinIf.TransferDataList, pPacket, pOrigBuffer);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisTransferData(&Status, pNetFlt->u.s.WinIf.hBinding, MacReceiveContext,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync 0, /* ByteOffset */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinPtTransferDataComplete(pNetFlt, pPacket, Status, cbTransferred);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync } while (0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic NDIS_STATUS vboxNetFltWinPtReceive(IN NDIS_HANDLE hProtocolBindingContext,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bool fWinIfActive = vboxNetFltWinReferenceWinIfNetFlt(pNetFlt, &bNetFltActive);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pPacket = NdisGetReceivedPacket(pNetFlt->u.s.WinIf.hBinding, MacReceiveContext);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* nothing else to do here, just return the packet */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync //NdisReturnPackets(&pPacket, 1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pLb = vboxNetFltWinLbSearchLoopBack(pNetFlt, pPacket, false);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* drop it */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinQuEnqueuePacket(pNetFlt, pPacket, PACKET_COPY);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync //NdisReturnPackets(&pPacket, 1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* nothing else to do here, just return the packet */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync //NdisReturnPackets(&pPacket, 1);
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 Status = vboxNetFltWinRecvPassThru(pNetFlt, pPacket);
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 /* intnet processing failed - fall back to no-packet mode */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif /* #ifndef DEBUG_NETFLT_RECV_NOPACKET */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinPtReceiveActive(pNetFlt, MacReceiveContext, pHeaderBuffer, cbHeaderBuffer,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* this is a loopback packet, nothing to do here */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* should not be here */
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 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 } while (0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic VOID vboxNetFltWinPtReceiveComplete(NDIS_HANDLE hProtocolBindingContext)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext;
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 Assert(iProc < RT_ELEMENTS(pNetFlt->u.s.WinIf.abIndicateRxComplete));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (hMiniport != NULL && pNetFlt->u.s.WinIf.abIndicateRxComplete[iProc])
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.abIndicateRxComplete[iProc] = FALSE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic INT vboxNetFltWinPtReceivePacket(NDIS_HANDLE hProtocolBindingContext, PNDIS_PACKET pPacket)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bool fWinIfActive = vboxNetFltWinReferenceWinIfNetFlt(pNetFlt, &bNetFltActive);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* nothing else to do here, just return the packet */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync //NdisReturnPackets(&pPacket, 1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_PACKET pLb = vboxNetFltWinLbSearchLoopBack(pNetFlt, pPacket, false);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bool bResources = NDIS_GET_PACKET_STATUS(pPacket) == NDIS_STATUS_RESOURCES;
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 /* drop it */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync fStatus = vboxNetFltWinQuEnqueuePacket(pNetFlt, pPacket, bResources ? PACKET_COPY : 0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync //NdisReturnPackets(&pPacket, 1);
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 //NdisReturnPackets(&pPacket, 1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cRefCount = vboxNetFltWinRecvPacketPassThru(pNetFlt, pPacket, bNetFltActive);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync //NdisReturnPackets(&pPacket, 1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p), cRefCount (%d)\n", pNetFlt, cRefCount));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(bool) vboxNetFltWinPtCloseInterface(PVBOXNETFLTINS pNetFlt, PNDIS_STATUS pStatus)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pNetFlt->u.s.WinIf.StateFlags.fInterfaceClosing)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.StateFlags.fInterfaceClosing = TRUE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisResetEvent(&pNetFlt->u.s.WinIf.OpenCloseEvent);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisCloseAdapter(pStatus, pNetFlt->u.s.WinIf.hBinding);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisWaitEvent(&pNetFlt->u.s.WinIf.OpenCloseEvent, 0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return true;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic NDIS_STATUS vboxNetFltWinPtPnPSetPower(PVBOXNETFLTINS pNetFlt, NDIS_DEVICE_POWER_STATE enmPowerState)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_DEVICE_POWER_STATE enmPrevPowerState = vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.PtState);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSetPowerState(&pNetFlt->u.s.WinIf.PtState, enmPowerState);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.PtState) > NdisDeviceStateD0)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinWaitDereference(&pNetFlt->u.s.WinIf.MpState);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinWaitDereference(&pNetFlt->u.s.WinIf.PtState);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* check packet pool is empty */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT cPPUsage = NdisPacketPoolUsage(pNetFlt->u.s.WinIf.hSendPacketPool);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cPPUsage = NdisPacketPoolUsage(pNetFlt->u.s.WinIf.hRecvPacketPool);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* for debugging only, ignore the err in release */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(!pNetFlt->u.s.WinIf.StateFlags.fRequestInfo);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pNetFlt->u.s.WinIf.StateFlags.fRequestInfo & VBOXNDISREQUEST_QUEUED)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.StateFlags.fRequestInfo = VBOXNDISREQUEST_INPROGRESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic NDIS_STATUS vboxNetFltWinPtPnPEvent(IN NDIS_HANDLE hProtocolBindingContext, IN PNET_PNP_EVENT pNetPnPEvent)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p), NetEvent (%d)\n", pNetFlt, pNetPnPEvent->NetEvent));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_DEVICE_POWER_STATE enmPowerState = *((PNDIS_DEVICE_POWER_STATE)pNetPnPEvent->Buffer);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return vboxNetFltWinPtPnPSetPower(pNetFlt, enmPowerState);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisReEnumerateProtocolBindings(g_VBoxNetFltGlobalsWin.Pt.hProtocol);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), NetEvent (%d)\n", pNetFlt, pNetPnPEvent->NetEvent));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * register the protocol edge
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtRegister(PVBOXNETFLTGLOBALS_PT pGlobalsPt, PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPathStr)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisInitUnicodeString(&NameStr, VBOXNETFLT_NAME_PROTOCOL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PTCHARS_40(PtChars).MajorNdisVersion = VBOXNETFLT_VERSION_PT_NDIS_MAJOR;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PTCHARS_40(PtChars).MinorNdisVersion = VBOXNETFLT_VERSION_PT_NDIS_MINOR;
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 PTCHARS_40(PtChars).ReceivePacketHandler = vboxNetFltWinPtReceivePacket;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PTCHARS_40(PtChars).PnPEventHandler = vboxNetFltWinPtPnPEvent;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisRegisterProtocol(&Status, &pGlobalsPt->hProtocol, &PtChars, sizeof (PtChars));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * deregister the protocol edge
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtDeregister(PVBOXNETFLTGLOBALS_PT pGlobalsPt)