3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/* $Id$ */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/** @file
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * VBoxNetFltRt-win.cpp - Bridged Networking Driver, Windows Specific Code.
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * NetFlt Runtime
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#include <VBox/intnetinline.h>
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#include <iprt/thread.h>
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/** represents the job element of the job queue
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * see comments for VBOXNETFLT_JOB_QUEUE */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsynctypedef struct VBOXNETFLT_JOB
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /** link in the job queue */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LIST_ENTRY ListEntry;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /** job function to be executed */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PFNVBOXNETFLT_JOB_ROUTINE pfnRoutine;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /** parameter to be passed to the job function */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVOID pContext;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /** event that will be fired on job completion */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync KEVENT CompletionEvent;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /** true if the job manager should use the completion even for completion indication, false-otherwise*/
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bool bUseCompletionEvent;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync} VBOXNETFLT_JOB, *PVBOXNETFLT_JOB;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/**
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * represents the queue of jobs processed by the worker thread
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * we use the thread to process tasks which are required to be done at passive level
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * our callbacks may be called at APC level by IntNet, there are some tasks that we can not create at APC,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * e.g. thread creation. This is why we schedule such jobs to the worker thread working at passive level
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsynctypedef struct VBOXNETFLT_JOB_QUEUE
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* jobs */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LIST_ENTRY Jobs;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* we are using ExInterlocked..List functions to access the jobs list */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync KSPIN_LOCK Lock;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /** this event is used to initiate a job worker thread kill */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync KEVENT KillEvent;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /** this event is used to notify a worker thread that jobs are added to the queue */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync KEVENT NotifyEvent;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /** worker thread */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PKTHREAD pThread;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync} VBOXNETFLT_JOB_QUEUE, *PVBOXNETFLT_JOB_QUEUE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsynctypedef struct _CREATE_INSTANCE_CONTEXT
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_STRING pOurName;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_STRING pBindToName;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_HANDLE hMiniportAdapter;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_HANDLE hWrapperConfigurationContext;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}CREATE_INSTANCE_CONTEXT, *PCREATE_INSTANCE_CONTEXT;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/*contexts used for our jobs */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/* Attach context */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsynctypedef struct _ATTACH_INFO
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLTINS pNetFltIf;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PCREATE_INSTANCE_CONTEXT pCreateContext;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bool fRediscovery;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync int Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}ATTACH_INFO, *PATTACH_INFO;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/* general worker context */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsynctypedef struct _WORKER_INFO
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLTINS pNetFltIf;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync int Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}WORKER_INFO, *PWORKER_INFO;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/* idc initialization */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsynctypedef struct _INIT_IDC_INFO
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync VBOXNETFLT_JOB Job;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bool bInitialized;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync volatile bool bStop;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync volatile int rc;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync KEVENT hCompletionEvent;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}INIT_IDC_INFO, *PINIT_IDC_INFO;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/** globals */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/** global job queue. some operations are required to be done at passive level, e.g. thread creation, adapter bind/unbind initiation,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * while IntNet typically calls us APC_LEVEL, so we just create a system thread in our DriverEntry and enqueue the jobs to that thread */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic VBOXNETFLT_JOB_QUEUE g_VBoxJobQueue;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncvolatile static bool g_bVBoxIdcInitialized;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncINIT_IDC_INFO g_VBoxInitIdcInfo;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/**
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * The (common) global data.
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic VBOXNETFLTGLOBALS g_VBoxNetFltGlobals;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/* win-specific global data */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncVBOXNETFLTGLOBALS_WIN g_VBoxNetFltGlobalsWin = {0};
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#define LIST_ENTRY_2_JOB(pListEntry) \
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ( (PVBOXNETFLT_JOB)((uint8_t *)(pListEntry) - RT_OFFSETOF(VBOXNETFLT_JOB, ListEntry)) )
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic int vboxNetFltWinAttachToInterface(PVBOXNETFLTINS pThis, void * pContext, bool fRediscovery);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic int vboxNetFltWinConnectIt(PVBOXNETFLTINS pThis);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic int vboxNetFltWinTryFiniIdc();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic void vboxNetFltWinFiniNetFltBase();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic int vboxNetFltWinInitNetFltBase();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic int vboxNetFltWinFiniNetFlt();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic int vboxNetFltWinStartInitIdcProbing();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic int vboxNetFltWinStopInitIdcProbing();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/** makes the current thread to sleep for the given number of miliseconds */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(void) vboxNetFltWinSleep(ULONG milis)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync RTThreadSleep(milis);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/** wait for the given device to be dereferenced */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(void) vboxNetFltWinWaitDereference(PVBOXNETFLT_WINIF_DEVICE pState)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifdef DEBUG
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync uint64_t StartNanoTS = RTTimeSystemNanoTS();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync uint64_t CurNanoTS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync while (ASMAtomicUoReadU32((volatile uint32_t *)&pState->cReferences))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSleep(2);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifdef DEBUG
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync CurNanoTS = RTTimeSystemNanoTS();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (CurNanoTS - StartNanoTS > 20000000)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogRel(("device not idle"));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertFailed();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync// break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/**
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * mem functions
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/* allocates and zeroes the nonpaged memory of a given size */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinMemAlloc(PVOID* ppMemBuf, UINT cbLength)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifdef DEBUG_NETFLT_USE_EXALLOC
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *ppMemBuf = ExAllocatePoolWithTag(NonPagedPool, cbLength, VBOXNETFLT_MEM_TAG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (*ppMemBuf)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisZeroMemory(*ppMemBuf, cbLength);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return NDIS_STATUS_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return NDIS_STATUS_FAILURE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS fStatus = NdisAllocateMemoryWithTag(ppMemBuf, cbLength, VBOXNETFLT_MEM_TAG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (fStatus == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisZeroMemory(*ppMemBuf, cbLength);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return fStatus;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/* frees memory allocated with vboxNetFltWinMemAlloc */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(void) vboxNetFltWinMemFree(PVOID pvMemBuf)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifdef DEBUG_NETFLT_USE_EXALLOC
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ExFreePool(pvMemBuf);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisFreeMemory(pvMemBuf, 0, 0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETFLT_NO_PACKET_QUEUE
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/* initializes packet info pool and allocates the cSize packet infos for the pool */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic NDIS_STATUS vboxNetFltWinPpAllocatePacketInfoPool(PVBOXNETFLT_PACKET_INFO_POOL pPool, UINT cSize)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT cbBufSize = sizeof(PACKET_INFO)*cSize;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PACKET_INFO * pPacketInfos;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS fStatus;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT i;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(cSize > 0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync INIT_INTERLOCKED_PACKET_QUEUE(&pPool->Queue);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync fStatus = vboxNetFltWinMemAlloc((PVOID*)&pPacketInfos, cbBufSize);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (fStatus == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLTPACKET_INFO pInfo;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pPool->pBuffer = pPacketInfos;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync for (i = 0; i < cSize; i++)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pInfo = &pPacketInfos[i];
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinQuEnqueueTail(&pPool->Queue.Queue, pInfo);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pInfo->pPool = pPool;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertFailed();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return fStatus;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/* frees the packet info pool */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncVOID vboxNetFltWinPpFreePacketInfoPool(PVBOXNETFLT_PACKET_INFO_POOL pPool)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinMemFree(pPool->pBuffer);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync FINI_INTERLOCKED_PACKET_QUEUE(&pPool->Queue)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/**
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * copies one string to another. in case the destination string size is not enough to hold the complete source string
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * does nothing and returns NDIS_STATUS_RESOURCES .
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinCopyString(PNDIS_STRING pDst, PNDIS_STRING pSrc)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pDst != pSrc)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pDst->MaximumLength < pSrc->Length)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertFailed();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = NDIS_STATUS_RESOURCES;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pDst->Length = pSrc->Length;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pDst->Buffer != pSrc->Buffer)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMoveMemory(pDst->Buffer, pSrc->Buffer, pSrc->Length);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/************************************************************************************
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * PINTNETSG pSG manipulation functions
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ************************************************************************************/
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/* moves the contents of the given NDIS_BUFFER and all other buffers chained to it to the PINTNETSG
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * the PINTNETSG is expected to contain one segment whose bugger is large enough to maintain
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * the contents of the given NDIS_BUFFER and all other buffers chained to it */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic NDIS_STATUS vboxNetFltWinNdisBufferMoveToSG0(PNDIS_BUFFER pBuffer, PINTNETSG pSG)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT cSegs = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PINTNETSEG paSeg;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync uint8_t * ptr;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVOID pVirtualAddress;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT cbCurrentLength;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS fStatus = NDIS_STATUS_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pSG->cSegsAlloc == 1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync paSeg = pSG->aSegs;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ptr = (uint8_t*)paSeg->pv;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync paSeg->cb = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync paSeg->Phys = NIL_RTHCPHYS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pSG->cbTotal = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(paSeg->pv);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync while (pBuffer)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisQueryBufferSafe(pBuffer, &pVirtualAddress, &cbCurrentLength, NormalPagePriority);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!pVirtualAddress)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync fStatus = NDIS_STATUS_FAILURE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pSG->cbTotal += cbCurrentLength;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync paSeg->cb += cbCurrentLength;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMoveMemory(ptr, pVirtualAddress, cbCurrentLength);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ptr += cbCurrentLength;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisGetNextBuffer(pBuffer, &pBuffer);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (fStatus == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pSG->cSegsUsed = 1;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pSG->cbTotal == paSeg->cb);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return fStatus;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/* converts the PNDIS_BUFFER to PINTNETSG by making the PINTNETSG segments to point to the memory buffers the
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * ndis buffer(s) point to (as opposed to vboxNetFltWinNdisBufferMoveToSG0 which copies the memory from ndis buffers(s) to PINTNETSG) */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic NDIS_STATUS vboxNetFltWinNdisBuffersToSG(PNDIS_BUFFER pBuffer, PINTNETSG pSG)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT cSegs = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVOID pVirtualAddress;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT cbCurrentLength;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync while (pBuffer)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisQueryBufferSafe(pBuffer, &pVirtualAddress, &cbCurrentLength, NormalPagePriority);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!pVirtualAddress)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = NDIS_STATUS_FAILURE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pSG->cbTotal += cbCurrentLength;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pSG->aSegs[cSegs].cb = cbCurrentLength;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pSG->aSegs[cSegs].pv = pVirtualAddress;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pSG->aSegs[cSegs].Phys = NIL_RTHCPHYS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cSegs++;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisGetNextBuffer(pBuffer, &pBuffer);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertFatal(cSegs <= pSG->cSegsAlloc);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pSG->cSegsUsed = cSegs;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic void vboxNetFltWinDeleteSG(PINTNETSG pSG)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinMemFree(pSG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic PINTNETSG vboxNetFltWinCreateSG(uint32_t cSegs)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PINTNETSG pSG;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NTSTATUS Status = vboxNetFltWinMemAlloc((PVOID*)&pSG, RT_OFFSETOF(INTNETSG, aSegs[cSegs]));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync IntNetSgInitTempSegs(pSG, 0 /*cbTotal*/, cSegs, 0 /*cSegsUsed*/);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return pSG;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return NULL;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/************************************************************************************
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * packet queue functions
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ************************************************************************************/
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETFLT_NO_PACKET_QUEUE
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#if !defined(VBOXNETADP)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic NDIS_STATUS vboxNetFltWinQuPostPacket(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket, PINTNETSG pSG, uint32_t fFlags
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# ifdef DEBUG_NETFLT_PACKETS
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync , PNDIS_PACKET pTmpPacket
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync )
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_PACKET pMyPacket;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bool bSrcHost = fFlags & PACKET_SRC_HOST;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("posting packet back to driver stack..\n"));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!pPacket)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* INTNETSG was in the packet queue, create a new NdisPacket from INTNETSG*/
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pMyPacket = vboxNetFltWinNdisPacketFromSG(pNetFlt,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pSG, /* PINTNETSG */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pSG, /* PVOID pBufToFree */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bSrcHost, /* bool bToWire */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync false); /* bool bCopyMemory */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pMyPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_SET_PACKET_STATUS(pMyPacket, NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync DBG_CHECK_PACKET_AND_SG(pMyPacket, pSG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifdef DEBUG_NETFLT_PACKETS
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pTmpPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync DBG_CHECK_PACKET_AND_SG(pTmpPacket, pSG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync DBG_CHECK_PACKETS(pTmpPacket, pMyPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("non-ndis packet info, packet created (%p)\n", pMyPacket));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* NDIS_PACKET was in the packet queue */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync DBG_CHECK_PACKET_AND_SG(pPacket, pSG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!(fFlags & PACKET_MINE))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* the packet is the one that was passed to us in send/receive callback
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * According to the DDK, we can not post it further,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * instead we should allocate our own packet.
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * So, allocate our own packet (pMyPacket) and copy the packet info there */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (bSrcHost)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinPrepareSendPacket(pNetFlt, pPacket, &pMyPacket/*, true*/);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("packet from wire, packet created (%p)\n", pMyPacket));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinPrepareRecvPacket(pNetFlt, pPacket, &pMyPacket, false);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("packet from wire, packet created (%p)\n", pMyPacket));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* the packet enqueued is ours, simply assign pMyPacket and zero pPacket */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pMyPacket = pPacket;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pPacket = NULL;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pMyPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pMyPacket)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* we have successfully initialized our packet, post it to the host or to the wire */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (bSrcHost)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#if defined(DEBUG_NETFLT_PACKETS) || !defined(VBOX_LOOPBACK_USEFLAGS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinLbPutSendPacket(pNetFlt, pMyPacket, false /* bFromIntNet */);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisSend(&Status, pNetFlt->u.s.hBinding, pMyPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status != NDIS_STATUS_PENDING)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#if defined(DEBUG_NETFLT_PACKETS) || !defined(VBOX_LOOPBACK_USEFLAGS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* the status is NOT pending, complete the packet */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bool bTmp = vboxNetFltWinLbRemoveSendPacket(pNetFlt, pMyPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(bTmp);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pPacket)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("status is not pending, completing packet (%p)\n", pPacket));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisIMCopySendCompletePerPacketInfo (pPacket, pMyPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisFreePacket(pMyPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* should never be here since the PINTNETSG is stored only when the underlying miniport
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * indicates NDIS_STATUS_RESOURCES, we should never have this when processing
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * the "from-host" packets */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertFailed();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("status is not pending, freeing myPacket (%p)\n", pMyPacket));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinFreeSGNdisPacket(pMyPacket, false);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMIndicateReceivePacket(pNetFlt->u.s.hMiniport, &pMyPacket, 1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = NDIS_STATUS_PENDING;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* the packet receive completion is always indicated via MiniportReturnPacket */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /*we failed to create our packet */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertFailed();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = NDIS_STATUS_FAILURE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic bool vboxNetFltWinQuProcessInfo(PVBOXNETFLTINS pNetFltIf, PPACKET_QUEUE_WORKER pWorker, PVOID pvPacket, const UINT fFlags)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pNetFltIf, PVOID pvPacket, const UINT fFlags)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_PACKET pPacket = NULL;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PINTNETSG pSG = NULL;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bool bSrcHost;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bool bDropIt;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# ifndef VBOXNETFLT_NO_PACKET_QUEUE
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bool bPending;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifdef VBOXNETFLT_NO_PACKET_QUEUE
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bool bDeleteSG = false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifdef DEBUG_NETFLT_PACKETS
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* packet used for matching */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_PACKET pTmpPacket = NULL;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bSrcHost = (fFlags & VBOXNETFLT_PACKET_SRC_HOST) != 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* we first need to obtain the INTNETSG to be passed to intnet */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* the queue may contain two "types" of packets:
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * the NDIS_PACKET and the INTNETSG.
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * I.e. on send/receive we typically enqueue the NDIS_PACKET passed to us by ndis,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * however in case our ProtocolReceive is called or the packet's status is set to NDIS_STSTUS_RESOURCES
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * in ProtocolReceivePacket, we must return the packet immediately on ProtocolReceive*** exit
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * In this case we allocate the INTNETSG, copy the ndis packet data there and enqueue it.
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * In this case the packet info flags has the VBOXNETFLT_PACKET_SG fag set
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * Besides that the NDIS_PACKET contained in the queue could be either the one passed to us in our send/receive callback
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * or the one created by us. The latter is possible in case our ProtocolReceive callback is called and we call NdisTransferData
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * in this case we need to allocate the packet the data to be transferred to.
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * If the enqueued packet is the one allocated by us the VBOXNETFLT_PACKET_MINE flag is set
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if ((fFlags & VBOXNETFLT_PACKET_SG) == 0)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* we have NDIS_PACKET enqueued, we need to convert it to INTNETSG to be passed to intnet */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_BUFFER pCurrentBuffer = NULL;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT cBufferCount;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT uBytesCopied = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT cbPacketLength;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pPacket = (PNDIS_PACKET)pvPacket;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("ndis packet info, packet (%p)\n", pPacket));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("preparing pSG"));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisQueryPacket(pPacket, NULL, &cBufferCount, &pCurrentBuffer, &cbPacketLength);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(cBufferCount);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifdef VBOXNETFLT_NO_PACKET_QUEUE
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pSG = vboxNetFltWinCreateSG(cBufferCount);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* we can not allocate the INTNETSG on stack since in this case we may get stack overflow
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * somewhere outside of our driver (3 pages of system thread stack does not seem to be enough)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * since we have a "serialized" packet processing, i.e. all packets are being processed and passed
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * to intnet by this thread, we just use one previously allocated INTNETSG which is stored in PVBOXNETFLTINS */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pSG = pWorker->pSG;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (cBufferCount > pSG->cSegsAlloc)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pSG = vboxNetFltWinCreateSG(cBufferCount + 2);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pSG)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDeleteSG(pWorker->pSG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pWorker->pSG = pSG;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogRel(("Failed to reallocate the pSG\n"));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pSG)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifdef VBOXNETFLT_NO_PACKET_QUEUE
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bDeleteSG = true;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* reinitialize */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync IntNetSgInitTempSegs(pSG, 0 /*cbTotal*/, pSG->cSegsAlloc, 0 /*cSegsUsed*/);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* convert the ndis buffers to INTNETSG */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinNdisBuffersToSG(pCurrentBuffer, pSG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status != NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pSG = NULL;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync DBG_CHECK_PACKET_AND_SG(pPacket, pSG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* we have the INTNETSG enqueued. (see the above comment explaining why/when this may happen)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * just use the INTNETSG to pass it to intnet */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* the PINTNETSG is stored only when the underlying miniport
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * indicates NDIS_STATUS_RESOURCES, we should never have this when processing
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * the "from-host" packedts */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(!bSrcHost);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pSG = (PINTNETSG)pvPacket;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("not ndis packet info, pSG (%p)\n", pSG));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifdef DEBUG_NETFLT_PACKETS
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!pPacket && !pTmpPacket)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* create tmp packet that woud be used for matching */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pTmpPacket = vboxNetFltWinNdisPacketFromSG(pNetFltIf,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pSG, /* PINTNETSG */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pSG, /* PVOID pBufToFree */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bSrcHost, /* bool bToWire */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync true); /* bool bCopyMemory */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_SET_PACKET_STATUS(pTmpPacket, NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync DBG_CHECK_PACKET_AND_SG(pTmpPacket, pSG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pTmpPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync do
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* the pSG was successfully initialized, post it to the netFlt*/
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bDropIt = pSG ? pNetFltIf->pSwitchPort->pfnRecv(pNetFltIf->pSwitchPort, NULL /* pvIf */, pSG,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bSrcHost ? INTNETTRUNKDIR_HOST : INTNETTRUNKDIR_WIRE
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync )
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync : false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pSG)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFltIf->pSwitchPort->pfnRecv(pNetFltIf->pSwitchPort, NULL /* pvIf */, pSG, INTNETTRUNKDIR_HOST);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync STATISTIC_INCREASE(pNetFltIf->u.s.WinIf.cTxSuccess);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync STATISTIC_INCREASE(pNetFltIf->u.s.WinIf.cTxError);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETFLT_NO_PACKET_QUEUE
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# if !defined(VBOXNETADP)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!bDropIt)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinQuPostPacket(pNetFltIf, pPacket, pSG, fFlags
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# ifdef DEBUG_NETFLT_PACKETS
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync , pTmpPacket
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync );
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_PENDING)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* we will process packet completion in the completion routine */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bPending = true;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = NDIS_STATUS_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* drop it */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pPacket)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!(fFlags & PACKET_MINE))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# if !defined(VBOXNETADP)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* complete the packets */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (fFlags & PACKET_SRC_HOST)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/* NDIS_SET_PACKET_STATUS(pPacket, Status); */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMSendComplete(pNetFltIf->u.s.hMiniport, pPacket, Status);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# if !defined(VBOXNETADP)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisReturnPackets(&pPacket, 1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# if !defined(VBOXNETADP)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(!(fFlags & PACKET_SRC_HOST));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinFreeSGNdisPacket(pPacket, true);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pSG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinMemFree(pSG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bPending = false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync } while (0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifdef DEBUG_NETFLT_PACKETS
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pTmpPacket)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinFreeSGNdisPacket(pTmpPacket, true);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return bPending;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#else /* #ifdef VBOXNETFLT_NO_PACKET_QUEUE */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync } while (0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (bDeleteSG)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinMemFree(pSG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return bDropIt;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return true;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETFLT_NO_PACKET_QUEUE
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/*
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * thread start function for the thread which processes the packets enqueued in our send and receive callbacks called by ndis
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * ndis calls us at DISPATCH_LEVEL, while IntNet is using kernel functions which require Irql<DISPATCH_LEVEL
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * this is why we can not immediately post packets to IntNet from our sen/receive callbacks
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * instead we put the incoming packets to the queue and maintain the system thread running at passive level
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * which processes the queue and posts the packets to IntNet, and further to the host or to the wire.
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic VOID vboxNetFltWinQuPacketQueueWorkerThreadProc(PVBOXNETFLTINS pNetFltIf)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bool fResume = true;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NTSTATUS fStatus;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PPACKET_QUEUE_WORKER pWorker = &pNetFltIf->u.s.PacketQueueWorker;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVOID apEvents[] = {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync (PVOID)&pWorker->KillEvent,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync (PVOID)&pWorker->NotifyEvent
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync };
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync while (fResume)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync uint32_t cNumProcessed;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync uint32_t cNumPostedToHostWire;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync fStatus = KeWaitForMultipleObjects(RT_ELEMENTS(apEvents), apEvents, WaitAny, Executive, KernelMode, FALSE, NULL, NULL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!NT_SUCCESS(fStatus) || fStatus == STATUS_WAIT_0)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* "kill" event was set
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * will process queued packets and exit */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync fResume = false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("processing vboxNetFltWinQuPacketQueueWorkerThreadProc\n"));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cNumProcessed = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cNumPostedToHostWire = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync do
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLTPACKET_INFO pInfo;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifdef DEBUG_NETFLT_PACKETS
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* packet used for matching */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_PACKET pTmpPacket = NULL;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /*TODO: FIXME: !!! the better approach for performance would be to dequeue all packets at once
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * and then go through all dequeued packets
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * the same should be done for enqueue !!! */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pInfo = vboxNetFltWinQuInterlockedDequeueHead(&pWorker->PacketQueue);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!pInfo)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("found info (0x%p)\n", pInfo));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (vboxNetFltWinQuProcessInfo(pNetFltIf, pWorker, pInfo->pPacket, pInfo->fFlags))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cNumPostedToHostWire++;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinPpFreePacketInfo(pInfo);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cNumProcessed++;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync } while (TRUE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (cNumProcessed)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDecReferenceNetFlt(pNetFltIf, cNumProcessed);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(cNumProcessed >= cNumPostedToHostWire);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (cNumProcessed != cNumPostedToHostWire)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDecReferenceWinIf(pNetFltIf, cNumProcessed - cNumPostedToHostWire);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PsTerminateSystemThread(STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/**
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * thread start function for the job processing thread
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * see comments for PVBOXNETFLT_JOB_QUEUE
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic VOID vboxNetFltWinJobWorkerThreadProc(PVBOXNETFLT_JOB_QUEUE pQueue)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bool fResume = true;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NTSTATUS Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVOID apEvents[] = {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync (PVOID)&pQueue->KillEvent,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync (PVOID)&pQueue->NotifyEvent,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync };
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync do
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = KeWaitForMultipleObjects(RT_ELEMENTS(apEvents), apEvents, WaitAny, Executive, KernelMode, FALSE, NULL, NULL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(NT_SUCCESS(Status));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!NT_SUCCESS(Status) || Status == STATUS_WAIT_0)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* will process queued jobs and exit */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == STATUS_WAIT_0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync fResume = false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync do
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PLIST_ENTRY pJobEntry = ExInterlockedRemoveHeadList(&pQueue->Jobs, &pQueue->Lock);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLT_JOB pJob;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!pJobEntry)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pJob = LIST_ENTRY_2_JOB(pJobEntry);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pJob->pfnRoutine(pJob->pContext);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pJob->bUseCompletionEvent)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync KeSetEvent(&pJob->CompletionEvent, 1, FALSE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync } while (TRUE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync } while (fResume);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == STATUS_WAIT_0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PsTerminateSystemThread(STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/**
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * enqueues the job to the job queue to be processed by the job worker thread
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * see comments for PVBOXNETFLT_JOB_QUEUE
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic VOID vboxNetFltWinJobEnqueueJob(PVBOXNETFLT_JOB_QUEUE pQueue, PVBOXNETFLT_JOB pJob, bool bEnqueueHead)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (bEnqueueHead)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ExInterlockedInsertHeadList(&pQueue->Jobs, &pJob->ListEntry, &pQueue->Lock);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ExInterlockedInsertTailList(&pQueue->Jobs, &pJob->ListEntry, &pQueue->Lock);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync KeSetEvent(&pQueue->NotifyEvent, 1, FALSE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLINLINE(VOID) vboxNetFltWinJobInit(PVBOXNETFLT_JOB pJob, PFNVBOXNETFLT_JOB_ROUTINE pfnRoutine, PVOID pContext, bool bUseEvent)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pJob->pfnRoutine = pfnRoutine;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pJob->pContext = pContext;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pJob->bUseCompletionEvent = bUseEvent;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (bUseEvent)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync KeInitializeEvent(&pJob->CompletionEvent, NotificationEvent, FALSE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/**
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * enqueues the job to the job queue to be processed by the job worker thread and
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * blocks until the job is done
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * see comments for PVBOXNETFLT_JOB_QUEUE
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic VOID vboxNetFltWinJobSynchExec(PVBOXNETFLT_JOB_QUEUE pQueue, PFNVBOXNETFLT_JOB_ROUTINE pfnRoutine, PVOID pContext)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync VBOXNETFLT_JOB Job;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinJobInit(&Job, pfnRoutine, pContext, true);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinJobEnqueueJob(pQueue, &Job, false);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync KeWaitForSingleObject(&Job.CompletionEvent, Executive, KernelMode, FALSE, NULL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/**
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * enqueues the job to be processed by the job worker thread at passive level and
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * blocks until the job is done
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(VOID) vboxNetFltWinJobSynchExecAtPassive(PFNVBOXNETFLT_JOB_ROUTINE pfnRoutine, PVOID pContext)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinJobSynchExec(&g_VBoxJobQueue, pfnRoutine, pContext);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/**
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * helper function used for system thread creation
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic NTSTATUS vboxNetFltWinQuCreateSystemThread(PKTHREAD *ppThread, PKSTART_ROUTINE pfnStartRoutine, PVOID pvStartContext)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync OBJECT_ATTRIBUTES ObjectAttributes;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync HANDLE hThread;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NTSTATUS Status = PsCreateSystemThread(&hThread, THREAD_ALL_ACCESS, &ObjectAttributes, NULL, NULL, (PKSTART_ROUTINE)pfnStartRoutine, pvStartContext);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = ObReferenceObjectByHandle(hThread, THREAD_ALL_ACCESS, NULL, KernelMode, (PVOID*)ppThread, NULL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ZwClose(hThread);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return STATUS_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* @todo: how would we fail in this case ?*/
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/**
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * initialize the job queue
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * see comments for PVBOXNETFLT_JOB_QUEUE
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic NTSTATUS vboxNetFltWinJobInitQueue(PVBOXNETFLT_JOB_QUEUE pQueue)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NTSTATUS fStatus;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisZeroMemory(pQueue, sizeof(VBOXNETFLT_JOB_QUEUE));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync KeInitializeEvent(&pQueue->KillEvent, NotificationEvent, FALSE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync KeInitializeEvent(&pQueue->NotifyEvent, SynchronizationEvent, FALSE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync InitializeListHead(&pQueue->Jobs);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync fStatus = vboxNetFltWinQuCreateSystemThread(&pQueue->pThread, (PKSTART_ROUTINE)vboxNetFltWinJobWorkerThreadProc, pQueue);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (fStatus != STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pQueue->pThread = NULL;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pQueue->pThread);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return fStatus;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/**
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * deinitialize the job queue
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * see comments for PVBOXNETFLT_JOB_QUEUE
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic void vboxNetFltWinJobFiniQueue(PVBOXNETFLT_JOB_QUEUE pQueue)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pQueue->pThread)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync KeSetEvent(&pQueue->KillEvent, 0, FALSE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync KeWaitForSingleObject(pQueue->pThread, Executive,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync KernelMode, FALSE, NULL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETFLT_NO_PACKET_QUEUE
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/**
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * initializes the packet queue
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(NTSTATUS) vboxNetFltWinQuInitPacketQueue(PVBOXNETFLTINS pInstance)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NTSTATUS Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PPACKET_QUEUE_WORKER pWorker = &pInstance->u.s.PacketQueueWorker;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertFatal(!pWorker->pSG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync KeInitializeEvent(&pWorker->KillEvent, NotificationEvent, FALSE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync KeInitializeEvent(&pWorker->NotifyEvent, SynchronizationEvent, FALSE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync INIT_INTERLOCKED_PACKET_QUEUE(&pWorker->PacketQueue);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync do
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinPpAllocatePacketInfoPool(&pWorker->PacketInfoPool, VBOXNETFLT_PACKET_INFO_POOL_SIZE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pWorker->pSG = vboxNetFltWinCreateSG(PACKET_QUEUE_SG_SEGS_ALLOC);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!pWorker->pSG)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = STATUS_INSUFFICIENT_RESOURCES;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinQuCreateSystemThread(&pWorker->pThread, (PKSTART_ROUTINE)vboxNetFltWinQuPacketQueueWorkerThreadProc, pInstance);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status != STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinPpFreePacketInfoPool(&pWorker->PacketInfoPool);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinMemFree(pWorker->pSG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pWorker->pSG = NULL;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync } while (0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/*
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * deletes the packet queue
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(void) vboxNetFltWinQuFiniPacketQueue(PVBOXNETFLTINS pInstance)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PINTNETSG pSG;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PPACKET_QUEUE_WORKER pWorker = &pInstance->u.s.PacketQueueWorker;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* using the pPacketQueueSG as an indicator that the packet queue is initialized */
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync RTSpinlockAcquire((pInstance)->hSpinlock);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pWorker->pSG)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pSG = pWorker->pSG;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pWorker->pSG = NULL;
c0b6af690ad705bddfa87c643b89770a7a0aaf5avboxsync RTSpinlockRelease((pInstance)->hSpinlock);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync KeSetEvent(&pWorker->KillEvent, 0, FALSE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync KeWaitForSingleObject(pWorker->pThread, Executive,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync KernelMode, FALSE, NULL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinPpFreePacketInfoPool(&pWorker->PacketInfoPool);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDeleteSG(pSG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync FINI_INTERLOCKED_PACKET_QUEUE(&pWorker->PacketQueue);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
c0b6af690ad705bddfa87c643b89770a7a0aaf5avboxsync RTSpinlockRelease((pInstance)->hSpinlock);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/*
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * creates the INTNETSG containing one segment pointing to the buffer of size cbBufSize
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * the INTNETSG created should be cleaned with vboxNetFltWinMemFree
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinAllocSG(UINT cbPacket, PINTNETSG *ppSG)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PINTNETSG pSG;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* allocation:
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * 1. SG_PACKET - with one aSegs pointing to
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * 2. buffer of cbPacket containing the entire packet */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertCompileSizeAlignment(INTNETSG, sizeof(PVOID));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinMemAlloc((PVOID*)&pSG, cbPacket + sizeof(INTNETSG));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync IntNetSgInitTemp(pSG, pSG + 1, cbPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("pSG created (%p)\n", pSG));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *ppSG = pSG;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETFLT_NO_PACKET_QUEUE
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/**
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * put the packet info to the queue
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLINLINE(void) vboxNetFltWinQuEnqueueInfo(PVBOXNETFLTPACKET_QUEUE_WORKER pWorker, PVBOXNETFLTPACKET_INFO pInfo)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinQuInterlockedEnqueueTail(&pWorker->PacketQueue, pInfo);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync KeSetEvent(&pWorker->NotifyEvent, IO_NETWORK_INCREMENT, FALSE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/**
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * puts the packet to the queue
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * @return NDIST_STATUS_SUCCESS iff the packet was enqueued successfully
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * and error status otherwise.
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * NOTE: that the success status does NOT mean that the packet processing is completed, but only that it was enqueued successfully
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * the packet can be returned to the caller protocol/moniport only in case the bReleasePacket was set to true (in this case the copy of the packet was enqueued)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * or if vboxNetFltWinQuEnqueuePacket failed, i.e. the packet was NOT enqueued
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinQuEnqueuePacket(PVBOXNETFLTINS pInstance, PVOID pPacket, const UINT fPacketFlags)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLT_PACKET_INFO pInfo;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLT_PACKET_QUEUE_WORKER pWorker = &pInstance->u.s.PacketQueueWorker;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS fStatus = NDIS_STATUS_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync do
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (fPacketFlags & PACKET_COPY)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_BUFFER pBuffer = NULL;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT cBufferCount;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT uBytesCopied = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT cbPacketLength;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PINTNETSG pSG;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* the packet is Ndis packet */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(!(fPacketFlags & PACKET_SG));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(!(fPacketFlags & PACKET_MINE));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisQueryPacket((PNDIS_PACKET)pPacket,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NULL,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync &cBufferCount,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync &pBuffer,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync &cbPacketLength);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(cBufferCount);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync fStatus = vboxNetFltWinAllocSG(cbPacketLength, &pSG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (fStatus != NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertFailed();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pInfo = vboxNetFltWinPpAllocPacketInfo(&pWorker->PacketInfoPool);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!pInfo)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertFailed();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* TODO: what status to set? */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync fStatus = NDIS_STATUS_FAILURE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinMemFree(pSG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pInfo->pPool);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* the packet we are queueing is SG, add PACKET_SG to flags */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync SET_FLAGS_TO_INFO(pInfo, fPacketFlags | PACKET_SG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync SET_PACKET_TO_INFO(pInfo, pSG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync fStatus = vboxNetFltWinNdisBufferMoveToSG0(pBuffer, pSG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (fStatus != NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertFailed();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinPpFreePacketInfo(pInfo);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinMemFree(pSG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync DBG_CHECK_PACKET_AND_SG((PNDIS_PACKET)pPacket, pSG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pInfo = vboxNetFltWinPpAllocPacketInfo(&pWorker->PacketInfoPool);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!pInfo)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertFailed();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* TODO: what status to set? */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync fStatus = NDIS_STATUS_FAILURE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pInfo->pPool);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync SET_FLAGS_TO_INFO(pInfo, fPacketFlags);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync SET_PACKET_TO_INFO(pInfo, pPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinQuEnqueueInfo(pWorker, pInfo);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync } while (0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return fStatus;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/*
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * netflt
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic NDIS_STATUS vboxNetFltWinSynchNdisRequest(PVBOXNETFLTINS pNetFlt, PNDIS_REQUEST pRequest)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync int rc;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* 1. serialize */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync rc = RTSemFastMutexRequest(pNetFlt->u.s.WinIf.hSynchRequestMutex); AssertRC(rc);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (RT_SUCCESS(rc))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS fRequestStatus = NDIS_STATUS_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* 2. set pNetFlt->u.s.pSynchRequest */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(!pNetFlt->u.s.WinIf.pSynchRequest);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.pSynchRequest = pRequest;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* 3. call NdisRequest */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisRequest(&fRequestStatus, pNetFlt->u.s.WinIf.hBinding, pRequest);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (fRequestStatus == NDIS_STATUS_PENDING)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* 3.1 if pending wait and assign the resulting status */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync KeWaitForSingleObject(&pNetFlt->u.s.WinIf.hSynchCompletionEvent, Executive,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync KernelMode, FALSE, NULL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync fRequestStatus = pNetFlt->u.s.WinIf.SynchCompletionStatus;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* 4. clear the pNetFlt->u.s.pSynchRequest */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.pSynchRequest = NULL;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync RTSemFastMutexRelease(pNetFlt->u.s.WinIf.hSynchRequestMutex); AssertRC(rc);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return fRequestStatus;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return NDIS_STATUS_FAILURE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinGetMacAddress(PVBOXNETFLTINS pNetFlt, PRTMAC pMac)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_REQUEST request;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync request.RequestType = NdisRequestQueryInformation;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync request.DATA.QUERY_INFORMATION.InformationBuffer = pMac;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync request.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(RTMAC);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync request.DATA.QUERY_INFORMATION.Oid = OID_802_3_CURRENT_ADDRESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync status = vboxNetFltWinSynchNdisRequest(pNetFlt, &request);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (status != NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* TODO */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertFailed();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinQueryPhysicalMedium(PVBOXNETFLTINS pNetFlt, NDIS_PHYSICAL_MEDIUM * pMedium)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_REQUEST Request;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Request.RequestType = NdisRequestQueryInformation;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Request.DATA.QUERY_INFORMATION.InformationBuffer = pMedium;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Request.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(NDIS_PHYSICAL_MEDIUM);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Request.DATA.QUERY_INFORMATION.Oid = OID_GEN_PHYSICAL_MEDIUM;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinSynchNdisRequest(pNetFlt, &Request);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status != NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_NOT_SUPPORTED || Status == NDIS_STATUS_NOT_RECOGNIZED || Status == NDIS_STATUS_INVALID_OID)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = NDIS_STATUS_NOT_SUPPORTED;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogRel(("OID_GEN_PHYSICAL_MEDIUM failed: Status (0x%x)", Status));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertFailed();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(bool) vboxNetFltWinIsPromiscuous(PVBOXNETFLTINS pNetFlt)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /** @todo r=bird: This is too slow and is probably returning the wrong
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * information. What we're interested in is whether someone besides us
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * has put the interface into promiscuous mode. */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_REQUEST request;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ULONG filter;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(VBOXNETFLT_PROMISCUOUS_SUPPORTED(pNetFlt));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync request.RequestType = NdisRequestQueryInformation;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync request.DATA.QUERY_INFORMATION.InformationBuffer = &filter;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync request.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(filter);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync request.DATA.QUERY_INFORMATION.Oid = OID_GEN_CURRENT_PACKET_FILTER;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync status = vboxNetFltWinSynchNdisRequest(pNetFlt, &request);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (status != NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* TODO */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertFailed();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return (filter & NDIS_PACKET_TYPE_PROMISCUOUS) != 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinSetPromiscuous(PVBOXNETFLTINS pNetFlt, bool bYes)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/** @todo Need to report changes to the switch via:
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * pThis->pSwitchPort->pfnReportPromiscuousMode(pThis->pSwitchPort, fPromisc);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(VBOXNETFLT_PROMISCUOUS_SUPPORTED(pNetFlt));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (VBOXNETFLT_PROMISCUOUS_SUPPORTED(pNetFlt))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_REQUEST Request;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS fStatus;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ULONG fFilter;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ULONG fExpectedFilter;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ULONG fOurFilter;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Request.RequestType = NdisRequestQueryInformation;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Request.DATA.QUERY_INFORMATION.InformationBuffer = &fFilter;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Request.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(fFilter);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Request.DATA.QUERY_INFORMATION.Oid = OID_GEN_CURRENT_PACKET_FILTER;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync fStatus = vboxNetFltWinSynchNdisRequest(pNetFlt, &Request);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (fStatus != NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* TODO: */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertFailed();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return fStatus;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!pNetFlt->u.s.WinIf.StateFlags.fUpperProtSetFilterInitialized)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* the cache was not initialized yet, initiate it with the current filter value */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.fUpperProtocolSetFilter = fFilter;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.StateFlags.fUpperProtSetFilterInitialized = TRUE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (bYes)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync fExpectedFilter = NDIS_PACKET_TYPE_PROMISCUOUS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync fOurFilter = NDIS_PACKET_TYPE_PROMISCUOUS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync fExpectedFilter = pNetFlt->u.s.WinIf.fUpperProtocolSetFilter;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync fOurFilter = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (fExpectedFilter != fFilter)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Request.RequestType = NdisRequestSetInformation;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Request.DATA.SET_INFORMATION.InformationBuffer = &fExpectedFilter;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Request.DATA.SET_INFORMATION.InformationBufferLength = sizeof(fExpectedFilter);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Request.DATA.SET_INFORMATION.Oid = OID_GEN_CURRENT_PACKET_FILTER;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync fStatus = vboxNetFltWinSynchNdisRequest(pNetFlt, &Request);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (fStatus != NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* TODO */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertFailed();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return fStatus;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.fOurSetFilter = fOurFilter;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return fStatus;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return NDIS_STATUS_NOT_SUPPORTED;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#else /* if defined VBOXNETADP */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/**
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * Generates a new unique MAC address based on our vendor ID
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(void) vboxNetFltWinGenerateMACAddress(RTMAC *pMac)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* temporary use a time info */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync uint64_t NanoTS = RTTimeSystemNanoTS();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pMac->au8[0] = (uint8_t)((VBOXNETADP_VENDOR_ID >> 16) & 0xff);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pMac->au8[1] = (uint8_t)((VBOXNETADP_VENDOR_ID >> 8) & 0xff);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pMac->au8[2] = (uint8_t)(VBOXNETADP_VENDOR_ID & 0xff);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pMac->au8[3] = (uint8_t)(NanoTS & 0xff0000);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pMac->au16[2] = (uint16_t)(NanoTS & 0xffff);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(int) vboxNetFltWinMAC2NdisString(RTMAC *pMac, PNDIS_STRING pNdisString)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync static const char s_achDigits[17] = "0123456789abcdef";
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PWSTR pString;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* validate parameters */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertPtrReturn(pMac, VERR_INVALID_PARAMETER);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertPtrReturn(pNdisString, VERR_INVALID_PARAMETER);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertReturn(pNdisString->MaximumLength >= 13*sizeof(pNdisString->Buffer[0]), VERR_INVALID_PARAMETER);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pString = pNdisString->Buffer;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync for (int i = 0; i < 6; i++)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync uint8_t u8 = pMac->au8[i];
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pString[0] = s_achDigits[(u8 >> 4) & 0xf];
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pString[1] = s_achDigits[(u8/*>>0*/)& 0xf];
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pString += 2;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNdisString->Length = 12*sizeof(pNdisString->Buffer[0]);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *pString = L'\0';
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return VINF_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic int vboxNetFltWinWchar2Int(WCHAR c, uint8_t * pv)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (c >= L'A' && c <= L'F')
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *pv = (c - L'A') + 10;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else if (c >= L'a' && c <= L'f')
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *pv = (c - L'a') + 10;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else if (c >= L'0' && c <= L'9')
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *pv = (c - L'0');
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return VERR_INVALID_PARAMETER;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return VINF_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(int) vboxNetFltWinMACFromNdisString(RTMAC *pMac, PNDIS_STRING pNdisString)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync int i, rc;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PWSTR pString;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* validate parameters */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertPtrReturn(pMac, VERR_INVALID_PARAMETER);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertPtrReturn(pNdisString, VERR_INVALID_PARAMETER);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertReturn(pNdisString->Length >= 12*sizeof(pNdisString->Buffer[0]), VERR_INVALID_PARAMETER);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pString = pNdisString->Buffer;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync for (i = 0; i < 6; i++)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync uint8_t v1, v2;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync rc = vboxNetFltWinWchar2Int(pString[0], &v1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (RT_FAILURE(rc))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync rc = vboxNetFltWinWchar2Int(pString[1], &v2);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (RT_FAILURE(rc))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pMac->au8[i] = (v1 << 4) | v2;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pString += 2;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return rc;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/**
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * creates a NDIS_PACKET from the PINTNETSG
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(PNDIS_PACKET) vboxNetFltWinNdisPacketFromSG(PVBOXNETFLTINS pNetFlt, PINTNETSG pSG, PVOID pBufToFree, bool bToWire, bool bCopyMemory)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS fStatus;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_PACKET pPacket;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pSG->aSegs[0].pv);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pSG->cbTotal >= sizeof(VBOXNETFLT_PACKET_ETHEADER_SIZE));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/** @todo Hrmpf, how can we fix this assumption? I fear this'll cause data
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * corruption and maybe even BSODs ... */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertReturn(pSG->cSegsUsed == 1 || bCopyMemory, NULL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifdef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisAllocatePacket(&fStatus, &pPacket, pNetFlt->u.s.WinIf.hRecvPacketPool);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisAllocatePacket(&fStatus, &pPacket, bToWire ? pNetFlt->u.s.WinIf.hSendPacketPool : pNetFlt->u.s.WinIf.hRecvPacketPool);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (fStatus == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_BUFFER pBuffer;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVOID pvMemBuf;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* @todo: generally we do not always need to zero-initialize the complete OOB data here, reinitialize only when/what we need,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * however we DO need to reset the status for the packets we indicate via NdisMIndicateReceivePacket to avoid packet loss
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * in case the status contains NDIS_STATUS_RESOURCES */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync VBOXNETFLT_OOB_INIT(pPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (bCopyMemory)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync fStatus = vboxNetFltWinMemAlloc(&pvMemBuf, pSG->cbTotal);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(fStatus == NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (fStatus == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync IntNetSgRead(pSG, pvMemBuf);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pvMemBuf = pSG->aSegs[0].pv;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (fStatus == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifdef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisAllocateBuffer(&fStatus, &pBuffer,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.hRecvBufferPool,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pvMemBuf,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pSG->cbTotal);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisAllocateBuffer(&fStatus, &pBuffer,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bToWire ? pNetFlt->u.s.WinIf.hSendBufferPool : pNetFlt->u.s.WinIf.hRecvBufferPool,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pvMemBuf,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pSG->cbTotal);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (fStatus == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisChainBufferAtBack(pPacket, pBuffer);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (bToWire)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLT_PKTRSVD_PT pSendInfo = (PVBOXNETFLT_PKTRSVD_PT)pPacket->ProtocolReserved;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pSendInfo->pOrigPacket = NULL;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pSendInfo->pBufToFree = pBufToFree;
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 else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLT_PKTRSVD_MP pRecvInfo = (PVBOXNETFLT_PKTRSVD_MP)pPacket->MiniportReserved;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pRecvInfo->pOrigPacket = NULL;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pRecvInfo->pBufToFree = pBufToFree;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* we must set the header size on receive */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_SET_PACKET_HEADER_SIZE(pPacket, VBOXNETFLT_PACKET_ETHEADER_SIZE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* NdisAllocatePacket zero-initializes the OOB data,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * but keeps the packet flags, clean them here */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisGetPacketFlags(pPacket) = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* TODO: set out of bound data */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertFailed();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (bCopyMemory)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinMemFree(pvMemBuf);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisFreePacket(pPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pPacket = NULL;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertFailed();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisFreePacket(pPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pPacket = NULL;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pPacket = NULL;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync DBG_CHECK_PACKET_AND_SG(pPacket, pSG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return pPacket;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/*
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * frees NDIS_PACKET created with vboxNetFltWinNdisPacketFromSG
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(void) vboxNetFltWinFreeSGNdisPacket(PNDIS_PACKET pPacket, bool bFreeMem)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT cBufCount;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_BUFFER pFirstBuffer;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT uTotalPacketLength;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_BUFFER pBuffer;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisQueryPacket(pPacket, NULL, &cBufCount, &pFirstBuffer, &uTotalPacketLength);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(cBufCount == 1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync do
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisUnchainBufferAtBack(pPacket, &pBuffer);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pBuffer != NULL)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVOID pvMemBuf;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT cbLength;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisQueryBufferSafe(pBuffer, &pvMemBuf, &cbLength, NormalPagePriority);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisFreeBuffer(pBuffer);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (bFreeMem)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinMemFree(pvMemBuf);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync } while (true);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisFreePacket(pPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#if !defined(VBOXNETADP)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic void vboxNetFltWinAssociateMiniportProtocol(PVBOXNETFLTGLOBALS_WIN pGlobalsWin)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisIMAssociateMiniport(pGlobalsWin->Mp.hMiniport, pGlobalsWin->Pt.hProtocol);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/*
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * NetFlt driver unload function
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(VOID) vboxNetFltWinUnload(IN PDRIVER_OBJECT DriverObject)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync int rc;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UNREFERENCED_PARAMETER(DriverObject);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow((__FUNCTION__" ==> DO (0x%x)\n", DriverObject));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync rc = vboxNetFltWinTryFiniIdc();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (RT_FAILURE(rc))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* TODO: we can not prevent driver unload here */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertFailed();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Log((__FUNCTION__": vboxNetFltWinTryFiniIdc - failed, busy.\n"));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinJobFiniQueue(&g_VBoxJobQueue);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinPtDeregister(&g_VBoxNetFltGlobalsWin.Pt);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinMpDeregister(&g_VBoxNetFltGlobalsWin.Mp);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
adc4dc70e95e458241de9ae84b29e773dbd1dafavboxsync LogFlow((__FUNCTION__" <== DO (0x%x)\n", DriverObject));
adc4dc70e95e458241de9ae84b29e773dbd1dafavboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinFiniNetFltBase();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* don't use logging or any RT after de-init */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncRT_C_DECLS_BEGIN
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncNTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncRT_C_DECLS_END
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncNTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync int rc;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* the idc registration is initiated via IOCTL since our driver
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * can be loaded when the VBoxDrv is not in case we are a Ndis IM driver */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync rc = vboxNetFltWinInitNetFltBase();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertRC(rc);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (RT_SUCCESS(rc))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinJobInitQueue(&g_VBoxJobQueue);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ULONG MjVersion;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ULONG MnVersion;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* note: we do it after we initialize the Job Queue */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinStartInitIdcProbing();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisZeroMemory(&g_VBoxNetFltGlobalsWin, sizeof (g_VBoxNetFltGlobalsWin));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync KeInitializeEvent(&g_VBoxNetFltGlobalsWin.SynchEvent, SynchronizationEvent, TRUE /* signalled*/);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PsGetVersion(&MjVersion, &MnVersion,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NULL, /* PULONG BuildNumber OPTIONAL */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NULL /* PUNICODE_STRING CSDVersion OPTIONAL */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync );
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync g_VBoxNetFltGlobalsWin.fPacketDontLoopBack = NDIS_FLAGS_DONT_LOOPBACK;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (MjVersion == 5 && MnVersion == 0)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* this is Win2k, we don't support it actually, but just in case */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync g_VBoxNetFltGlobalsWin.fPacketDontLoopBack |= NDIS_FLAGS_SKIP_LOOPBACK_W2K;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync g_VBoxNetFltGlobalsWin.fPacketIsLoopedBack = NDIS_FLAGS_IS_LOOPBACK_PACKET;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinMpRegister(&g_VBoxNetFltGlobalsWin.Mp, DriverObject, RegistryPath);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinPtRegister(&g_VBoxNetFltGlobalsWin.Pt, DriverObject, RegistryPath);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinAssociateMiniportProtocol(&g_VBoxNetFltGlobalsWin);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return STATUS_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync//#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync// vboxNetFltWinPtDeregister(&g_VBoxNetFltGlobalsWin.Pt);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync//#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinMpDeregister(&g_VBoxNetFltGlobalsWin.Mp);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinJobFiniQueue(&g_VBoxJobQueue);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinFiniNetFlt();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = NDIS_STATUS_FAILURE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/**
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * creates and initializes the packet to be sent to the underlying miniport given a packet posted to our miniport edge
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * according to DDK docs we must create our own packet rather than posting the one passed to us
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinPrepareSendPacket(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket, PNDIS_PACKET *ppMyPacket)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisAllocatePacket(&Status, ppMyPacket, pNetFlt->u.s.WinIf.hSendPacketPool);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLT_PKTRSVD_PT pSendInfo = (PVBOXNETFLT_PKTRSVD_PT)((*ppMyPacket)->ProtocolReserved);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pSendInfo->pOrigPacket = pPacket;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pSendInfo->pBufToFree = NULL;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* the rest will be filled on send */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinCopyPacketInfoOnSend(*ppMyPacket, pPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifdef VBOX_LOOPBACK_USEFLAGS
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisGetPacketFlags(*ppMyPacket) |= g_VBoxNetFltGlobalsWin.fPacketDontLoopBack;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *ppMyPacket = NULL;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/**
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * creates and initializes the packet to be sent to the upperlying protocol given a packet indicated to our protocol edge
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * according to DDK docs we must create our own packet rather than posting the one passed to us
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinPrepareRecvPacket(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket, PNDIS_PACKET *ppMyPacket, bool bDpr)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (bDpr)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisDprAllocatePacket(&Status, ppMyPacket, pNetFlt->u.s.WinIf.hRecvPacketPool);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisAllocatePacket(&Status, ppMyPacket, pNetFlt->u.s.WinIf.hRecvPacketPool);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLT_PKTRSVD_MP pRecvInfo = (PVBOXNETFLT_PKTRSVD_MP)((*ppMyPacket)->MiniportReserved);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pRecvInfo->pOrigPacket = pPacket;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pRecvInfo->pBufToFree = NULL;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinCopyPacketInfoOnRecv(*ppMyPacket, pPacket, false);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *ppMyPacket = NULL;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/**
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * initializes the VBOXNETFLTINS (our context structure) and binds to the given adapter
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#if defined(VBOXNETADP)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PVBOXNETFLTINS *ppNetFlt, NDIS_HANDLE hMiniportAdapter, PNDIS_STRING pBindToMiniportName /* actually this is our miniport name*/, NDIS_HANDLE hWrapperConfigurationContext)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PVBOXNETFLTINS *ppNetFlt, PNDIS_STRING pOurMiniportName, PNDIS_STRING pBindToMiniportName)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync do
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ANSI_STRING AnsiString;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync int rc;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLTINS pInstance;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync USHORT cbAnsiName = pBindToMiniportName->Length;/* the length is is bytes ; *2 ;RtlUnicodeStringToAnsiSize(pBindToMiniportName)*/
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync CREATE_INSTANCE_CONTEXT Context;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Context.pOurName = pOurMiniportName;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Context.pBindToName = pBindToMiniportName;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Context.hMiniportAdapter = hMiniportAdapter;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Context.hWrapperConfigurationContext = hWrapperConfigurationContext;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Context.Status = NDIS_STATUS_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AnsiString.Buffer = 0; /* will be allocated by RtlUnicodeStringToAnsiString */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AnsiString.Length = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AnsiString.MaximumLength = cbAnsiName;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = RtlUnicodeStringToAnsiString(&AnsiString, pBindToMiniportName, true);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status != STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync rc = vboxNetFltSearchCreateInstance(&g_VBoxNetFltGlobals, AnsiString.Buffer, &pInstance, &Context);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync RtlFreeAnsiString(&AnsiString);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (RT_FAILURE(rc))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertFailed();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = Context.Status != NDIS_STATUS_SUCCESS ? Context.Status : NDIS_STATUS_FAILURE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pInstance);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (rc == VINF_ALREADY_INITIALIZED)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* the case when our adapter was unbound while IntNet was connected to it */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* the instance remains valid until IntNet disconnects from it, we simply search and re-use it*/
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync rc = vboxNetFltWinAttachToInterface(pInstance, &Context, true);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (RT_FAILURE(rc))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertFailed();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = Context.Status != NDIS_STATUS_SUCCESS ? Context.Status : NDIS_STATUS_FAILURE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* release netflt */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltRelease(pInstance, false);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *ppNetFlt = pInstance;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync } while (FALSE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/*
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * deinitializes the VBOXNETFLTWIN
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(VOID) vboxNetFltWinPtFiniWinIf(PVBOXNETFLTWIN pWinIf)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync int rc;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("==>"__FUNCTION__" : pWinIf 0x%p\n", pWinIf));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pWinIf->MpDeviceName.Buffer)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinMemFree(pWinIf->MpDeviceName.Buffer);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync FINI_INTERLOCKED_SINGLE_LIST(&pWinIf->TransferDataList);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# if defined(DEBUG_NETFLT_LOOPBACK) || !defined(VBOX_LOOPBACK_USEFLAGS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync FINI_INTERLOCKED_SINGLE_LIST(&pWinIf->SendPacketQueue);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisFreeBufferPool(pWinIf->hSendBufferPool);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisFreePacketPool(pWinIf->hSendPacketPool);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync rc = RTSemFastMutexDestroy(pWinIf->hSynchRequestMutex); AssertRC(rc);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* NOTE: NULL is a valid handle */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisFreeBufferPool(pWinIf->hRecvBufferPool);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisFreePacketPool(pWinIf->hRecvPacketPool);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__" : pWinIf 0x%p\n", pWinIf));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitWinIf(PVBOXNETFLTWIN pWinIf, IN PNDIS_STRING pOurDeviceName)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitWinIf(PVBOXNETFLTWIN pWinIf)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync int rc;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync BOOLEAN bCallFiniOnFail = FALSE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("==>"__FUNCTION__": pWinIf 0x%p\n", pWinIf));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisZeroMemory(pWinIf, sizeof (VBOXNETFLTWIN));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisAllocatePacketPoolEx(&Status, &pWinIf->hRecvPacketPool,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync VBOXNETFLT_PACKET_POOL_SIZE_NORMAL,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync VBOXNETFLT_PACKET_POOL_SIZE_OVERFLOW,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PROTOCOL_RESERVED_SIZE_IN_PACKET);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* NOTE: NULL is a valid handle !!! */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisAllocateBufferPool(&Status, &pWinIf->hRecvBufferPool, VBOXNETFLT_BUFFER_POOL_SIZE_RX);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pWinIf->MpState.PowerState = NdisDeviceStateD3;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSetOpState(&pWinIf->MpState, kVBoxNetDevOpState_Deinitialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pWinIf->PtState.PowerState = NdisDeviceStateD3;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSetOpState(&pWinIf->PtState, kVBoxNetDevOpState_Deinitialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisAllocateBufferPool(&Status,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync &pWinIf->hSendBufferPool,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync VBOXNETFLT_BUFFER_POOL_SIZE_TX);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync INIT_INTERLOCKED_SINGLE_LIST(&pWinIf->TransferDataList);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# if defined(DEBUG_NETFLT_LOOPBACK) || !defined(VBOX_LOOPBACK_USEFLAGS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync INIT_INTERLOCKED_SINGLE_LIST(&pWinIf->SendPacketQueue);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisInitializeEvent(&pWinIf->OpenCloseEvent);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync KeInitializeEvent(&pWinIf->hSynchCompletionEvent, SynchronizationEvent, FALSE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisInitializeEvent(&pWinIf->MpInitCompleteEvent);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisAllocatePacketPoolEx(&Status, &pWinIf->hSendPacketPool,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync VBOXNETFLT_PACKET_POOL_SIZE_NORMAL,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync VBOXNETFLT_PACKET_POOL_SIZE_OVERFLOW,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync sizeof (PVBOXNETFLT_PKTRSVD_PT));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync rc = RTSemFastMutexCreate(&pWinIf->hSynchRequestMutex);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertRC(rc);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (RT_SUCCESS(rc))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinMemAlloc((PVOID*)&pWinIf->MpDeviceName.Buffer, pOurDeviceName->Length);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pWinIf->MpDeviceName.MaximumLength = pOurDeviceName->Length;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pWinIf->MpDeviceName.Length = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinCopyString(&pWinIf->MpDeviceName, pOurDeviceName);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return NDIS_STATUS_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinMemFree(pWinIf->MpDeviceName.Buffer);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync RTSemFastMutexDestroy(pWinIf->hSynchRequestMutex);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = NDIS_STATUS_FAILURE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisFreePacketPool(pWinIf->hSendPacketPool);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisFreeBufferPool(pWinIf->hSendBufferPool);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisFreeBufferPool(pWinIf->hRecvBufferPool);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisFreePacketPool(pWinIf->hRecvPacketPool);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("<=="__FUNCTION__": pWinIf 0x%p, Status 0x%x\n", pWinIf, Status));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/**
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * match packets
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#define NEXT_LIST_ENTRY(_Entry) ((_Entry)->Flink)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#define PREV_LIST_ENTRY(_Entry) ((_Entry)->Blink)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#define FIRST_LIST_ENTRY NEXT_LIST_ENTRY
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#define LAST_LIST_ENTRY PREV_LIST_ENTRY
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#define MIN(_a, _b) ((_a) < (_b) ? (_a) : (_b))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifdef DEBUG_misha
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncRTMAC g_vboxNetFltWinVerifyMACBroadcast = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncRTMAC g_vboxNetFltWinVerifyMACGuest = {0x08, 0x00, 0x27, 0x01, 0x02, 0x03};
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(PRTNETETHERHDR) vboxNetFltWinGetEthHdr(PNDIS_PACKET pPacket)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT cBufCount1;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_BUFFER pBuffer1;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT uTotalPacketLength1;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync RTNETETHERHDR* pEth;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT cbLength1 = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT i = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisQueryPacket(pPacket, NULL, &cBufCount1, &pBuffer1, &uTotalPacketLength1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pBuffer1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(uTotalPacketLength1 >= VBOXNETFLT_PACKET_ETHEADER_SIZE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (uTotalPacketLength1 < VBOXNETFLT_PACKET_ETHEADER_SIZE)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return NULL;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisQueryBufferSafe(pBuffer1, &pEth, &cbLength1, NormalPagePriority);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(cbLength1 >= VBOXNETFLT_PACKET_ETHEADER_SIZE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (cbLength1 < VBOXNETFLT_PACKET_ETHEADER_SIZE)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return NULL;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return pEth;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(PRTNETETHERHDR) vboxNetFltWinGetEthHdrSG(PINTNETSG pSG)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pSG->cSegsUsed);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pSG->cSegsAlloc >= pSG->cSegsUsed);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pSG->aSegs[0].cb >= VBOXNETFLT_PACKET_ETHEADER_SIZE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!pSG->cSegsUsed)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return NULL;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pSG->aSegs[0].cb < VBOXNETFLT_PACKET_ETHEADER_SIZE)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return NULL;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return (PRTNETETHERHDR)pSG->aSegs[0].pv;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(bool) vboxNetFltWinCheckMACs(PNDIS_PACKET pPacket, PRTMAC pDst, PRTMAC pSrc)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PRTNETETHERHDR pHdr = vboxNetFltWinGetEthHdr(pPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pHdr);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!pHdr)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pDst && memcmp(pDst, &pHdr->DstMac, sizeof(RTMAC)))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pSrc && memcmp(pSrc, &pHdr->SrcMac, sizeof(RTMAC)))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return true;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(bool) vboxNetFltWinCheckMACsSG(PINTNETSG pSG, PRTMAC pDst, PRTMAC pSrc)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PRTNETETHERHDR pHdr = vboxNetFltWinGetEthHdrSG(pSG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pHdr);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!pHdr)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pDst && memcmp(pDst, &pHdr->DstMac, sizeof(RTMAC)))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pSrc && memcmp(pSrc, &pHdr->SrcMac, sizeof(RTMAC)))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return true;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# if !defined(VBOX_LOOPBACK_USEFLAGS) || defined(DEBUG_NETFLT_PACKETS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/*
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * answers whether the two given packets match based on the packet length and the first cbMatch bytes of the packets
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * if cbMatch < 0 matches complete packets.
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(bool) vboxNetFltWinMatchPackets(PNDIS_PACKET pPacket1, PNDIS_PACKET pPacket2, const INT cbMatch)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT cBufCount1;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_BUFFER pBuffer1;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT uTotalPacketLength1;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync uint8_t* pMemBuf1;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT cbLength1 = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT cBufCount2;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_BUFFER pBuffer2;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT uTotalPacketLength2;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync uint8_t* pMemBuf2;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT cbLength2 = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bool bMatch = true;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifdef DEBUG_NETFLT_PACKETS
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bool bCompleteMatch = false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisQueryPacket(pPacket1, NULL, &cBufCount1, &pBuffer1, &uTotalPacketLength1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisQueryPacket(pPacket2, NULL, &cBufCount2, &pBuffer2, &uTotalPacketLength2);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pBuffer1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pBuffer2);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (uTotalPacketLength1 != uTotalPacketLength2)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bMatch = false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT ucbLength2Match = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT ucbMatch;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (cbMatch < 0 || (UINT)cbMatch > uTotalPacketLength1)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* NOTE: assuming uTotalPacketLength1 == uTotalPacketLength2*/
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ucbMatch = uTotalPacketLength1;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifdef DEBUG_NETFLT_PACKETS
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bCompleteMatch = true;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ucbMatch = (UINT)cbMatch;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync for (;;)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!cbLength1)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisQueryBufferSafe(pBuffer1, &pMemBuf1, &cbLength1, NormalPagePriority);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisGetNextBuffer(pBuffer1, &pBuffer1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pMemBuf1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(ucbLength2Match);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pMemBuf1 += ucbLength2Match;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!cbLength2)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisQueryBufferSafe(pBuffer2, &pMemBuf2, &cbLength2, NormalPagePriority);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisGetNextBuffer(pBuffer2, &pBuffer2);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pMemBuf2);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(ucbLength2Match);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pMemBuf2 += ucbLength2Match;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ucbLength2Match = MIN(ucbMatch, cbLength1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ucbLength2Match = MIN(ucbLength2Match, cbLength2);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (memcmp((PVOID*)pMemBuf1, (PVOID*)pMemBuf2, ucbLength2Match))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bMatch = false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ucbMatch -= ucbLength2Match;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!ucbMatch)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cbLength1 -= ucbLength2Match;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cbLength2 -= ucbLength2Match;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifdef DEBUG_NETFLT_PACKETS
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (bMatch && !bCompleteMatch)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* check that the packets fully match */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync DBG_CHECK_PACKETS(pPacket1, pPacket2);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return bMatch;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/*
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * answers whether the ndis packet and PINTNETSG match based on the packet length and the first cbMatch bytes of the packet and PINTNETSG
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * if cbMatch < 0 matches complete packets.
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(bool) vboxNetFltWinMatchPacketAndSG(PNDIS_PACKET pPacket, PINTNETSG pSG, const INT cbMatch)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT cBufCount1;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_BUFFER pBuffer1;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT uTotalPacketLength1;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync uint8_t* pMemBuf1;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT cbLength1 = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT uTotalPacketLength2 = pSG->cbTotal;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync uint8_t* pMemBuf2;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT cbLength2 = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bool bMatch = true;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bool bCompleteMatch = false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT i = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisQueryPacket(pPacket, NULL, &cBufCount1, &pBuffer1, &uTotalPacketLength1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pBuffer1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pSG->cSegsUsed);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pSG->cSegsAlloc >= pSG->cSegsUsed);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (uTotalPacketLength1 != uTotalPacketLength2)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertFailed();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bMatch = false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT ucbLength2Match = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT ucbMatch;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (cbMatch < 0 || (UINT)cbMatch > uTotalPacketLength1)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* NOTE: assuming uTotalPacketLength1 == uTotalPacketLength2*/
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ucbMatch = uTotalPacketLength1;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bCompleteMatch = true;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ucbMatch = (UINT)cbMatch;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync for (;;)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!cbLength1)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisQueryBufferSafe(pBuffer1, &pMemBuf1, &cbLength1, NormalPagePriority);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisGetNextBuffer(pBuffer1, &pBuffer1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pMemBuf1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(ucbLength2Match);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pMemBuf1 += ucbLength2Match;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!cbLength2)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(i < pSG->cSegsUsed);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pMemBuf2 = (uint8_t*)pSG->aSegs[i].pv;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cbLength2 = pSG->aSegs[i].cb;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync i++;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pMemBuf2);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(ucbLength2Match);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pMemBuf2 += ucbLength2Match;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ucbLength2Match = MIN(ucbMatch, cbLength1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ucbLength2Match = MIN(ucbLength2Match, cbLength2);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (memcmp((PVOID*)pMemBuf1, (PVOID*)pMemBuf2, ucbLength2Match))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bMatch = false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertFailed();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ucbMatch -= ucbLength2Match;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!ucbMatch)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cbLength1 -= ucbLength2Match;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cbLength2 -= ucbLength2Match;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (bMatch && !bCompleteMatch)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* check that the packets fully match */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync DBG_CHECK_PACKET_AND_SG(pPacket, pSG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return bMatch;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# if 0
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/*
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * answers whether the two PINTNETSGs match based on the packet length and the first cbMatch bytes of the PINTNETSG
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * if cbMatch < 0 matches complete packets.
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic bool vboxNetFltWinMatchSGs(PINTNETSG pSG1, PINTNETSG pSG2, const INT cbMatch)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT uTotalPacketLength1 = pSG1->cbTotal;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVOID pMemBuf1;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT cbLength1 = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT i1 = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT uTotalPacketLength2 = pSG2->cbTotal;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVOID pMemBuf2;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT cbLength2 = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bool bMatch = true;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bool bCompleteMatch = false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT i2 = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pSG1->cSegsUsed);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pSG2->cSegsUsed);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pSG1->cSegsAlloc >= pSG1->cSegsUsed);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pSG2->cSegsAlloc >= pSG2->cSegsUsed);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (uTotalPacketLength1 != uTotalPacketLength2)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertFailed();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bMatch = false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT ucbMatch;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (cbMatch < 0 || (UINT)cbMatch > uTotalPacketLength1)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* NOTE: assuming uTotalPacketLength1 == uTotalPacketLength2*/
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ucbMatch = uTotalPacketLength1;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bCompleteMatch = true;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ucbMatch = (UINT)cbMatch;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync do
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync UINT ucbLength2Match;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!cbLength1)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(i1 < pSG1->cSegsUsed);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pMemBuf1 = pSG1->aSegs[i1].pv;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cbLength1 = pSG1->aSegs[i1].cb;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync i1++;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!cbLength2)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(i2 < pSG2->cSegsUsed);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pMemBuf2 = pSG2->aSegs[i2].pv;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cbLength2 = pSG2->aSegs[i2].cb;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync i2++;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ucbLength2Match = MIN(ucbMatch, cbLength1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ucbLength2Match = MIN(ucbLength2Match, cbLength2);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (memcmp(pMemBuf1, pMemBuf2, ucbLength2Match))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bMatch = false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertFailed();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ucbMatch -= ucbLength2Match;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cbLength1 -= ucbLength2Match;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cbLength2 -= ucbLength2Match;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync } while (ucbMatch);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (bMatch && !bCompleteMatch)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* check that the packets fully match */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync DBG_CHECK_SGS(pSG1, pSG2);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return bMatch;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic void vboxNetFltWinFiniNetFltBase()
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync do
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltDeleteGlobals(&g_VBoxNetFltGlobals);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /*
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * Undo the work done during start (in reverse order).
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync memset(&g_VBoxNetFltGlobals, 0, sizeof(g_VBoxNetFltGlobals));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync RTLogDestroy(RTLogRelSetDefaultInstance(NULL));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync RTLogDestroy(RTLogSetDefaultInstance(NULL));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync RTR0Term();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync } while (0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic int vboxNetFltWinTryFiniIdc()
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync int rc;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinStopInitIdcProbing();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (g_bVBoxIdcInitialized)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync rc = vboxNetFltTryDeleteIdc(&g_VBoxNetFltGlobals);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (RT_SUCCESS(rc))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync g_bVBoxIdcInitialized = false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync rc = VINF_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return rc;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic int vboxNetFltWinFiniNetFlt()
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync int rc = vboxNetFltWinTryFiniIdc();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (RT_SUCCESS(rc))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinFiniNetFltBase();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return rc;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/**
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * base netflt initialization
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic int vboxNetFltWinInitNetFltBase()
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync int rc;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync do
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(!g_bVBoxIdcInitialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync rc = RTR0Init(0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!RT_SUCCESS(rc))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync memset(&g_VBoxNetFltGlobals, 0, sizeof(g_VBoxNetFltGlobals));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync rc = vboxNetFltInitGlobals(&g_VBoxNetFltGlobals);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!RT_SUCCESS(rc))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync RTR0Term();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }while (0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return rc;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/**
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * initialize IDC
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic int vboxNetFltWinInitIdc()
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync int rc;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync do
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (g_bVBoxIdcInitialized)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync rc = VINF_ALREADY_INITIALIZED;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /*
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * connect to the support driver.
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * This will call back vboxNetFltOsOpenSupDrv (and maybe vboxNetFltOsCloseSupDrv)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * for establishing the connect to the support driver.
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync rc = vboxNetFltInitIdc(&g_VBoxNetFltGlobals);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!RT_SUCCESS(rc))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync g_bVBoxIdcInitialized = true;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync } while (0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return rc;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic VOID vboxNetFltWinInitIdcProbingWorker(PVOID pvContext)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PINIT_IDC_INFO pInitIdcInfo = (PINIT_IDC_INFO)pvContext;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync int rc = vboxNetFltWinInitIdc();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (RT_FAILURE(rc))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bool bInterupted = ASMAtomicUoReadBool(&pInitIdcInfo->bStop);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!bInterupted)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync RTThreadSleep(1000); /* 1 s */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bInterupted = ASMAtomicUoReadBool(&pInitIdcInfo->bStop);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!bInterupted)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinJobEnqueueJob(&g_VBoxJobQueue, &pInitIdcInfo->Job, false);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* it's interrupted */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync rc = VERR_INTERRUPTED;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ASMAtomicUoWriteS32(&pInitIdcInfo->rc, rc);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync KeSetEvent(&pInitIdcInfo->hCompletionEvent, 0, FALSE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic int vboxNetFltWinStopInitIdcProbing()
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!g_VBoxInitIdcInfo.bInitialized)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return VERR_INVALID_STATE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ASMAtomicUoWriteBool(&g_VBoxInitIdcInfo.bStop, true);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync KeWaitForSingleObject(&g_VBoxInitIdcInfo.hCompletionEvent, Executive, KernelMode, FALSE, NULL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return g_VBoxInitIdcInfo.rc;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic int vboxNetFltWinStartInitIdcProbing()
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(!g_bVBoxIdcInitialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync KeInitializeEvent(&g_VBoxInitIdcInfo.hCompletionEvent, NotificationEvent, FALSE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync g_VBoxInitIdcInfo.bStop = false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync g_VBoxInitIdcInfo.bInitialized = true;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinJobInit(&g_VBoxInitIdcInfo.Job, vboxNetFltWinInitIdcProbingWorker, &g_VBoxInitIdcInfo, false);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinJobEnqueueJob(&g_VBoxJobQueue, &g_VBoxInitIdcInfo.Job, false);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return VINF_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic int vboxNetFltWinInitNetFlt()
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync int rc;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync do
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync rc = vboxNetFltWinInitNetFltBase();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (RT_FAILURE(rc))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertFailed();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /*
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * connect to the support driver.
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * This will call back vboxNetFltOsOpenSupDrv (and maybe vboxNetFltOsCloseSupDrv)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * for establishing the connect to the support driver.
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync rc = vboxNetFltWinInitIdc();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (RT_FAILURE(rc))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertFailed();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinFiniNetFltBase();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync } while (0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return rc;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/* detach*/
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic int vboxNetFltWinDeleteInstance(PVBOXNETFLTINS pThis)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow(("vboxNetFltWinDeleteInstance: pThis=0x%p \n", pThis));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pThis);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pThis->fDisconnectedFromHost);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(!pThis->fRediscoveryPending);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pThis->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pThis->u.s.WinIf.PtState.OpState == kVBoxNetDevOpState_Deinitialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(!pThis->u.s.WinIf.hBinding);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pThis->u.s.WinIf.MpState.OpState == kVBoxNetDevOpState_Deinitialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETFLT_NO_PACKET_QUEUE
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(!pThis->u.s.PacketQueueWorker.pSG);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync RTSemMutexDestroy(pThis->u.s.hWinIfMutex);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDrvDereference();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return VINF_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic NDIS_STATUS vboxNetFltWinDisconnectIt(PVBOXNETFLTINS pInstance)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETFLT_NO_PACKET_QUEUE
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinQuFiniPacketQueue(pInstance);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return NDIS_STATUS_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/* detach*/
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinDetachFromInterface(PVBOXNETFLTINS pNetFlt, bool bOnUnbind)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync int rc;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogFlow((__FUNCTION__": pThis=%0xp\n", pNetFlt));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pNetFlt);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* paranoia to ensure the instance is not removed while we're waiting on the mutex
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * in case ndis does something unpredictable, e.g. calls our miniport halt independently
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * from protocol unbind and concurrently with it*/
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltRetain(pNetFlt, false);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync rc = RTSemMutexRequest(pNetFlt->u.s.hWinIfMutex, RT_INDEFINITE_WAIT);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (RT_SUCCESS(rc))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(vboxNetFltWinGetWinIfState(pNetFlt) == kVBoxWinIfState_Connected);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Initialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.PtState) == kVBoxNetDevOpState_Initialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (vboxNetFltWinGetWinIfState(pNetFlt) == kVBoxWinIfState_Connected)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSetWinIfState(pNetFlt, kVBoxWinIfState_Disconnecting);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinPtDoUnbinding(pNetFlt, bOnUnbind);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinMpDoDeinitialization(pNetFlt);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSetWinIfState(pNetFlt, kVBoxWinIfState_Disconnected);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.PtState) == kVBoxNetDevOpState_Deinitialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinPtFiniWinIf(&pNetFlt->u.s.WinIf);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* we're unbinding, make an unbind-related release */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltRelease(pNetFlt, false);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertBreakpoint();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pNetFlt->u.s.WinIf.OpenCloseStatus = NDIS_STATUS_FAILURE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!bOnUnbind)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = NDIS_STATUS_FAILURE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync RTSemMutexRelease(pNetFlt->u.s.hWinIfMutex);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertBreakpoint();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = NDIS_STATUS_FAILURE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* release for the retain we made before waining on the mutex */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltRelease(pNetFlt, false);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/**
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * Checks if the host (not us) has put the adapter in promiscuous mode.
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * @returns true if promiscuous, false if not.
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * @param pThis The instance.
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic bool vboxNetFltWinIsPromiscuous2(PVBOXNETFLTINS pThis)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (VBOXNETFLT_PROMISCUOUS_SUPPORTED(pThis))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bool bPromiscuous;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!vboxNetFltWinReferenceWinIf(pThis))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bPromiscuous = (pThis->u.s.WinIf.fUpperProtocolSetFilter & NDIS_PACKET_TYPE_PROMISCUOUS) == NDIS_PACKET_TYPE_PROMISCUOUS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /*vboxNetFltWinIsPromiscuous(pAdapt);*/
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDereferenceWinIf(pThis);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return bPromiscuous;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return false;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return true;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/**
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * Report the MAC address, promiscuous mode setting, GSO capabilities and
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * no-preempt destinations to the internal network.
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * Does nothing if we're not currently connected to an internal network.
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * @param pThis The instance data.
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic void vboxNetFltWinReportStuff(PVBOXNETFLTINS pThis)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /** @todo Keep these up to date, esp. the promiscuous mode bit. */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pThis->pSwitchPort
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync && vboxNetFltTryRetainBusyNotDisconnected(pThis))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pThis->pSwitchPort->pfnReportMacAddress(pThis->pSwitchPort, &pThis->u.s.MacAddr);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pThis->pSwitchPort->pfnReportPromiscuousMode(pThis->pSwitchPort,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinIsPromiscuous2(pThis));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pThis->pSwitchPort->pfnReportGsoCapabilities(pThis->pSwitchPort, 0,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync INTNETTRUNKDIR_WIRE | INTNETTRUNKDIR_HOST);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /** @todo We should be able to do pfnXmit at DISPATCH_LEVEL... */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pThis->pSwitchPort->pfnReportNoPreemptDsts(pThis->pSwitchPort, 0 /* none */);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltRelease(pThis, true /*fBusy*/);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/**
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * Worker for vboxNetFltWinAttachToInterface.
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * @param pAttachInfo Structure for communicating with
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * vboxNetFltWinAttachToInterface.
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic void vboxNetFltWinAttachToInterfaceWorker(PATTACH_INFO pAttachInfo)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLTINS pThis = pAttachInfo->pNetFltIf;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync int rc;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* to ensure we're not removed while we're here */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltRetain(pThis, false);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync rc = RTSemMutexRequest(pThis->u.s.hWinIfMutex, RT_INDEFINITE_WAIT);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (RT_SUCCESS(rc))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(vboxNetFltWinGetWinIfState(pThis) == kVBoxWinIfState_Disconnected);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(vboxNetFltWinGetOpState(&pThis->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(vboxNetFltWinGetOpState(&pThis->u.s.WinIf.PtState) == kVBoxNetDevOpState_Deinitialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (vboxNetFltWinGetWinIfState(pThis) == kVBoxWinIfState_Disconnected)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pAttachInfo->fRediscovery)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* rediscovery means adaptor bind is performed while intnet is already using it
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * i.e. adaptor was unbound while being used by intnet and now being bound back again */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(((VBOXNETFTLINSSTATE)ASMAtomicUoReadU32((uint32_t volatile *)&pThis->enmState)) == kVBoxNetFltInsState_Connected);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinPtInitWinIf(&pThis->u.s.WinIf, pAttachInfo->pCreateContext->pOurName);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinPtInitWinIf(&pThis->u.s.WinIf);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSetWinIfState(pThis, kVBoxWinIfState_Connecting);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinPtDoBinding(pThis, pAttachInfo->pCreateContext->pOurName, pAttachInfo->pCreateContext->pBindToName);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinMpDoInitialization(pThis, pAttachInfo->pCreateContext->hMiniportAdapter, pAttachInfo->pCreateContext->hWrapperConfigurationContext);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!pAttachInfo->fRediscovery)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDrvReference();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pThis->u.s.WinIf.OpenCloseStatus == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSetWinIfState(pThis, kVBoxWinIfState_Connected);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(vboxNetFltWinGetOpState(&pThis->u.s.WinIf.PtState) == kVBoxNetDevOpState_Initialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* 4. mark as connected */
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync RTSpinlockAcquire(pThis->hSpinlock);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ASMAtomicUoWriteBool(&pThis->fDisconnectedFromHost, false);
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync RTSpinlockRelease(pThis->hSpinlock);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pAttachInfo->Status = VINF_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pAttachInfo->pCreateContext->Status = NDIS_STATUS_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync RTSemMutexRelease(pThis->u.s.hWinIfMutex);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltRelease(pThis, false);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* 5. Report MAC address, promiscuousness and GSO capabilities. */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinReportStuff(pThis);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertBreakpoint();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!pAttachInfo->fRediscovery)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDrvDereference();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinPtDoUnbinding(pThis, true);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinMpDoDeinitialization(pThis);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertBreakpoint();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinPtFiniWinIf(&pThis->u.s.WinIf);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertBreakpoint();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSetWinIfState(pThis, kVBoxWinIfState_Disconnected);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(vboxNetFltWinGetOpState(&pThis->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(vboxNetFltWinGetOpState(&pThis->u.s.WinIf.PtState) == kVBoxNetDevOpState_Deinitialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertBreakpoint();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pAttachInfo->Status = VERR_GENERAL_FAILURE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pAttachInfo->pCreateContext->Status = Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync RTSemMutexRelease(pThis->u.s.hWinIfMutex);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertBreakpoint();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pAttachInfo->Status = rc;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltRelease(pThis, false);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/**
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * Common code for vboxNetFltOsInitInstance and
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * vboxNetFltOsMaybeRediscovered.
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * @returns IPRT status code.
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * @param pThis The instance.
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * @param fRediscovery True if vboxNetFltOsMaybeRediscovered is calling,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * false if it's vboxNetFltOsInitInstance.
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic int vboxNetFltWinAttachToInterface(PVBOXNETFLTINS pThis, void * pContext, bool fRediscovery)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ATTACH_INFO Info;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Info.pNetFltIf = pThis;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Info.fRediscovery = fRediscovery;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Info.pCreateContext = (PCREATE_INSTANCE_CONTEXT)pContext;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinAttachToInterfaceWorker(&Info);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return Info.Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic NTSTATUS vboxNetFltWinPtDevDispatch(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PIO_STACK_LOCATION pIrpSl = IoGetCurrentIrpStackLocation(pIrp);;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NTSTATUS Status = STATUS_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync switch (pIrpSl->MajorFunction)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync case IRP_MJ_DEVICE_CONTROL:
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = STATUS_NOT_SUPPORTED;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync case IRP_MJ_CREATE:
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync case IRP_MJ_CLEANUP:
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync case IRP_MJ_CLOSE:
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync default:
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pIrp->IoStatus.Status = Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync IoCompleteRequest(pIrp, IO_NO_INCREMENT);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic NDIS_STATUS vboxNetFltWinDevCreate(PVBOXNETFLTGLOBALS_WIN pGlobals)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STRING DevName, LinkName;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PDRIVER_DISPATCH aMajorFunctions[IRP_MJ_MAXIMUM_FUNCTION+1];
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisInitUnicodeString(&DevName, VBOXNETFLT_NAME_DEVICE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisInitUnicodeString(&LinkName, VBOXNETFLT_NAME_LINK);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(!pGlobals->hDevice);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(!pGlobals->pDevObj);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisZeroMemory(aMajorFunctions, sizeof (aMajorFunctions));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync aMajorFunctions[IRP_MJ_CREATE] = vboxNetFltWinPtDevDispatch;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync aMajorFunctions[IRP_MJ_CLEANUP] = vboxNetFltWinPtDevDispatch;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync aMajorFunctions[IRP_MJ_CLOSE] = vboxNetFltWinPtDevDispatch;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync aMajorFunctions[IRP_MJ_DEVICE_CONTROL] = vboxNetFltWinPtDevDispatch;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS Status = NdisMRegisterDevice(pGlobals->Mp.hNdisWrapper,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync &DevName, &LinkName,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync aMajorFunctions,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync &pGlobals->pDevObj,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync &pGlobals->hDevice);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic NDIS_STATUS vboxNetFltWinDevDestroy(PVBOXNETFLTGLOBALS_WIN pGlobals)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pGlobals->hDevice);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pGlobals->pDevObj);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS Status = NdisMDeregisterDevice(pGlobals->hDevice);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == NDIS_STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pGlobals->hDevice = NULL;
b47bb47439dd595c9715ef0b6874c89927ef3cbfvboxsync pGlobals->pDevObj = NULL;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic NDIS_STATUS vboxNetFltWinDevCreateReference(PVBOXNETFLTGLOBALS_WIN pGlobals)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS Status = KeWaitForSingleObject(&pGlobals->SynchEvent, Executive, KernelMode, FALSE, NULL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pGlobals->cDeviceRefs >= 0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (++pGlobals->cDeviceRefs == 1)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinDevCreate(pGlobals);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ObReferenceObject(pGlobals->pDevObj);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = NDIS_STATUS_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync KeSetEvent(&pGlobals->SynchEvent, 0, FALSE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* should never happen actually */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = NDIS_STATUS_FAILURE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic NDIS_STATUS vboxNetFltWinDevDereference(PVBOXNETFLTGLOBALS_WIN pGlobals)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS Status = KeWaitForSingleObject(&pGlobals->SynchEvent, Executive, KernelMode, FALSE, NULL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == STATUS_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(pGlobals->cDeviceRefs > 0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!(--pGlobals->cDeviceRefs))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ObDereferenceObject(pGlobals->pDevObj);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinDevDestroy(pGlobals);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = NDIS_STATUS_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync KeSetEvent(&pGlobals->SynchEvent, 0, FALSE);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* should never happen actually */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = NDIS_STATUS_FAILURE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/* reference the driver module to prevent driver unload */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(void) vboxNetFltWinDrvReference()
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDevCreateReference(&g_VBoxNetFltGlobalsWin);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/* dereference the driver module to prevent driver unload */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncDECLHIDDEN(void) vboxNetFltWinDrvDereference()
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDevDereference(&g_VBoxNetFltGlobalsWin);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync/*
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * The OS specific interface definition
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync *
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncbool vboxNetFltOsMaybeRediscovered(PVBOXNETFLTINS pThis)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* AttachToInterface true if disconnected */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return !ASMAtomicUoReadBool(&pThis->fDisconnectedFromHost);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncint vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, void *pvIfData, PINTNETSG pSG, uint32_t fDst)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync int rc = VINF_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync uint32_t cRefs = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (fDst & INTNETTRUNKDIR_WIRE)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cRefs++;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (fDst & INTNETTRUNKDIR_HOST)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cRefs++;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (fDst & INTNETTRUNKDIR_WIRE || fDst & INTNETTRUNKDIR_HOST)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cRefs = 1;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertReturn(cRefs, VINF_SUCCESS);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!vboxNetFltWinIncReferenceWinIf(pThis, cRefs))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return VERR_GENERAL_FAILURE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (fDst & INTNETTRUNKDIR_WIRE)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_PACKET pPacket;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pPacket = vboxNetFltWinNdisPacketFromSG(pThis, pSG, NULL /*pBufToFree*/,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync true /*fToWire*/, true /*fCopyMemory*/);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pPacket)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS fStatus;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOX_LOOPBACK_USEFLAGS
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* force "don't loopback" flags to prevent loopback branch invocation in any case
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * to avoid ndis misbehave */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisGetPacketFlags(pPacket) |= g_VBoxNetFltGlobalsWin.fPacketDontLoopBack;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* this is done by default in vboxNetFltWinNdisPacketFromSG */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#if defined(DEBUG_NETFLT_PACKETS) || !defined(VBOX_LOOPBACK_USEFLAGS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinLbPutSendPacket(pThis, pPacket, true /* bFromIntNet */);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisSend(&fStatus, pThis->u.s.WinIf.hBinding, pPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (fStatus != NDIS_STATUS_PENDING)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#if defined(DEBUG_NETFLT_PACKETS) || !defined(VBOX_LOOPBACK_USEFLAGS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* the status is NOT pending, complete the packet */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bool bTmp = vboxNetFltWinLbRemoveSendPacket(pThis, pPacket);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(bTmp);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!NT_SUCCESS(fStatus))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* TODO: convert status to VERR_xxx */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync rc = VERR_GENERAL_FAILURE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinFreeSGNdisPacket(pPacket, true);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* pending, dereference on packet complete */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cRefs--;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertFailed();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync rc = VERR_NO_MEMORY;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (fDst & INTNETTRUNKDIR_HOST)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (cRefs)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PNDIS_PACKET pPacket = vboxNetFltWinNdisPacketFromSG(pThis, pSG, NULL /*pBufToFree*/,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync false /*fToWire*/, true /*fCopyMemory*/);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (pPacket)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMIndicateReceivePacket(pThis->u.s.WinIf.hMiniport, &pPacket, 1);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync cRefs--;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifdef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync STATISTIC_INCREASE(pThis->u.s.WinIf.cRxSuccess);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertFailed();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifdef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync STATISTIC_INCREASE(pThis->u.s.WinIf.cRxError);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync rc = VERR_NO_MEMORY;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(cRefs <= 2);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (cRefs)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDecReferenceWinIf(pThis, cRefs);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return rc;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncvoid vboxNetFltPortOsSetActive(PVBOXNETFLTINS pThis, bool fActive)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* we first wait for all pending ops to complete
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync * this might include all packets queued for processing */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync for (;;)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (fActive)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!pThis->u.s.cModePassThruRefs)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!pThis->u.s.cModeNetFltRefs)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync break;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSleep(2);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (!vboxNetFltWinReferenceWinIf(pThis))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (fActive)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifdef DEBUG_misha
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_PHYSICAL_MEDIUM PhMedium;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bool bPromiscSupported;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinQueryPhysicalMedium(pThis, &PhMedium);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status != NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogRel(("vboxNetFltWinQueryPhysicalMedium failed, Status (0x%x), setting medium to NdisPhysicalMediumUnspecified\n", Status));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(Status == NDIS_STATUS_NOT_SUPPORTED);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status != NDIS_STATUS_NOT_SUPPORTED)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogRel(("vboxNetFltWinQueryPhysicalMedium failed, Status (0x%x), setting medium to NdisPhysicalMediumUnspecified\n", Status));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PhMedium = NdisPhysicalMediumUnspecified;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogRel(("(SUCCESS) vboxNetFltWinQueryPhysicalMedium SUCCESS\n"));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync bPromiscSupported = (!(PhMedium == NdisPhysicalMediumWirelessWan
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync || PhMedium == NdisPhysicalMediumWirelessLan
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync || PhMedium == NdisPhysicalMediumNative802_11
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync || PhMedium == NdisPhysicalMediumBluetooth
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /*|| PhMedium == NdisPhysicalMediumWiMax */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync ));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(bPromiscSupported == VBOXNETFLT_PROMISCUOUS_SUPPORTED(pThis));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (VBOXNETFLT_PROMISCUOUS_SUPPORTED(pThis))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinSetPromiscuous(pThis, fActive);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status != NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync LogRel(("vboxNetFltWinSetPromiscuous failed, Status (0x%x), fActive (%d)\n", Status, fActive));
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync AssertFailed();
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# ifdef VBOXNETADP_REPORT_DISCONNECTED
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (fActive)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMIndicateStatus(pThis->u.s.WinIf.hMiniport,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS_MEDIA_CONNECT,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync (PVOID)NULL,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync 0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMIndicateStatus(pThis->u.s.WinIf.hMiniport,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS_MEDIA_DISCONNECT,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync (PVOID)NULL,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync 0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (fActive)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* indicate status change to make the ip settings be re-picked for dhcp */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMIndicateStatus(pThis->u.s.WinIf.hMiniport,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS_MEDIA_DISCONNECT,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync (PVOID)NULL,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync 0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NdisMIndicateStatus(pThis->u.s.WinIf.hMiniport,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS_MEDIA_CONNECT,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync (PVOID)NULL,
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync 0);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync# endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDereferenceWinIf(pThis);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncint vboxNetFltOsDisconnectIt(PVBOXNETFLTINS pThis)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS Status = vboxNetFltWinDisconnectIt(pThis);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return Status == NDIS_STATUS_SUCCESS ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic void vboxNetFltWinConnectItWorker(PVOID pvContext)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PWORKER_INFO pInfo = (PWORKER_INFO)pvContext;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#if !defined(VBOXNETADP) || !defined(VBOXNETFLT_NO_PACKET_QUEUE)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync NDIS_STATUS Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync PVBOXNETFLTINS pInstance = pInfo->pNetFltIf;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* this is not a rediscovery, initialize Mac cache */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (vboxNetFltWinReferenceWinIf(pInstance))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinGetMacAddress(pInstance, &pInstance->u.s.MacAddr);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifdef VBOXNETFLT_NO_PACKET_QUEUE
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pInfo->Status = VINF_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Status = vboxNetFltWinQuInitPacketQueue(pInstance);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (Status == NDIS_STATUS_SUCCESS)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pInfo->Status = VINF_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pInfo->Status = VERR_GENERAL_FAILURE;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pInfo->Status = VERR_INTNET_FLT_IF_FAILED;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDereferenceWinIf(pInstance);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync else
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pInfo->Status = VERR_INTNET_FLT_IF_NOT_FOUND;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncstatic int vboxNetFltWinConnectIt(PVBOXNETFLTINS pThis)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync WORKER_INFO Info;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync Info.pNetFltIf = pThis;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinJobSynchExecAtPassive(vboxNetFltWinConnectItWorker, &Info);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (RT_SUCCESS(Info.Status))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinReportStuff(pThis);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return Info.Status;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncint vboxNetFltOsConnectIt(PVBOXNETFLTINS pThis)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return vboxNetFltWinConnectIt(pThis);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncvoid vboxNetFltOsDeleteInstance(PVBOXNETFLTINS pThis)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinDeleteInstance(pThis);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncint vboxNetFltOsInitInstance(PVBOXNETFLTINS pThis, void *pvContext)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync int rc = RTSemMutexCreate(&pThis->u.s.hWinIfMutex);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (RT_SUCCESS(rc))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync rc = vboxNetFltWinAttachToInterface(pThis, pvContext, false /*fRediscovery*/ );
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync if (RT_SUCCESS(rc))
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync {
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return rc;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync RTSemMutexDestroy(pThis->u.s.hWinIfMutex);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync }
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return rc;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncint vboxNetFltOsPreInitInstance(PVBOXNETFLTINS pThis)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pThis->u.s.cModeNetFltRefs = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync pThis->u.s.cModePassThruRefs = 0;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSetWinIfState(pThis, kVBoxWinIfState_Disconnected);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSetOpState(&pThis->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#ifndef VBOXNETADP
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync vboxNetFltWinSetOpState(&pThis->u.s.WinIf.PtState, kVBoxNetDevOpState_Deinitialized);
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync#endif
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return VINF_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncvoid vboxNetFltPortOsNotifyMacAddress(PVBOXNETFLTINS pThis, void *pvIfData, PCRTMAC pMac)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncint vboxNetFltPortOsConnectInterface(PVBOXNETFLTINS pThis, void *pvIf, void **ppvIfData)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* Nothing to do */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return VINF_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync
3331475701a5b12f98b3cfea07d5dca60072530fvboxsyncint vboxNetFltPortOsDisconnectInterface(PVBOXNETFLTINS pThis, void *pvIfData)
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync{
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync /* Nothing to do */
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync return VINF_SUCCESS;
3331475701a5b12f98b3cfea07d5dca60072530fvboxsync}