VBoxNetFlt-win.c revision 1d94ccd0c6d838a45dea3a79ba295adc4caabcf9
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* $Id$ */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** @file
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * VBoxNetFlt - Network Filter Driver (Host), Windows Specific Code. Integration with IntNet/NetFlt
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Copyright (C) 2008 Sun Microsystems, Inc.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * available from http://www.virtualbox.org. This file is free software;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * you can redistribute it and/or modify it under the terms of the GNU
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * General Public License (GPL) as published by the Free Software
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync *
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * additional information or have any questions.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Copyright (c) 1993-1999, Microsoft Corporation
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include "VBoxNetFltCommon-win.h"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <iprt/thread.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** represents the job element of the job queue
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * see comments for JOB_QUEUE */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsynctypedef struct _JOB
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** link in the job queue */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LIST_ENTRY ListEntry;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** job function to be executed */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync JOB_ROUTINE pRoutine;
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync /** parameter to be passed to the job function */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PVOID pContext;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** event that will be fired on job completion */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync KEVENT CompletionEvent;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** true if the job manager should use the completion even for completion indication, false-otherwise*/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bool bUseCompletionEvent;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync} JOB, *PJOB;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * represents the queue of jobs processed by the worker thred
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * we use the thread to process tasks which are required to be done at passive level
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * our callbacks may be called at APC level by IntNet, there are some tasks that we can not create at APC,
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync * e.g. thread creation. This is why we schedule such jobs to the worker thread working at passive level
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsynctypedef struct _JOB_QUEUE
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* jobs */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LIST_ENTRY Jobs;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* we are using ExInterlocked..List functions to access the jobs list */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync KSPIN_LOCK Lock;
afed5ab737f4aacfae3fe73776f40e989190a7cavboxsync /** this event is used to initiate a job worker thread kill */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync KEVENT KillEvent;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** this event is used to notify a worker thread that jobs are added to the queue */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync KEVENT NotifyEvent;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** worker thread */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PKTHREAD pThread;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync} JOB_QUEUE, *PJOB_QUEUE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsynctypedef struct _CREATE_INSTANCE_CONTEXT
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PNDIS_STRING pOurName;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PNDIS_STRING pBindToName;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_HANDLE hMiniportAdapter;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_HANDLE hWrapperConfigurationContext;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_STATUS Status;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}CREATE_INSTANCE_CONTEXT, *PCREATE_INSTANCE_CONTEXT;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*contexts used for our jobs */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* Attach context */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsynctypedef struct _ATTACH_INFO
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PVBOXNETFLTINS pNetFltIf;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PCREATE_INSTANCE_CONTEXT pCreateContext;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bool fRediscovery;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int Status;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}ATTACH_INFO, *PATTACH_INFO;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* general worker context */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsynctypedef struct _WORKER_INFO
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PVBOXNETFLTINS pNetFltIf;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int Status;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}WORKER_INFO, *PWORKER_INFO;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* idc initialization */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsynctypedef struct _INIT_IDC_INFO
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync JOB Job;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bool bInitialized;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync volatile bool bStop;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync volatile int rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync KEVENT hCompletionEvent;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}INIT_IDC_INFO, *PINIT_IDC_INFO;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** globals */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** global lock */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncNDIS_SPIN_LOCK g_GlobalLock;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** global job queue. some operations are required to be done at passive level, e.g. thread creation, adapter bind/unbind initiation,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * while IntNet typically calls us APC_LEVEL, so we just create a system thread in our DriverEntry and enqueue the jobs to that thread */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic JOB_QUEUE g_JobQueue;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * The (common) global data.
fdea543f71872a3ec3909536a4fce37ab7aa3a8bvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic VBOXNETFLTGLOBALS g_VBoxNetFltGlobals;
fdea543f71872a3ec3909536a4fce37ab7aa3a8bvboxsyncvolatile static bool g_bIdcInitialized;
fdea543f71872a3ec3909536a4fce37ab7aa3a8bvboxsyncINIT_IDC_INFO g_InitIdcInfo;
fdea543f71872a3ec3909536a4fce37ab7aa3a8bvboxsync
fdea543f71872a3ec3909536a4fce37ab7aa3a8bvboxsync#ifdef VBOX_LOOPBACK_USEFLAGS
fdea543f71872a3ec3909536a4fce37ab7aa3a8bvboxsyncUINT g_fPacketDontLoopBack;
fdea543f71872a3ec3909536a4fce37ab7aa3a8bvboxsyncUINT g_fPacketIsLoopedBack;
8f7bc6ad2b7bbcb4b3b96248cd2478e45f2e3b88vboxsync#endif
8f7bc6ad2b7bbcb4b3b96248cd2478e45f2e3b88vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#define LIST_ENTRY_2_JOB(pListEntry) \
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ( (PJOB)((uint8_t *)(pListEntry) - RT_OFFSETOF(JOB, ListEntry)) )
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int vboxNetFltWinAttachToInterface(PVBOXNETFLTINS pThis, void * pContext, bool fRediscovery);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int vboxNetFltWinConnectIt(PVBOXNETFLTINS pThis);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int vboxNetFltWinTryFiniIdc();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic void vboxNetFltWinFiniNetFltBase();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int vboxNetFltWinInitNetFltBase();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int vboxNetFltWinFiniNetFlt();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int vboxNetFltWinStartInitIdcProbing();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int vboxNetFltWinStopInitIdcProbing();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** makes the current thread to sleep for the given number of miliseconds */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(void) vboxNetFltWinSleep(ULONG milis)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTThreadSleep(milis);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** wait for the given device to be dereferenced */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(void) vboxNetFltWinWaitDereference(PADAPT_DEVICE pState)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifdef DEBUG
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync uint64_t StartNanoTS = RTTimeSystemNanoTS();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync uint64_t CurNanoTS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync while (ASMAtomicUoReadU32((volatile uint32_t *)&pState->cReferences))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinSleep(2);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifdef DEBUG
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync CurNanoTS = RTTimeSystemNanoTS();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(CurNanoTS - StartNanoTS > 20000000)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
a11c569636fa6838bd423f4631a9660a5a84204bvboxsync DBGPRINT(("device not idle"));
a11c569636fa6838bd423f4631a9660a5a84204bvboxsync Assert(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * mem functions
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* allocates and zeroes the nonpaged memory of a given size */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinMemAlloc(PVOID* ppMemBuf, UINT cbLength)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_STATUS fStatus = NdisAllocateMemoryWithTag(ppMemBuf, cbLength, MEM_TAG);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(fStatus == NDIS_STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
3ecf9412133496b2aeb090cfd33a286404ec59fbvboxsync NdisZeroMemory(*ppMemBuf, cbLength);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return fStatus;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* frees memory allocated with vboxNetFltWinMemAlloc */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(void) vboxNetFltWinMemFree(PVOID pMemBuf)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisFreeMemory(pMemBuf, 0, 0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* frees ndis buffers used on send/receive */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic VOID vboxNetFltWinFiniBuffers(PADAPT pAdapt)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* NOTE: don't check for NULL since NULL is a valid handle */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisFreeBufferPool(pAdapt->hSendBufferPoolHandle);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOX_NETFLT_ONDEMAND_BIND
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisFreeBufferPool(pAdapt->hRecvBufferPoolHandle);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync/* initializes ndis buffers used on send/receive */
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsyncstatic NDIS_STATUS vboxNetFltWinInitBuffers(PADAPT pAdapt)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync do
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* NOTE: NULL is a valid handle !!! */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync NdisAllocateBufferPool(&Status,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync &pAdapt->hSendBufferPoolHandle,
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync TX_BUFFER_POOL_SIZE);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(Status == NDIS_STATUS_SUCCESS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (Status != NDIS_STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
78a205e3fc6719d59e8c561b3d287d3a4f879852vboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync#ifndef VBOX_NETFLT_ONDEMAND_BIND
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* NOTE: NULL is a valid handle !!! */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisAllocateBufferPool(&Status,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync &pAdapt->hRecvBufferPoolHandle,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RX_BUFFER_POOL_SIZE);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(Status == NDIS_STATUS_SUCCESS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (Status != NDIS_STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisFreeBufferPool(pAdapt->hSendBufferPoolHandle);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync } while (FALSE);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return Status;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* initializes packet info pool and allocates the cSize packet infos for the pool */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic NDIS_STATUS vboxNetFltWinPpAllocatePacketInfoPool(PPACKET_INFO_POOL pPool, UINT cSize)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync UINT cbBufSize = sizeof(PACKET_INFO)*cSize;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PACKET_INFO * pPacketInfos;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_STATUS fStatus;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync UINT i;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(cSize > 0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync INIT_INTERLOCKED_PACKET_QUEUE(&pPool->Queue);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync fStatus = vboxNetFltWinMemAlloc((PVOID*)&pPacketInfos, cbBufSize);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
e08de24d4792d31b7f2aac29db5cb8840d940009vboxsync if(fStatus == NDIS_STATUS_SUCCESS)
9782b553bdb12385214a3ac596aff1476bcb7cbdvboxsync {
8a132edc1577cbe2a19cd778c1b2bea6ae5e8515vboxsync PPACKET_INFO pInfo;
e08de24d4792d31b7f2aac29db5cb8840d940009vboxsync pPool->pBuffer = pPacketInfos;
8a132edc1577cbe2a19cd778c1b2bea6ae5e8515vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync for(i = 0; i < cSize; i++)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pInfo = &pPacketInfos[i];
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinQuEnqueueTail(&pPool->Queue.Queue, pInfo);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pInfo->pPool = pPool;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
f9147fe1eaa4e35287f8f39282c7f92f0d7de0b7vboxsync Assert(0);
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync return fStatus;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* frees the packet info pool */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncVOID vboxNetFltWinPpFreePacketInfoPool(PPACKET_INFO_POOL pPool)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinMemFree(pPool->pBuffer);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync FINI_INTERLOCKED_PACKET_QUEUE(&pPool->Queue)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * copies one string to another. in case the destination string size is not enough to hold the complete source string
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * does nothing and returns NDIS_STATUS_RESOURCES .
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinCopyString(PNDIS_STRING pDst, PNDIS_STRING pSrc)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(pDst != pSrc)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(pDst->MaximumLength < pSrc->Length)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = NDIS_STATUS_RESOURCES;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pDst->Length = pSrc->Length;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(pDst->Buffer != pSrc->Buffer)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisMoveMemory(pDst->Buffer, pSrc->Buffer, pSrc->Length);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return Status;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/************************************************************************************
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * PINTNETSG pSG manipulation functions
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ************************************************************************************/
e52f819639386db020b2a635b47a415248c7fbf9vboxsyncstatic void vboxNetFltWinReinitSG(PINTNETSG pSG)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pSG->pvOwnerData = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pSG->pvUserData = NULL;
e02db9e0d46f862430895b82b10e8ecde075cf11vboxsync pSG->pvUserData2 = NULL;
680ca45722ec7123029ced4f88dfad87b397ef52vboxsync pSG->cUsers = 1;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pSG->fFlags = INTNETSG_FLAGS_TEMP;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pSG->cSegsUsed = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pSG->cbTotal = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic void vboxNetFltWinInitSG(PINTNETSG pSG, UINT cBufferCount)
0e77737b0ba913683e614db11463b31ca67aacbevboxsync{
0e77737b0ba913683e614db11463b31ca67aacbevboxsync pSG->pvOwnerData = NULL;
0e77737b0ba913683e614db11463b31ca67aacbevboxsync pSG->pvUserData = NULL;
0e77737b0ba913683e614db11463b31ca67aacbevboxsync pSG->pvUserData2 = NULL;
e08de24d4792d31b7f2aac29db5cb8840d940009vboxsync pSG->cUsers = 1;
0e77737b0ba913683e614db11463b31ca67aacbevboxsync pSG->fFlags = INTNETSG_FLAGS_TEMP;
e08de24d4792d31b7f2aac29db5cb8840d940009vboxsync pSG->cSegsAlloc = cBufferCount;
e4ea543752422f1139923e3e506c625b0a1827c5vboxsync pSG->cSegsUsed = 0;
e9a217d585085a6a6d129d27ca0d96a1b8e6d0eevboxsync pSG->cbTotal = 0;
2d53f6e472561965d363674e17f48d3bdffc24d3vboxsync}
2d53f6e472561965d363674e17f48d3bdffc24d3vboxsync
e9a217d585085a6a6d129d27ca0d96a1b8e6d0eevboxsync/* moves the contents of the given NDIS_BUFFER and all other buffers chained to it to the PINTNETSG
2d53f6e472561965d363674e17f48d3bdffc24d3vboxsync * the PINTNETSG is expected to contain one segment whose bugger is large enough to maintain
2d53f6e472561965d363674e17f48d3bdffc24d3vboxsync * the contents of the given NDIS_BUFFER and all other buffers chained to it */
2d53f6e472561965d363674e17f48d3bdffc24d3vboxsyncstatic NDIS_STATUS vboxNetFltWinNdisBufferMoveToSG0(PNDIS_BUFFER pBuffer, PINTNETSG pSG)
2d53f6e472561965d363674e17f48d3bdffc24d3vboxsync{
2d53f6e472561965d363674e17f48d3bdffc24d3vboxsync UINT cbSeg = 0;
e9a217d585085a6a6d129d27ca0d96a1b8e6d0eevboxsync PINTNETSEG paSeg;
2d53f6e472561965d363674e17f48d3bdffc24d3vboxsync uint8_t * ptr;
2d53f6e472561965d363674e17f48d3bdffc24d3vboxsync PVOID pVirtualAddress;
0e77737b0ba913683e614db11463b31ca67aacbevboxsync UINT cbCurrentLength;
0e77737b0ba913683e614db11463b31ca67aacbevboxsync NDIS_STATUS fStatus = NDIS_STATUS_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pSG->cSegsAlloc == 1);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync paSeg = pSG->aSegs;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ptr = (uint8_t*)paSeg->pv;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync paSeg->cb = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync paSeg->Phys = NIL_RTHCPHYS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pSG->cbTotal = 0;
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync Assert(paSeg->pv);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync while(pBuffer)
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisQueryBufferSafe(
e98b0df488a9ec7732b1d5c2e735ce707842e975vboxsync pBuffer,
e08de24d4792d31b7f2aac29db5cb8840d940009vboxsync &pVirtualAddress,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync &cbCurrentLength,
e08de24d4792d31b7f2aac29db5cb8840d940009vboxsync NormalPagePriority);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
e4ea543752422f1139923e3e506c625b0a1827c5vboxsync if(!pVirtualAddress)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync fStatus = NDIS_STATUS_FAILURE;
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync break;
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pSG->cbTotal += cbCurrentLength;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync paSeg->cb += cbCurrentLength;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisMoveMemory(ptr, pVirtualAddress, cbCurrentLength);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ptr += cbCurrentLength;
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisGetNextBuffer(
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pBuffer,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync &pBuffer);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync if(fStatus == NDIS_STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pSG->cSegsUsed = 1;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pSG->cbTotal == paSeg->cb);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return fStatus;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* converts the PNDIS_BUFFER to PINTNETSG by making the PINTNETSG segments to point to the memory buffers the
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync * ndis buffer(s) point to (as opposed to vboxNetFltWinNdisBufferMoveToSG0 which copies the memory from ndis buffers(s) to PINTNETSG) */
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsyncstatic NDIS_STATUS vboxNetFltWinNdisBuffersToSG(PNDIS_BUFFER pBuffer, PINTNETSG pSG)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync UINT cbSeg = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_STATUS fStatus = NDIS_STATUS_SUCCESS;
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync PVOID pVirtualAddress;
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync UINT cbCurrentLength;
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync while(pBuffer)
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync {
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync NdisQueryBufferSafe(
a6936eab59adc5624216e6e5e5e455fc6a40df7fvboxsync pBuffer,
e08de24d4792d31b7f2aac29db5cb8840d940009vboxsync &pVirtualAddress,
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync &cbCurrentLength,
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync NormalPagePriority);
e4ea543752422f1139923e3e506c625b0a1827c5vboxsync
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync if(!pVirtualAddress) {
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync fStatus = NDIS_STATUS_FAILURE;
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync break;
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync }
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync pSG->cbTotal += cbCurrentLength;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pSG->aSegs[cbSeg].cb = cbCurrentLength;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pSG->aSegs[cbSeg].pv = pVirtualAddress;
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync pSG->aSegs[cbSeg].Phys = NIL_RTHCPHYS;
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync cbSeg++;
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync NdisGetNextBuffer(
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pBuffer,
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync &pBuffer);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync AssertFatal(cbSeg <= pSG->cSegsAlloc);
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync
440444d68cda7866c59e2e3d3f236608ef1c316fvboxsync if(fStatus == NDIS_STATUS_SUCCESS)
d98e61ba075ed7d0b567a5d884bc85d643fe3de7vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pSG->cSegsUsed = cbSeg;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
79b24ef0ab7cd4a03a3571b3954c52ab8b573137vboxsync return fStatus;
79b24ef0ab7cd4a03a3571b3954c52ab8b573137vboxsync}
3dde2f85d4cf477621a3128887a2c08a8bca7c01vboxsync
79b24ef0ab7cd4a03a3571b3954c52ab8b573137vboxsyncstatic void vboxNetFltWinDeleteSG(PINTNETSG pSG)
79b24ef0ab7cd4a03a3571b3954c52ab8b573137vboxsync{
79b24ef0ab7cd4a03a3571b3954c52ab8b573137vboxsync vboxNetFltWinMemFree(pSG);
79b24ef0ab7cd4a03a3571b3954c52ab8b573137vboxsync}
79b24ef0ab7cd4a03a3571b3954c52ab8b573137vboxsync
79b24ef0ab7cd4a03a3571b3954c52ab8b573137vboxsyncstatic PINTNETSG vboxNetFltWinCreateSG(uint32_t cSize)
03319aeaef07ef63a404237f2cb56199131f4a03vboxsync{
03319aeaef07ef63a404237f2cb56199131f4a03vboxsync PINTNETSG pSG;
03319aeaef07ef63a404237f2cb56199131f4a03vboxsync NTSTATUS Status = vboxNetFltWinMemAlloc((PVOID*)&pSG, RT_OFFSETOF(INTNETSG, aSegs[cSize]));
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync if(Status == STATUS_SUCCESS)
03319aeaef07ef63a404237f2cb56199131f4a03vboxsync {
5e797edc29f96c8367de4fbf5874171c24a89ba7vboxsync vboxNetFltWinInitSG(pSG, cSize);
3dde2f85d4cf477621a3128887a2c08a8bca7c01vboxsync return pSG;
5e797edc29f96c8367de4fbf5874171c24a89ba7vboxsync }
5e797edc29f96c8367de4fbf5874171c24a89ba7vboxsync
5e797edc29f96c8367de4fbf5874171c24a89ba7vboxsync return NULL;
8e8844a522f5d335f177a0313b03067d79cce201vboxsync}
8e8844a522f5d335f177a0313b03067d79cce201vboxsync
5e797edc29f96c8367de4fbf5874171c24a89ba7vboxsync/************************************************************************************
8e8844a522f5d335f177a0313b03067d79cce201vboxsync * packet queue functions
5e797edc29f96c8367de4fbf5874171c24a89ba7vboxsync ************************************************************************************/
5e797edc29f96c8367de4fbf5874171c24a89ba7vboxsync
5e797edc29f96c8367de4fbf5874171c24a89ba7vboxsync#if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP)
3dde2f85d4cf477621a3128887a2c08a8bca7c01vboxsyncstatic NDIS_STATUS vboxNetFltWinQuPostPacket(PADAPT pAdapt, PNDIS_PACKET pPacket, PINTNETSG pSG, uint32_t fFlags
03319aeaef07ef63a404237f2cb56199131f4a03vboxsync# ifdef DEBUG_NETFLT_PACKETS
79b24ef0ab7cd4a03a3571b3954c52ab8b573137vboxsync , PNDIS_PACKET pTmpPacket
3dde2f85d4cf477621a3128887a2c08a8bca7c01vboxsync# endif
3dde2f85d4cf477621a3128887a2c08a8bca7c01vboxsync )
e08de24d4792d31b7f2aac29db5cb8840d940009vboxsync{
79b24ef0ab7cd4a03a3571b3954c52ab8b573137vboxsync NDIS_STATUS fStatus;
e08de24d4792d31b7f2aac29db5cb8840d940009vboxsync PNDIS_PACKET pMyPacket;
e4ea543752422f1139923e3e506c625b0a1827c5vboxsync bool bSrcHost = fFlags & PACKET_SRC_HOST;
5e797edc29f96c8367de4fbf5874171c24a89ba7vboxsync
79b24ef0ab7cd4a03a3571b3954c52ab8b573137vboxsync LogFlow(("posting packet back to driver stack..\n"));
79b24ef0ab7cd4a03a3571b3954c52ab8b573137vboxsync
79b24ef0ab7cd4a03a3571b3954c52ab8b573137vboxsync if(!pPacket)
79b24ef0ab7cd4a03a3571b3954c52ab8b573137vboxsync {
79b24ef0ab7cd4a03a3571b3954c52ab8b573137vboxsync /* INTNETSG was in the packet queue, create a new NdisPacket from INTNETSG*/
79b24ef0ab7cd4a03a3571b3954c52ab8b573137vboxsync pMyPacket = vboxNetFltWinNdisPacketFromSG(pAdapt, /* PADAPT */
79b24ef0ab7cd4a03a3571b3954c52ab8b573137vboxsync pSG, /* PINTNETSG */
03319aeaef07ef63a404237f2cb56199131f4a03vboxsync pSG, /* PVOID pBufToFree */
5e797edc29f96c8367de4fbf5874171c24a89ba7vboxsync bSrcHost, /* bool bToWire */
3dde2f85d4cf477621a3128887a2c08a8bca7c01vboxsync false); /* bool bCopyMemory */
3dde2f85d4cf477621a3128887a2c08a8bca7c01vboxsync
3dde2f85d4cf477621a3128887a2c08a8bca7c01vboxsync Assert(pMyPacket);
8e8844a522f5d335f177a0313b03067d79cce201vboxsync
8e8844a522f5d335f177a0313b03067d79cce201vboxsync NDIS_SET_PACKET_STATUS(pMyPacket, NDIS_STATUS_SUCCESS);
9a12d720d4db6c26d09600ddab781ad8df5e1826vboxsync
8e8844a522f5d335f177a0313b03067d79cce201vboxsync DBG_CHECK_PACKET_AND_SG(pMyPacket, pSG);
9a12d720d4db6c26d09600ddab781ad8df5e1826vboxsync
3dde2f85d4cf477621a3128887a2c08a8bca7c01vboxsync#ifdef DEBUG_NETFLT_PACKETS
3dde2f85d4cf477621a3128887a2c08a8bca7c01vboxsync Assert(pTmpPacket);
03319aeaef07ef63a404237f2cb56199131f4a03vboxsync
79b24ef0ab7cd4a03a3571b3954c52ab8b573137vboxsync DBG_CHECK_PACKET_AND_SG(pTmpPacket, pSG);
79b24ef0ab7cd4a03a3571b3954c52ab8b573137vboxsync
79b24ef0ab7cd4a03a3571b3954c52ab8b573137vboxsync DBG_CHECK_PACKETS(pTmpPacket, pMyPacket);
79b24ef0ab7cd4a03a3571b3954c52ab8b573137vboxsync#endif
f9147fe1eaa4e35287f8f39282c7f92f0d7de0b7vboxsync
f9147fe1eaa4e35287f8f39282c7f92f0d7de0b7vboxsync LogFlow(("non-ndis packet info, packet created (%p)\n", pMyPacket));
7082d29724f6c3788977a51591b0379fd3acbf72vboxsync }
7082d29724f6c3788977a51591b0379fd3acbf72vboxsync else
7082d29724f6c3788977a51591b0379fd3acbf72vboxsync {
7082d29724f6c3788977a51591b0379fd3acbf72vboxsync /* NDIS_PACKET was in the packet queue */
f9147fe1eaa4e35287f8f39282c7f92f0d7de0b7vboxsync DBG_CHECK_PACKET_AND_SG(pPacket, pSG);
e4ea543752422f1139923e3e506c625b0a1827c5vboxsync
f9147fe1eaa4e35287f8f39282c7f92f0d7de0b7vboxsync if(!(fFlags & PACKET_MINE))
f827fea1108b8f8a1a5f63318f6ec3cf4a9e7010vboxsync {
f9147fe1eaa4e35287f8f39282c7f92f0d7de0b7vboxsync /* the packet is the one that was passed to us in send/receive callback
f9147fe1eaa4e35287f8f39282c7f92f0d7de0b7vboxsync * According to the DDK, we can not post it further,
f9147fe1eaa4e35287f8f39282c7f92f0d7de0b7vboxsync * instead we should allocate our own packet.
f9147fe1eaa4e35287f8f39282c7f92f0d7de0b7vboxsync * So, allocate our own packet (pMyPacket) and copy the packet info there */
f9147fe1eaa4e35287f8f39282c7f92f0d7de0b7vboxsync if(bSrcHost)
f9147fe1eaa4e35287f8f39282c7f92f0d7de0b7vboxsync {
f9147fe1eaa4e35287f8f39282c7f92f0d7de0b7vboxsync fStatus = vboxNetFltWinPrepareSendPacket(pAdapt, pPacket, &pMyPacket/*, true*/);
f9147fe1eaa4e35287f8f39282c7f92f0d7de0b7vboxsync LogFlow(("packet from wire, packet created (%p)\n", pMyPacket));
e08de24d4792d31b7f2aac29db5cb8840d940009vboxsync }
f9147fe1eaa4e35287f8f39282c7f92f0d7de0b7vboxsync else
e08de24d4792d31b7f2aac29db5cb8840d940009vboxsync {
f9147fe1eaa4e35287f8f39282c7f92f0d7de0b7vboxsync fStatus = vboxNetFltWinPrepareRecvPacket(pAdapt, pPacket, &pMyPacket, false);
f9147fe1eaa4e35287f8f39282c7f92f0d7de0b7vboxsync LogFlow(("packet from wire, packet created (%p)\n", pMyPacket));
f827fea1108b8f8a1a5f63318f6ec3cf4a9e7010vboxsync }
f9147fe1eaa4e35287f8f39282c7f92f0d7de0b7vboxsync }
f9147fe1eaa4e35287f8f39282c7f92f0d7de0b7vboxsync else
f9147fe1eaa4e35287f8f39282c7f92f0d7de0b7vboxsync {
f9147fe1eaa4e35287f8f39282c7f92f0d7de0b7vboxsync /* the packet enqueued is ours, simply assign pMyPacket and zero pPacket */
f9147fe1eaa4e35287f8f39282c7f92f0d7de0b7vboxsync pMyPacket = pPacket;
f9147fe1eaa4e35287f8f39282c7f92f0d7de0b7vboxsync pPacket = NULL;
f9147fe1eaa4e35287f8f39282c7f92f0d7de0b7vboxsync }
f9147fe1eaa4e35287f8f39282c7f92f0d7de0b7vboxsync Assert(pMyPacket);
f9147fe1eaa4e35287f8f39282c7f92f0d7de0b7vboxsync }
f9147fe1eaa4e35287f8f39282c7f92f0d7de0b7vboxsync
fe49486f3c0fc3c327138e9a8f9ea9911d7c0d64vboxsync if (pMyPacket)
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync {
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync /* we have successfuly initialized our packet, post it to the host or to the wire */
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync if(bSrcHost)
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync {
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync#if defined(DEBUG_NETFLT_PACKETS) || !defined(VBOX_LOOPBACK_USEFLAGS)
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync vboxNetFltWinLbPutSendPacket(pAdapt, pMyPacket, false /* bFromIntNet */);
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync#endif
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync NdisSend(&fStatus, pAdapt->hBindingHandle, pMyPacket);
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync if (fStatus != NDIS_STATUS_PENDING)
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync {
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync#if defined(DEBUG_NETFLT_PACKETS) || !defined(VBOX_LOOPBACK_USEFLAGS)
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync /* the status is NOT pending, complete the packet */
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync bool bTmp = vboxNetFltWinLbRemoveSendPacket(pAdapt, pMyPacket);
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync Assert(bTmp);
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync#endif
8e8844a522f5d335f177a0313b03067d79cce201vboxsync if(pPacket)
8e8844a522f5d335f177a0313b03067d79cce201vboxsync {
8e8844a522f5d335f177a0313b03067d79cce201vboxsync LogFlow(("status is not pending, completing packet (%p)\n", pPacket));
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync#ifndef WIN9X
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync NdisIMCopySendCompletePerPacketInfo (pPacket, pMyPacket);
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync#endif
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync NdisFreePacket(pMyPacket);
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync }
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync else
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync {
e08de24d4792d31b7f2aac29db5cb8840d940009vboxsync /* should never be here since the PINTNETSG is stored only when the underlying miniport
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync * indicates NDIS_STATUS_RESOURCES, we should never have this when processing
e08de24d4792d31b7f2aac29db5cb8840d940009vboxsync * the "from-host" packets */
e4ea543752422f1139923e3e506c625b0a1827c5vboxsync Assert(0);
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync LogFlow(("status is not pending, freeing myPacket (%p)\n", pMyPacket));
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync vboxNetFltWinFreeSGNdisPacket(pMyPacket, false);
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync }
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync }
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync }
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync else
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync {
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync NdisMIndicateReceivePacket(pAdapt->hMiniportHandle, &pMyPacket, 1);
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync fStatus = NDIS_STATUS_PENDING;
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync /* the packet receive completion is always indicated via MiniportReturnPacket */
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync }
8e8844a522f5d335f177a0313b03067d79cce201vboxsync }
8e8844a522f5d335f177a0313b03067d79cce201vboxsync else
8e8844a522f5d335f177a0313b03067d79cce201vboxsync {
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync /*we failed to create our packet */
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync Assert(0);
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync fStatus = NDIS_STATUS_FAILURE;
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync }
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync return fStatus;
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync}
46df4404c8dbbf3672e7aae8cd0b2770356e5b73vboxsync#endif
46df4404c8dbbf3672e7aae8cd0b2770356e5b73vboxsync
46df4404c8dbbf3672e7aae8cd0b2770356e5b73vboxsyncstatic bool vboxNetFltWinQuProcessInfo(PVBOXNETFLTINS pNetFltIf, PPACKET_QUEUE_WORKER pWorker, PPACKET_INFO pInfo)
46df4404c8dbbf3672e7aae8cd0b2770356e5b73vboxsync{
46df4404c8dbbf3672e7aae8cd0b2770356e5b73vboxsync PNDIS_PACKET pPacket = NULL;
3dde2f85d4cf477621a3128887a2c08a8bca7c01vboxsync PINTNETSG pSG = NULL;
46df4404c8dbbf3672e7aae8cd0b2770356e5b73vboxsync PADAPT pAdapt = PVBOXNETFLTINS_2_PADAPT(pNetFltIf);
3dde2f85d4cf477621a3128887a2c08a8bca7c01vboxsync UINT fFlags;
3dde2f85d4cf477621a3128887a2c08a8bca7c01vboxsync NDIS_STATUS Status;
3dde2f85d4cf477621a3128887a2c08a8bca7c01vboxsync#ifndef VBOXNETADP
3dde2f85d4cf477621a3128887a2c08a8bca7c01vboxsync bool bSrcHost;
50eab0c7ce9efeebd02c186d598f1db900f0c717vboxsync bool bPending;
3dde2f85d4cf477621a3128887a2c08a8bca7c01vboxsync bool bDropIt;
3dde2f85d4cf477621a3128887a2c08a8bca7c01vboxsync#endif
3dde2f85d4cf477621a3128887a2c08a8bca7c01vboxsync#ifdef DEBUG_NETFLT_PACKETS
3dde2f85d4cf477621a3128887a2c08a8bca7c01vboxsync /* packet used for matching */
3dde2f85d4cf477621a3128887a2c08a8bca7c01vboxsync PNDIS_PACKET pTmpPacket = NULL;
e08de24d4792d31b7f2aac29db5cb8840d940009vboxsync#endif
3dde2f85d4cf477621a3128887a2c08a8bca7c01vboxsync
e08de24d4792d31b7f2aac29db5cb8840d940009vboxsync fFlags = GET_FLAGS_FROM_INFO(pInfo);
3dde2f85d4cf477621a3128887a2c08a8bca7c01vboxsync#ifndef VBOXNETADP
3dde2f85d4cf477621a3128887a2c08a8bca7c01vboxsync bSrcHost = (fFlags & PACKET_SRC_HOST) != 0;
3dde2f85d4cf477621a3128887a2c08a8bca7c01vboxsync#endif
50eab0c7ce9efeebd02c186d598f1db900f0c717vboxsync
3dde2f85d4cf477621a3128887a2c08a8bca7c01vboxsync /* we first need to obtain the INTNETSG to be passed to intnet */
3dde2f85d4cf477621a3128887a2c08a8bca7c01vboxsync
3dde2f85d4cf477621a3128887a2c08a8bca7c01vboxsync /* the queue may contain two "types" of packets:
46df4404c8dbbf3672e7aae8cd0b2770356e5b73vboxsync * the NDIS_PACKET and the INTNETSG.
46df4404c8dbbf3672e7aae8cd0b2770356e5b73vboxsync * I.e. on send/receive we typically enqueue the NDIS_PACKET passed to us by ndis,
46df4404c8dbbf3672e7aae8cd0b2770356e5b73vboxsync * however in case our ProtocolReceive is called or the packet's status is set to NDIS_STSTUS_RESOURCES
46df4404c8dbbf3672e7aae8cd0b2770356e5b73vboxsync * in ProtocolReceivePacket, we must return the packet immediately on ProtocolReceive*** exit
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync * In this case we allocate the INTNETSG, copy the ndis packet data there and enqueue it.
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync * In this case the packet info flags has the PACKET_SG fag set
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync *
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync * Besides that the NDIS_PACKET contained in the queue could be either the one passed to us in our send/receive callback
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync * or the one created by us. The latter is possible in case our ProtocolReceive callback is called and we call NdisTransferData
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync * in this case we need to allocate the packet the data to be transfered to.
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync * If the enqueued packet is the one allocated by us the PACKET_MINE flag is set
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync * */
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync if((fFlags & PACKET_SG) == 0)
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync {
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync /* we have NDIS_PACKET enqueued, we need to convert it to INTNETSG to be passed to intnet */
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync PNDIS_BUFFER pCurrentBuffer = NULL;
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync UINT cBufferCount;
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync UINT uBytesCopied = 0;
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync UINT cbPacketLength;
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync pPacket = (PNDIS_PACKET)GET_PACKET_FROM_INFO(pInfo);
e08de24d4792d31b7f2aac29db5cb8840d940009vboxsync LogFlow(("ndis packet info, packet (%p)\n", pPacket));
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync
e08de24d4792d31b7f2aac29db5cb8840d940009vboxsync LogFlow(("preparing pSG"));
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync NdisQueryPacket(pPacket,
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync NULL,
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync &cBufferCount,
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync &pCurrentBuffer,
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync &cbPacketLength);
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync Assert(cBufferCount);
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync /* we can not allocate the INTNETSG on stack since in this case we may get stack overflow
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync * somewhere outside of our driver (3 pages of system thread stack does not seem to be enough)
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * since we have a "serialized" packet processing, i.e. all packets are being processed and passed
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * to intnet by this thread, we just use one previously allocated INTNETSG which is stored in PADAPT */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pSG = pWorker->pSG;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(cBufferCount > pSG->cSegsAlloc)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pSG = vboxNetFltWinCreateSG(cBufferCount + 2);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(pSG)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinDeleteSG(pWorker->pSG);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pWorker->pSG = pSG;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel(("Failed to reallocate the pSG\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(pSG)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* reinitialize */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinReinitSG(pSG);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* convert the ndis buffers to INTNETSG */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = vboxNetFltWinNdisBuffersToSG(pCurrentBuffer, pSG);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(Status != NDIS_STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pSG = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync DBG_CHECK_PACKET_AND_SG(pPacket, pSG);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* we have the INTNETSG enqueued. (see the above comment explaining why/when this may happen)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * just use the INTNETSG to pass it to intnet */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOX_NETFLT_ONDEMAND_BIND
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync #ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* the PINTNETSG is stored only when the underlying miniport
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * indicates NDIS_STATUS_RESOURCES, we should never have this when processing
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * the "from-host" packedts */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(!bSrcHost);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync #endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* we have both host and wire in ProtocolReceive */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pSG = (PINTNETSG)GET_PACKET_FROM_INFO(pInfo);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("not ndis packet info, pSG (%p)\n", pSG));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
e9a217d585085a6a6d129d27ca0d96a1b8e6d0eevboxsync#ifdef DEBUG_NETFLT_PACKETS
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(!pPacket && !pTmpPacket)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* create tmp packet that woud be used for matching */
e17bd6c32a8dd64f2d42838f9028216465e2caf0vboxsync pTmpPacket = vboxNetFltWinNdisPacketFromSG(pAdapt, /* PADAPT */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pSG, /* PINTNETSG */
e9a217d585085a6a6d129d27ca0d96a1b8e6d0eevboxsync pSG, /* PVOID pBufToFree */
e17bd6c32a8dd64f2d42838f9028216465e2caf0vboxsync bSrcHost, /* bool bToWire */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync true); /* bool bCopyMemory */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_SET_PACKET_STATUS(pTmpPacket, NDIS_STATUS_SUCCESS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
e17bd6c32a8dd64f2d42838f9028216465e2caf0vboxsync DBG_CHECK_PACKET_AND_SG(pTmpPacket, pSG);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
e17bd6c32a8dd64f2d42838f9028216465e2caf0vboxsync Assert(pTmpPacket);
e17bd6c32a8dd64f2d42838f9028216465e2caf0vboxsync }
e17bd6c32a8dd64f2d42838f9028216465e2caf0vboxsync#endif
e17bd6c32a8dd64f2d42838f9028216465e2caf0vboxsync do
e17bd6c32a8dd64f2d42838f9028216465e2caf0vboxsync {
e17bd6c32a8dd64f2d42838f9028216465e2caf0vboxsync#ifndef VBOXNETADP
e17bd6c32a8dd64f2d42838f9028216465e2caf0vboxsync /* the pSG was successfully initialized, post it to the netFlt*/
e17bd6c32a8dd64f2d42838f9028216465e2caf0vboxsync#ifndef VBOX_NETFLT_ONDEMAND_BIND
e17bd6c32a8dd64f2d42838f9028216465e2caf0vboxsync bDropIt =
e17bd6c32a8dd64f2d42838f9028216465e2caf0vboxsync#endif
e17bd6c32a8dd64f2d42838f9028216465e2caf0vboxsync pSG ? pNetFltIf->pSwitchPort->pfnRecv(pNetFltIf->pSwitchPort, pSG,
e17bd6c32a8dd64f2d42838f9028216465e2caf0vboxsync bSrcHost ? INTNETTRUNKDIR_HOST : INTNETTRUNKDIR_WIRE
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync )
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync : false;
49748bb305bd71f672cd083af208f4bb08c5d6abvboxsync#else
49748bb305bd71f672cd083af208f4bb08c5d6abvboxsync if(pSG)
49748bb305bd71f672cd083af208f4bb08c5d6abvboxsync {
49748bb305bd71f672cd083af208f4bb08c5d6abvboxsync pNetFltIf->pSwitchPort->pfnRecv(pNetFltIf->pSwitchPort, pSG, INTNETTRUNKDIR_HOST);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync STATISTIC_INCREASE(pAdapt->cTxSuccess);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync STATISTIC_INCREASE(pAdapt->cTxError);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(!bDropIt)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = vboxNetFltWinQuPostPacket(pAdapt, pPacket, pSG, fFlags
b9ca93dd1ad44cb8b27679dc5624be2f7b7f7af5vboxsync# ifdef DEBUG_NETFLT_PACKETS
b9ca93dd1ad44cb8b27679dc5624be2f7b7f7af5vboxsync , pTmpPacket
b9ca93dd1ad44cb8b27679dc5624be2f7b7f7af5vboxsync# endif
b9ca93dd1ad44cb8b27679dc5624be2f7b7f7af5vboxsync );
b9ca93dd1ad44cb8b27679dc5624be2f7b7f7af5vboxsync
b9ca93dd1ad44cb8b27679dc5624be2f7b7f7af5vboxsync if(Status == NDIS_STATUS_PENDING)
7c3417bbf525c03163d54d151a277a981d5d61b6vboxsync {
e9a217d585085a6a6d129d27ca0d96a1b8e6d0eevboxsync /* we will process packet completion in the completion routine */
8b984478b755f4d3091b977d9beac9fb7434279fvboxsync bPending = true;
8b984478b755f4d3091b977d9beac9fb7434279fvboxsync break;
e9a217d585085a6a6d129d27ca0d96a1b8e6d0eevboxsync }
e9a217d585085a6a6d129d27ca0d96a1b8e6d0eevboxsync }
51d4024e2984de499ecd878341898f71f55cf9e0vboxsync else
51d4024e2984de499ecd878341898f71f55cf9e0vboxsync#endif
8b984478b755f4d3091b977d9beac9fb7434279fvboxsync {
e9a217d585085a6a6d129d27ca0d96a1b8e6d0eevboxsync Status = NDIS_STATUS_SUCCESS;
e9a217d585085a6a6d129d27ca0d96a1b8e6d0eevboxsync }
e9a217d585085a6a6d129d27ca0d96a1b8e6d0eevboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* drop it */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(pPacket)
14e483cf65160fb363043534151245ae4c215766vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(!(fFlags & PACKET_MINE))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* complete the packets */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(fFlags & PACKET_SRC_HOST)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOX_NETFLT_ONDEMAND_BIND
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* NDIS_SET_PACKET_STATUS(pPacket, Status); */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisMSendComplete(pAdapt->hMiniportHandle, pPacket, Status);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisReturnPackets(&pPacket, 1);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOX_NETFLT_ONDEMAND_BIND
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(!(fFlags & PACKET_SRC_HOST));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinFreeSGNdisPacket(pPacket, true);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pSG);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinMemFree(pSG);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
47b5427d1a541bcd269bc625c35b19d849071edfvboxsync bPending = false;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync } while(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
3964eef78ab9593263a3a982e26216d4d166869cvboxsync#ifdef DEBUG_NETFLT_PACKETS
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(pTmpPacket)
f02b41a7e54fc4e6b714f4e60260d94614d6e2e7vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinFreeSGNdisPacket(pTmpPacket, true);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return bPending;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return false;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * thread start function for the thread which processes the packets enqueued in our send and receive callbacks called by ndis
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * ndis calls us at DISPATCH_LEVEL, while IntNet is using kernel functions which require Irql<DISPATCH_LEVEL
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * this is why we can not immediately post packets to IntNet from our sen/receive callbacks
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * instead we put the incoming packets to the queue and maintain the system thread running at passive level
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * which processes the queue and posts the packets to IntNet, and further to the host or to the wire.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic VOID vboxNetFltWinQuPacketQueueWorkerThreadProc(PVBOXNETFLTINS pNetFltIf)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bool fResume = true;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NTSTATUS fStatus;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PADAPT pAdapt = PVBOXNETFLTINS_2_PADAPT(pNetFltIf);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PPACKET_QUEUE_WORKER pWorker = &pNetFltIf->u.s.PacketQueueWorker;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* two events we're waiting is "kill" and "notify" events
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * the former is used for the thread termination
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * the latter gets fired each time the packet is added to the queue */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PVOID pEvents[] = {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync (PVOID) &pWorker->KillEvent,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync (PVOID) &pWorker->NotifyEvent,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync };
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync while(fResume)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync uint32_t cNumProcessed;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync uint32_t cNumPostedToHostWire;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
e7081fdf0305eaa621e0dd6decf8b28c33febc58vboxsync fStatus = KeWaitForMultipleObjects(2, pEvents, WaitAny, Executive, KernelMode, FALSE,
3123bb2477edc752585e4bbd8e4cfedaf87997d1vboxsync NULL, NULL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(!NT_SUCCESS(fStatus) || fStatus == STATUS_WAIT_0)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* "kill" event was set
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * will process queued packets and exit */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync fResume = false;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("==> processing vboxNetFltWinQuPacketQueueWorkerThreadProc\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync cNumProcessed = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync cNumPostedToHostWire = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync do
78a205e3fc6719d59e8c561b3d287d3a4f879852vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PPACKET_INFO pInfo;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
78a205e3fc6719d59e8c561b3d287d3a4f879852vboxsync#ifdef DEBUG_NETFLT_PACKETS
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* packet used for matching */
78a205e3fc6719d59e8c561b3d287d3a4f879852vboxsync PNDIS_PACKET pTmpPacket = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*TODO: FIXME: !!! the better approach for performance would be to dequeue all packets at once
78a205e3fc6719d59e8c561b3d287d3a4f879852vboxsync * and then go through all dequeued packets
78a205e3fc6719d59e8c561b3d287d3a4f879852vboxsync * the same should be done for enqueue !!! */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pInfo = vboxNetFltWinQuInterlockedDequeueHead(&pWorker->PacketQueue);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(!pInfo)
47b5427d1a541bcd269bc625c35b19d849071edfvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("==> found info (%p)\n", pInfo));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(vboxNetFltWinQuProcessInfo(pNetFltIf, pWorker, pInfo))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync cNumPostedToHostWire++;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinPpFreePacketInfo(pInfo);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync cNumProcessed++;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync } while(TRUE);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(cNumProcessed)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinDecReferenceNetFlt(pNetFltIf, cNumProcessed);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(cNumProcessed >= cNumPostedToHostWire);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(cNumProcessed != cNumPostedToHostWire)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinDecReferenceAdapt(pAdapt, cNumProcessed - cNumPostedToHostWire);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PsTerminateSystemThread(STATUS_SUCCESS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * thread start function for the job processing thread
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * see comments for PJOB_QUEUE
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic VOID vboxNetFltWinJobWorkerThreadProc(PJOB_QUEUE pQueue)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bool fResume = true;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NTSTATUS Status;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PVOID pEvents[] = {
47b5427d1a541bcd269bc625c35b19d849071edfvboxsync (PVOID) &pQueue->KillEvent,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync (PVOID) &pQueue->NotifyEvent,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync };
3e6d3b0af632bdcd931b5149915c7b8be1a732cdvboxsync
47b5427d1a541bcd269bc625c35b19d849071edfvboxsync do
a11c569636fa6838bd423f4631a9660a5a84204bvboxsync {
a11c569636fa6838bd423f4631a9660a5a84204bvboxsync Status = KeWaitForMultipleObjects(2, pEvents, WaitAny, Executive, KernelMode, FALSE,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NULL, NULL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(NT_SUCCESS(Status));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(!NT_SUCCESS(Status) || Status == STATUS_WAIT_0)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* will process queued jobs and exit */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(Status == STATUS_WAIT_0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync fResume = false;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync do
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PLIST_ENTRY pJobEntry = ExInterlockedRemoveHeadList(&pQueue->Jobs, &pQueue->Lock);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PJOB pJob;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(!pJobEntry)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pJob = LIST_ENTRY_2_JOB(pJobEntry);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pJob->pRoutine(pJob->pContext);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(pJob->bUseCompletionEvent)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync KeSetEvent(&pJob->CompletionEvent, 1, FALSE);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync } while(TRUE);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync } while(fResume);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(Status == STATUS_WAIT_0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PsTerminateSystemThread(STATUS_SUCCESS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * enqueues the job to the job queue to be processed by the job worker thread
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * see comments for PJOB_QUEUE
7235946d51c4e7b209b12cefb8a3924660a9d46bvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic VOID vboxNetFltWinJobEnqueueJob(PJOB_QUEUE pQueue, PJOB pJob, bool bEnqueueHead)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(bEnqueueHead)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ExInterlockedInsertHeadList(&pQueue->Jobs, &pJob->ListEntry, &pQueue->Lock);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ExInterlockedInsertTailList(&pQueue->Jobs, &pJob->ListEntry, &pQueue->Lock);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync KeSetEvent(&pQueue->NotifyEvent, 1, FALSE);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLINLINE(VOID) vboxNetFltWinJobInit(PJOB pJob, JOB_ROUTINE pRoutine, PVOID pContext, bool bUseEvent)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pJob->pRoutine = pRoutine;
0f5d1b2abd9e82c7ee46f1327287c44856604bcbvboxsync pJob->pContext = pContext;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pJob->bUseCompletionEvent = bUseEvent;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(bUseEvent)
e17bd6c32a8dd64f2d42838f9028216465e2caf0vboxsync KeInitializeEvent(&pJob->CompletionEvent, NotificationEvent, FALSE);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * enqueues the job to the job queue to be processed by the job worker thread and
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * blocks until the job is done
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * see comments for PJOB_QUEUE
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic VOID vboxNetFltWinJobSynchExec(PJOB_QUEUE pQueue, JOB_ROUTINE pRoutine, PVOID pContext)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync JOB Job;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinJobInit(&Job, pRoutine, pContext, true);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinJobEnqueueJob(pQueue, &Job, false);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync KeWaitForSingleObject(&Job.CompletionEvent, Executive, KernelMode, FALSE, NULL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * enqueues the job to be processed by the job worker thread at passive level and
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * blocks until the job is done
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(VOID) vboxNetFltWinJobSynchExecAtPassive(JOB_ROUTINE pRoutine, PVOID pContext)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinJobSynchExec(&g_JobQueue, pRoutine, pContext);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * helper function used for system thread creation
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic NTSTATUS vboxNetFltWinQuCreateSystemThread(PKTHREAD * ppThread, PKSTART_ROUTINE pStartRoutine, PVOID pStartContext)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NTSTATUS fStatus;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync HANDLE hThread;
47b5427d1a541bcd269bc625c35b19d849071edfvboxsync OBJECT_ATTRIBUTES fObjectAttributes;
47b5427d1a541bcd269bc625c35b19d849071edfvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync InitializeObjectAttributes(&fObjectAttributes, NULL, OBJ_KERNEL_HANDLE,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NULL, NULL);
0f5d1b2abd9e82c7ee46f1327287c44856604bcbvboxsync
c20b837b2c912dd4dcaaa676e15acd2b230108f0vboxsync fStatus = PsCreateSystemThread(&hThread, THREAD_ALL_ACCESS,
c20b837b2c912dd4dcaaa676e15acd2b230108f0vboxsync &fObjectAttributes, NULL, NULL,
0f5d1b2abd9e82c7ee46f1327287c44856604bcbvboxsync (PKSTART_ROUTINE) pStartRoutine, pStartContext);
0f5d1b2abd9e82c7ee46f1327287c44856604bcbvboxsync if (!NT_SUCCESS(fStatus))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return fStatus;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
0f5d1b2abd9e82c7ee46f1327287c44856604bcbvboxsync ObReferenceObjectByHandle(hThread, THREAD_ALL_ACCESS, NULL,
0f5d1b2abd9e82c7ee46f1327287c44856604bcbvboxsync KernelMode, (PVOID*) ppThread, NULL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ZwClose(hThread);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return STATUS_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * initialize the job queue
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * see comments for PJOB_QUEUE
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic NTSTATUS vboxNetFltWinJobInitQueue(PJOB_QUEUE pQueue)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NTSTATUS fStatus;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisZeroMemory(pQueue, sizeof(JOB_QUEUE));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync KeInitializeEvent(&pQueue->KillEvent, NotificationEvent, FALSE);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
96d8c2c77873591a51233b013fc1ec8bc774a096vboxsync KeInitializeEvent(&pQueue->NotifyEvent, SynchronizationEvent, FALSE);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync InitializeListHead(&pQueue->Jobs);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync fStatus = vboxNetFltWinQuCreateSystemThread(&pQueue->pThread, (PKSTART_ROUTINE)vboxNetFltWinJobWorkerThreadProc, pQueue);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(fStatus != STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pQueue->pThread = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pQueue->pThread);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return fStatus;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
96d8c2c77873591a51233b013fc1ec8bc774a096vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * deinitialize the job queue
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * see comments for PJOB_QUEUE
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic void vboxNetFltWinJobFiniQueue(PJOB_QUEUE pQueue)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(pQueue->pThread)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync KeSetEvent(&pQueue->KillEvent, 0, FALSE);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync KeWaitForSingleObject(pQueue->pThread, Executive,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync KernelMode, FALSE, NULL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * initializes the packet queue
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(NTSTATUS) vboxNetFltWinQuInitPacketQueue(PVBOXNETFLTINS pInstance)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NTSTATUS Status;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PPACKET_QUEUE_WORKER pWorker = &pInstance->u.s.PacketQueueWorker;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertFatal(!pWorker->pSG);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync KeInitializeEvent(&pWorker->KillEvent, NotificationEvent, FALSE);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync KeInitializeEvent(&pWorker->NotifyEvent, SynchronizationEvent, FALSE);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync INIT_INTERLOCKED_PACKET_QUEUE(&pWorker->PacketQueue);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync do
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
ee5858e9d955811dae9e6b8ecbb336cc6d0e7197vboxsync Status = vboxNetFltWinPpAllocatePacketInfoPool(&pWorker->PacketInfoPool, PACKET_INFO_POOL_SIZE);
b45d66c0e496e2fd861479202f3d43aad592bd14vboxsync
b45d66c0e496e2fd861479202f3d43aad592bd14vboxsync if(Status == NDIS_STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pWorker->pSG = vboxNetFltWinCreateSG(PACKET_QUEUE_SG_SEGS_ALLOC);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(!pWorker->pSG)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = STATUS_INSUFFICIENT_RESOURCES;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = vboxNetFltWinQuCreateSystemThread(&pWorker->pThread, (PKSTART_ROUTINE)vboxNetFltWinQuPacketQueueWorkerThreadProc, pInstance);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(Status != STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinPpFreePacketInfoPool(&pWorker->PacketInfoPool);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinMemFree(pWorker->pSG);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pWorker->pSG = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync } while(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return Status;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * deletes the packet queue
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(void) vboxNetFltWinQuFiniPacketQueue(PVBOXNETFLTINS pInstance)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PINTNETSG pSG;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PPACKET_QUEUE_WORKER pWorker = &pInstance->u.s.PacketQueueWorker;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// Assert(pAdapt->pPacketQueueSG);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* using the pPacketQueueSG as an indicator that the packet queue is initialized */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTSpinlockAcquire((pInstance)->hSpinlock, &Tmp);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(pWorker->pSG)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pSG = pWorker->pSG;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pWorker->pSG = NULL;
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync RTSpinlockRelease((pInstance)->hSpinlock, &Tmp);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync KeSetEvent(&pWorker->KillEvent, 0, FALSE);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync KeWaitForSingleObject(pWorker->pThread, Executive,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync KernelMode, FALSE, NULL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinPpFreePacketInfoPool(&pWorker->PacketInfoPool);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinDeleteSG(pSG);
9b45880674da6f82ca27cc28b0272de3dd3cc7dfvboxsync
9b45880674da6f82ca27cc28b0272de3dd3cc7dfvboxsync FINI_INTERLOCKED_PACKET_QUEUE(&pWorker->PacketQueue);
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync }
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync else
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTSpinlockRelease((pInstance)->hSpinlock, &Tmp);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * creates the INTNETSG containing one segment pointing to the buffer of size cbBufSize
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * the INTNETSG created should be cleaned with vboxNetFltWinMemFree
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinAllocSG(UINT cbBufSize, PINTNETSG *ppSG)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync UINT cbBufferOffset;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync UINT cbMemSize;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_STATUS Status;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PINTNETSG pSG;
10e1bc06b2908a0af56d92ffdbadd25b36a5ef61vboxsync
8f7bc6ad2b7bbcb4b3b96248cd2478e45f2e3b88vboxsync /* allocation:
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync * 1. SG_PACKET - with one aSegs pointing to
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * 2. buffer of cbPacketLength containing the entire packet */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync cbBufferOffset = sizeof(INTNETSG);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* make sure the buffer is aligned */
9b45880674da6f82ca27cc28b0272de3dd3cc7dfvboxsync if((cbBufferOffset & (sizeof(PVOID) - 1)) != 0)
9b45880674da6f82ca27cc28b0272de3dd3cc7dfvboxsync {
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync cbBufferOffset += sizeof(PVOID);
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync cbBufferOffset &= ~(sizeof(PVOID) - 1);
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync cbMemSize = cbBufferOffset + cbBufSize;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = vboxNetFltWinMemAlloc((PVOID*)&pSG, cbMemSize);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(Status == NDIS_STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinInitSG(pSG, 1);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pSG->aSegs[0].pv = (uint8_t *)pSG + cbBufferOffset;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pSG->aSegs[0].Phys = NIL_RTHCPHYS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pSG->aSegs[0].cb = cbBufSize;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pSG->cbTotal = cbBufSize;
10e1bc06b2908a0af56d92ffdbadd25b36a5ef61vboxsync pSG->cSegsUsed = 1;
8f7bc6ad2b7bbcb4b3b96248cd2478e45f2e3b88vboxsync
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync LogFlow(("pSG created (%p)\n", pSG));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *ppSG = pSG;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return Status;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * put the packet info to the queue
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLINLINE(void) vboxNetFltWinQuEnqueueInfo(PPACKET_QUEUE_WORKER pWorker, PPACKET_INFO pInfo)
9b45880674da6f82ca27cc28b0272de3dd3cc7dfvboxsync{
9b45880674da6f82ca27cc28b0272de3dd3cc7dfvboxsync vboxNetFltWinQuInterlockedEnqueueTail(&pWorker->PacketQueue, pInfo);
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync KeSetEvent(&pWorker->NotifyEvent, IO_NETWORK_INCREMENT, FALSE);
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * puts the packet to the queue
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @return NDIST_STATUS_SUCCESS iff the packet was enqueued successfully
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * and error status otherwise.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * NOTE: that the success status does NOT mean that the packet processing is completed, but only that it was enqueued successfully
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * 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)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * or if vboxNetFltWinQuEnqueuePacket failed, i.e. the packet was NOT enqueued
8f7bc6ad2b7bbcb4b3b96248cd2478e45f2e3b88vboxsync */
ec588a4ac8429a8b6c744544818b3ce3b2c75690vboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinQuEnqueuePacket(PVBOXNETFLTINS pInstance, PVOID pPacket, const UINT fPacketFlags)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PPACKET_INFO pInfo;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PPACKET_QUEUE_WORKER pWorker = &pInstance->u.s.PacketQueueWorker;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_STATUS fStatus = NDIS_STATUS_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync do
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(fPacketFlags & PACKET_COPY)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PNDIS_BUFFER pBuffer = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync UINT cBufferCount;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync UINT uBytesCopied = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync UINT cbPacketLength;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PINTNETSG pSG;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* the packet is Ndis packet */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(!(fPacketFlags & PACKET_SG));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(!(fPacketFlags & PACKET_MINE));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisQueryPacket((PNDIS_PACKET)pPacket,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NULL,
afed5ab737f4aacfae3fe73776f40e989190a7cavboxsync &cBufferCount,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync &pBuffer,
ee5858e9d955811dae9e6b8ecbb336cc6d0e7197vboxsync &cbPacketLength);
b45d66c0e496e2fd861479202f3d43aad592bd14vboxsync
b45d66c0e496e2fd861479202f3d43aad592bd14vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(cBufferCount);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync fStatus = vboxNetFltWinAllocSG(cbPacketLength, &pSG);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(fStatus != NDIS_STATUS_SUCCESS)
96d8c2c77873591a51233b013fc1ec8bc774a096vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pInfo = vboxNetFltWinPpAllocPacketInfo(&pWorker->PacketInfoPool);
96d8c2c77873591a51233b013fc1ec8bc774a096vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(!pInfo)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* TODO: what status to set? */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync fStatus = NDIS_STATUS_FAILURE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinMemFree(pSG);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pInfo->pPool);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* the packet we are queueing is SG, add PACKET_SG to flags */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync SET_FLAGS_TO_INFO(pInfo, fPacketFlags | PACKET_SG);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync SET_PACKET_TO_INFO(pInfo, pSG);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync fStatus = vboxNetFltWinNdisBufferMoveToSG0(pBuffer, pSG);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(fStatus != NDIS_STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinPpFreePacketInfo(pInfo);
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync vboxNetFltWinMemFree(pSG);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync DBG_CHECK_PACKET_AND_SG((PNDIS_PACKET)pPacket, pSG);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pInfo = vboxNetFltWinPpAllocPacketInfo(&pWorker->PacketInfoPool);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(!pInfo)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* TODO: what status to set? */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync fStatus = NDIS_STATUS_FAILURE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pInfo->pPool);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync SET_FLAGS_TO_INFO(pInfo, fPacketFlags);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync SET_PACKET_TO_INFO(pInfo, pPacket);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinQuEnqueueInfo(pWorker, pInfo);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync } while(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return fStatus;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOX_NETFLT_ONDEMAND_BIND
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * ioctl i/f
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic NTSTATUS
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncvboxNetFltWinPtDispatchIoctl(
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync IN PDEVICE_OBJECT pDeviceObject,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync IN PIO_STACK_LOCATION pIrpStack)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#if 0
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ULONG CtlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NTSTATUS Status = STATUS_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync switch(CtlCode)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case VBOXNETFLT_WIN_IOCTL_INIT:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = vboxNetFltWinInitIdc();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(!RT_SUCCESS(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = STATUS_UNSUCCESSFUL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case VBOXNETFLT_WIN_IOCTL_FINI:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* we are finalizing during unload */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* TODO: FIXME: need to prevent driver unload that can occur in case IntNet is connected to us,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * but we are not bound to any adapters */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* rc = vboxNetFltWinTryFiniIdc();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(!RT_SUCCESS(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = STATUS_UNSUCCESSFUL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync default:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = STATUS_NOT_SUPPORTED;
96d8c2c77873591a51233b013fc1ec8bc774a096vboxsync break;
c33db29e7b41467a35675031f5f5233839909083vboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return Status;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return STATUS_NOT_SUPPORTED;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncRoutine Description:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Process IRPs sent to this device.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncArguments:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync DeviceObject - pointer to a device object
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Irp - pointer to an I/O Request Packet
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncReturn Value:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NTSTATUS - STATUS_SUCCESS always - change this when adding
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync real code to handle ioctls.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync*/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(NTSTATUS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncvboxNetFltWinPtDispatch(
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync IN PDEVICE_OBJECT pDeviceObject,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync IN PIRP pIrp
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync )
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PIO_STACK_LOCATION pIrpStack;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NTSTATUS Status = STATUS_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("==>Pt Dispatch\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync switch (pIrpStack->MajorFunction)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case IRP_MJ_CREATE:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case IRP_MJ_CLEANUP:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case IRP_MJ_CLOSE:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case IRP_MJ_DEVICE_CONTROL:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = vboxNetFltWinPtDispatchIoctl(pDeviceObject, pIrpStack);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync default:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pIrp->IoStatus.Status = Status;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync IoCompleteRequest(pIrp, IO_NO_INCREMENT);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("<== Pt Dispatch\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return Status;
10e1bc06b2908a0af56d92ffdbadd25b36a5ef61vboxsync
8f7bc6ad2b7bbcb4b3b96248cd2478e45f2e3b88vboxsync}
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*
8f7bc6ad2b7bbcb4b3b96248cd2478e45f2e3b88vboxsync * netflt
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * NOTE! the routine is NOT re-enterable for the given pAdapt
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * the serialization is not implemented for performance reasons
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * since we are assuming the caller serializes the requests as IntNet does
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic NDIS_STATUS vboxNetFltWinSynchNdisRequest(PADAPT pAdapt, PNDIS_REQUEST pRequest)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* 1. serialize */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = RTSemFastMutexRequest(pAdapt->hSynchRequestMutex); AssertRC(rc);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(RT_SUCCESS(rc))
9b45880674da6f82ca27cc28b0272de3dd3cc7dfvboxsync {
9b45880674da6f82ca27cc28b0272de3dd3cc7dfvboxsync NDIS_STATUS fRequestStatus = NDIS_STATUS_SUCCESS;
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync /* 2. set pAdapt->pSynchRequest */
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync Assert(!pAdapt->pSynchRequest);
ec588a4ac8429a8b6c744544818b3ce3b2c75690vboxsync pAdapt->pSynchRequest = pRequest;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* 3. call NdisRequest */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisRequest(&fRequestStatus, pAdapt->hBindingHandle, pRequest);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(fRequestStatus == NDIS_STATUS_PENDING)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* 3.1 if pending wait and assign the resulting status */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync KeWaitForSingleObject(&pAdapt->hSynchCompletionEvent, Executive,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync KernelMode, FALSE, NULL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync fRequestStatus = pAdapt->fSynchCompletionStatus;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* 4. clear the pAdapt->pSynchRequest */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pAdapt->pSynchRequest = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTSemFastMutexRelease(pAdapt->hSynchRequestMutex); AssertRC(rc);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return fRequestStatus;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return NDIS_STATUS_FAILURE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinGetMacAddress(PADAPT pAdapt, PRTMAC pMac)
c33db29e7b41467a35675031f5f5233839909083vboxsync{
c33db29e7b41467a35675031f5f5233839909083vboxsync NDIS_REQUEST request;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_STATUS status;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync request.RequestType = NdisRequestQueryInformation;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync request.DATA.QUERY_INFORMATION.InformationBuffer = pMac;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync request.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(RTMAC);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync request.DATA.QUERY_INFORMATION.Oid = OID_802_3_CURRENT_ADDRESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync status = vboxNetFltWinSynchNdisRequest(pAdapt, &request);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(status != NDIS_STATUS_SUCCESS)
a27fbcbb29ffc2196c2ebd0f2dad92f40c7ec65dvboxsync {
a27fbcbb29ffc2196c2ebd0f2dad92f40c7ec65dvboxsync /* TODO */
10e1bc06b2908a0af56d92ffdbadd25b36a5ef61vboxsync Assert(0);
315f443a509c31db47b8f5cb94d26e54c3d5c497vboxsync }
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync
7cced997f7e362bb903898de921271b5e1011e3dvboxsync return status;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinQueryPhysicalMedium(PADAPT pAdapt, NDIS_PHYSICAL_MEDIUM * pMedium)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_REQUEST Request;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_STATUS Status;
9b45880674da6f82ca27cc28b0272de3dd3cc7dfvboxsync Request.RequestType = NdisRequestQueryInformation;
9b45880674da6f82ca27cc28b0272de3dd3cc7dfvboxsync Request.DATA.QUERY_INFORMATION.InformationBuffer = pMedium;
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync Request.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(NDIS_PHYSICAL_MEDIUM);
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync Request.DATA.QUERY_INFORMATION.Oid = OID_GEN_PHYSICAL_MEDIUM;
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync Status = vboxNetFltWinSynchNdisRequest(pAdapt, &Request);
ec588a4ac8429a8b6c744544818b3ce3b2c75690vboxsync if(Status != NDIS_STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(Status == NDIS_STATUS_NOT_SUPPORTED || Status == NDIS_STATUS_NOT_RECOGNIZED || Status == NDIS_STATUS_INVALID_OID)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = NDIS_STATUS_NOT_SUPPORTED;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel(("OID_GEN_PHYSICAL_MEDIUM failed: Status (0x%x)", Status));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return Status;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(bool) vboxNetFltWinIsPromiscuous(PADAPT pAdapt)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** @todo r=bird: This is too slow and is probably returning the wrong
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * information. What we're interested in is whether someone besides us
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * has put the interface into promiscuous mode. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_REQUEST request;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_STATUS status;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ULONG filter;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(VBOXNETFLT_PROMISCUOUS_SUPPORTED(pAdapt));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync request.RequestType = NdisRequestQueryInformation;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync request.DATA.QUERY_INFORMATION.InformationBuffer = &filter;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync request.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(filter);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync request.DATA.QUERY_INFORMATION.Oid = OID_GEN_CURRENT_PACKET_FILTER;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync status = vboxNetFltWinSynchNdisRequest(pAdapt, &request);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(status != NDIS_STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* TODO */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(0);
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync return false;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return (filter & NDIS_PACKET_TYPE_PROMISCUOUS) != 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinSetPromiscuous(PADAPT pAdapt, bool bYes)
8e8844a522f5d335f177a0313b03067d79cce201vboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(VBOXNETFLT_PROMISCUOUS_SUPPORTED(pAdapt));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(VBOXNETFLT_PROMISCUOUS_SUPPORTED(pAdapt))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_REQUEST Request;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_STATUS fStatus;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ULONG fFilter;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ULONG fExpectedFilter;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ULONG fOurFilter;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Request.RequestType = NdisRequestQueryInformation;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Request.DATA.QUERY_INFORMATION.InformationBuffer = &fFilter;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Request.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(fFilter);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Request.DATA.QUERY_INFORMATION.Oid = OID_GEN_CURRENT_PACKET_FILTER;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync fStatus = vboxNetFltWinSynchNdisRequest(pAdapt, &Request);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(fStatus != NDIS_STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* TODO: */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return fStatus;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(!pAdapt->bUpperProtSetFilterInitialized)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* the cache was not initialized yet, initiate it with the current filter value */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pAdapt->fUpperProtocolSetFilter = fFilter;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pAdapt->bUpperProtSetFilterInitialized = true;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(bYes)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
a27fbcbb29ffc2196c2ebd0f2dad92f40c7ec65dvboxsync fExpectedFilter = NDIS_PACKET_TYPE_PROMISCUOUS;
a27fbcbb29ffc2196c2ebd0f2dad92f40c7ec65dvboxsync fOurFilter = NDIS_PACKET_TYPE_PROMISCUOUS;
10e1bc06b2908a0af56d92ffdbadd25b36a5ef61vboxsync }
315f443a509c31db47b8f5cb94d26e54c3d5c497vboxsync else
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync {
7cced997f7e362bb903898de921271b5e1011e3dvboxsync fExpectedFilter = pAdapt->fUpperProtocolSetFilter;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync fOurFilter = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(fExpectedFilter != fFilter)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Request.RequestType = NdisRequestSetInformation;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Request.DATA.SET_INFORMATION.InformationBuffer = &fExpectedFilter;
9b45880674da6f82ca27cc28b0272de3dd3cc7dfvboxsync Request.DATA.SET_INFORMATION.InformationBufferLength = sizeof(fExpectedFilter);
9b45880674da6f82ca27cc28b0272de3dd3cc7dfvboxsync Request.DATA.SET_INFORMATION.Oid = OID_GEN_CURRENT_PACKET_FILTER;
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync fStatus = vboxNetFltWinSynchNdisRequest(pAdapt, &Request);
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync if(fStatus != NDIS_STATUS_SUCCESS)
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync {
ec588a4ac8429a8b6c744544818b3ce3b2c75690vboxsync /* TODO */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return fStatus;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pAdapt->fOurSetFilter = fOurFilter;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return fStatus;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return NDIS_STATUS_NOT_SUPPORTED;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else /* if defined VBOXNETADP */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Generates a new unique MAC address based on our vendor ID
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(void) vboxNetFltWinGenerateMACAddress(RTMAC *pMac)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync /* temporary use a time info */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync uint64_t NanoTS = RTTimeSystemNanoTS();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pMac->au8[0] = (uint8_t)((VBOXNETADP_VENDOR_ID >> 16) & 0xff);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pMac->au8[1] = (uint8_t)((VBOXNETADP_VENDOR_ID >> 8) & 0xff);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pMac->au8[2] = (uint8_t)(VBOXNETADP_VENDOR_ID & 0xff);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pMac->au8[3] = (uint8_t)(NanoTS & 0xff0000);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pMac->au16[2] = (uint16_t)(NanoTS & 0xffff);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(int) vboxNetFltWinMAC2NdisString(RTMAC *pMac, PNDIS_STRING pNdisString)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync static const char s_achDigits[17] = "0123456789abcdef";
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync uint8_t u8;
8e8844a522f5d335f177a0313b03067d79cce201vboxsync int i;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PWSTR pString;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* validate parameters */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertPtrReturn(pMac, VERR_INVALID_PARAMETER);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertPtrReturn(pNdisString, VERR_INVALID_PARAMETER);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertReturn(pNdisString->MaximumLength >= 13*sizeof(pNdisString->Buffer[0]), VERR_INVALID_PARAMETER);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pString = pNdisString->Buffer;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync for( i = 0; i < 6; i++)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync u8 = pMac->au8[i];
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pString[ 0] = s_achDigits[(u8 >> 4) & 0xf];
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pString[ 1] = s_achDigits[(u8/*>>0*/)& 0xf];
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pString += 2;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pNdisString->Length = 12*sizeof(pNdisString->Buffer[0]);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *pString = L'\0';
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VINF_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int vboxNetFltWinWchar2Int(WCHAR c, uint8_t * pv)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(c >= L'A' && c <= L'F')
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *pv = (c - L'A') + 10;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else if(c >= L'a' && c <= L'f')
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *pv = (c - L'a') + 10;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else if(c >= L'0' && c <= L'9')
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *pv = (c - L'0');
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VERR_INVALID_PARAMETER;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VINF_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(int) vboxNetFltWinMACFromNdisString(RTMAC *pMac, PNDIS_STRING pNdisString)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int i, rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PWSTR pString;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* validate parameters */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertPtrReturn(pMac, VERR_INVALID_PARAMETER);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertPtrReturn(pNdisString, VERR_INVALID_PARAMETER);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertReturn(pNdisString->Length >= 12*sizeof(pNdisString->Buffer[0]), VERR_INVALID_PARAMETER);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pString = pNdisString->Buffer;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync for(i = 0; i < 6; i++)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync uint8_t v1, v2;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = vboxNetFltWinWchar2Int(pString[0], &v1);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(RT_FAILURE(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = vboxNetFltWinWchar2Int(pString[1], &v2);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(RT_FAILURE(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pMac->au8[i] = (v1 << 4) | v2;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pString += 2;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * creates a NDIS_PACKET from the PINTNETSG
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifdef VBOX_NETFLT_ONDEMAND_BIND
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* TODO: the bToWire parameter seems to be unneeded here, remove them*/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(PNDIS_PACKET) vboxNetFltWinNdisPacketFromSG(PADAPT pAdapt, PINTNETSG pSG, PVOID pBufToFree, bool bToWire, bool bCopyMemory)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_STATUS fStatus;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PNDIS_PACKET pPacket;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pSG->cSegsUsed == 1);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pSG->cbTotal == pSG->aSegs[0].cb);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pSG->aSegs[0].pv);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pSG->cbTotal >= sizeof(ETH_HEADER_SIZE));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifdef VBOX_NETFLT_ONDEMAND_BIND
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisAllocatePacket(&fStatus, &pPacket, pAdapt->hSendPacketPoolHandle);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#elif defined(VBOXNETADP)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisAllocatePacket(&fStatus, &pPacket, pAdapt->hRecvPacketPoolHandle);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisAllocatePacket(&fStatus, &pPacket, bToWire ? pAdapt->hSendPacketPoolHandle : pAdapt->hRecvPacketPoolHandle);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(fStatus == NDIS_STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PNDIS_BUFFER pBuffer;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PVOID pMemBuf;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* @todo: generally we do not always need to zero-initialize the complete OOB data here, reinitialize only when/what we need,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * however we DO need to reset the status for the packets we indicate via NdisMIndicateReceivePacket to avoid packet loss
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * in case the status contains NDIS_STATUS_RESOURCES */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBOXNETFLT_OOB_INIT(pPacket);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(bCopyMemory)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync fStatus = vboxNetFltWinMemAlloc(&pMemBuf, pSG->cbTotal);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(fStatus == NDIS_STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisMoveMemory(pMemBuf, pSG->aSegs[0].pv, pSG->cbTotal);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisFreePacket(pPacket);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pPacket = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pMemBuf = pSG->aSegs[0].pv;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(fStatus == NDIS_STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifdef VBOX_NETFLT_ONDEMAND_BIND
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisAllocateBuffer(&fStatus, &pBuffer,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pAdapt->hSendBufferPoolHandle,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pMemBuf,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pSG->cbTotal);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#elif defined(VBOXNETADP)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisAllocateBuffer(&fStatus, &pBuffer,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pAdapt->hRecvBufferPoolHandle,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pMemBuf,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pSG->cbTotal);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisAllocateBuffer(&fStatus, &pBuffer,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bToWire ? pAdapt->hSendBufferPoolHandle : pAdapt->hRecvBufferPoolHandle,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pMemBuf,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pSG->cbTotal);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(fStatus == NDIS_STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisChainBufferAtBack(pPacket, pBuffer);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOX_NETFLT_ONDEMAND_BIND
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(bToWire)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PSEND_RSVD pSendRsvd;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pSendRsvd = (PSEND_RSVD)(pPacket->ProtocolReserved);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pSendRsvd->pOriginalPkt = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pSendRsvd->pBufToFree = pBufToFree;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifdef VBOX_LOOPBACK_USEFLAGS
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* set "don't loopback" flags */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisSetPacketFlags(pPacket, g_fPacketDontLoopBack);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisSetPacketFlags(pPacket, 0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOX_NETFLT_ONDEMAND_BIND
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PRECV_RSVD pRecvRsvd;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pRecvRsvd = (PRECV_RSVD)(pPacket->MiniportReserved);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pRecvRsvd->pOriginalPkt = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pRecvRsvd->pBufToFree = pBufToFree;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* me must set the header size on receive */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_SET_PACKET_HEADER_SIZE(pPacket, ETH_HEADER_SIZE);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* NdisAllocatePacket zero-initializes the OOB data,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * but keeps the packet flags, clean them here */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisSetPacketFlags(pPacket, 0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* TODO: set out of bound data */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(bCopyMemory)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinMemFree(pMemBuf);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisFreePacket(pPacket);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pPacket = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisFreePacket(pPacket);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pPacket = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pPacket = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync DBG_CHECK_PACKET_AND_SG(pPacket, pSG);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return pPacket;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * frees NDIS_PACKET creaed with vboxNetFltWinNdisPacketFromSG
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(void) vboxNetFltWinFreeSGNdisPacket(PNDIS_PACKET pPacket, bool bFreeMem)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync UINT cBufCount;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PNDIS_BUFFER pFirstBuffer;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync UINT uTotalPacketLength;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PNDIS_BUFFER pBuffer;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisQueryPacket(pPacket, NULL, &cBufCount, &pFirstBuffer, &uTotalPacketLength);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(cBufCount == 1);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync do
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisUnchainBufferAtBack(pPacket, &pBuffer);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(pBuffer != NULL)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PVOID pMemBuf;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync UINT cbLength;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisQueryBufferSafe(pBuffer, &pMemBuf, &cbLength, NormalPagePriority);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisFreeBuffer(pBuffer);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(bFreeMem)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinMemFree(pMemBuf);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync } while(true);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisFreePacket(pPacket);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Free all packet pools on the specified adapter.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pAdapt - pointer to ADAPT structure
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic VOID
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncvboxNetFltWinPtFreeAllPacketPools(
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync IN PADAPT pAdapt
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync )
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOX_NETFLT_ONDEMAND_BIND
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (pAdapt->hRecvPacketPoolHandle != NULL)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Free the packet pool that is used to indicate receives
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisFreePacketPool(pAdapt->hRecvPacketPoolHandle);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pAdapt->hRecvPacketPoolHandle = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif /* #ifndef VBOX_NETFLT_ONDEMAND_BIND*/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (pAdapt->hSendPacketPoolHandle != NULL)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Free the packet pool that is used to send packets below
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisFreePacketPool(pAdapt->hSendPacketPoolHandle);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pAdapt->hSendPacketPoolHandle = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
9c425bdea5f0991df62922b1584b805a86f2f898vboxsync }
9c425bdea5f0991df62922b1584b805a86f2f898vboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic void vboxNetFltWinAssociateMiniportProtocol()
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisIMAssociateMiniport(vboxNetFltWinMpGetHandle(), vboxNetFltWinPtGetHandle());
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * NetFlt driver unload function
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(VOID)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncvboxNetFltWinUnload(
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync IN PDRIVER_OBJECT DriverObject
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync )
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync UNREFERENCED_PARAMETER(DriverObject);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("vboxNetFltWinUnload: entered\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = vboxNetFltWinTryFiniIdc();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (RT_FAILURE(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* TODO: we can not prevent driver unload here */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log(("vboxNetFltWinTryFiniIdc - failed, busy.\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinJobFiniQueue(&g_JobQueue);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinPtDeregister();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOX_NETFLT_ONDEMAND_BIND
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinMpDeregister();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinFiniNetFltBase();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* don't use logging or any RT after de-init */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisFreeSpinLock(&g_GlobalLock);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncRT_C_DECLS_BEGIN
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncNTSTATUS
18db01bbe01d709ed64ef78717e98b94b7fee056vboxsyncDriverEntry(
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync IN PDRIVER_OBJECT DriverObject,
18db01bbe01d709ed64ef78717e98b94b7fee056vboxsync IN PUNICODE_STRING RegistryPath
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync );
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncRT_C_DECLS_END
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * First entry point to be called, when this driver is loaded.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Register with NDIS as an intermediate driver.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @return STATUS_SUCCESS if all initialization is successful, STATUS_XXX
6f516ad9911d9037a18778742caa955fe362f8ffvboxsync * error code if not.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
6f516ad9911d9037a18778742caa955fe362f8ffvboxsyncNTSTATUS
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDriverEntry(
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync IN PDRIVER_OBJECT DriverObject,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync IN PUNICODE_STRING RegistryPath
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync )
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifdef VBOX_LOOPBACK_USEFLAGS
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ULONG MjVersion;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ULONG MnVersion;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisAllocateSpinLock(&g_GlobalLock);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifdef VBOX_NETFLT_ONDEMAND_BIND
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* we are registering in the DriverEntry only when we are working as a protocol
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * since in this case our driver is loaded after the VBoxDrv*/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = vboxNetFltWinInitNetFlt();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* the idc registration is initiated via IOCTL since our driver
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * can be loaded when the VBoxDrv is not in case we are a Ndis IM driver */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = vboxNetFltWinInitNetFltBase();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertRC(rc);
5dda7f07dab8a954e6c4cf2378b15f921e60d9aavboxsync if(RT_SUCCESS(rc))
5dda7f07dab8a954e6c4cf2378b15f921e60d9aavboxsync {
5dda7f07dab8a954e6c4cf2378b15f921e60d9aavboxsync#ifdef VBOX_LOOPBACK_USEFLAGS
5dda7f07dab8a954e6c4cf2378b15f921e60d9aavboxsync PsGetVersion(&MjVersion, &MnVersion,
5dda7f07dab8a954e6c4cf2378b15f921e60d9aavboxsync NULL, /* PULONG BuildNumber OPTIONAL */
5dda7f07dab8a954e6c4cf2378b15f921e60d9aavboxsync NULL /* PUNICODE_STRING CSDVersion OPTIONAL */
5dda7f07dab8a954e6c4cf2378b15f921e60d9aavboxsync );
5dda7f07dab8a954e6c4cf2378b15f921e60d9aavboxsync
5dda7f07dab8a954e6c4cf2378b15f921e60d9aavboxsync g_fPacketDontLoopBack = NDIS_FLAGS_DONT_LOOPBACK;
5dda7f07dab8a954e6c4cf2378b15f921e60d9aavboxsync
5dda7f07dab8a954e6c4cf2378b15f921e60d9aavboxsync if(MjVersion == 5 && MnVersion == 0)
5dda7f07dab8a954e6c4cf2378b15f921e60d9aavboxsync {
5dda7f07dab8a954e6c4cf2378b15f921e60d9aavboxsync /* this is Win2k*/
5dda7f07dab8a954e6c4cf2378b15f921e60d9aavboxsync g_fPacketDontLoopBack |= NDIS_FLAGS_SKIP_LOOPBACK_W2K;
5dda7f07dab8a954e6c4cf2378b15f921e60d9aavboxsync }
5dda7f07dab8a954e6c4cf2378b15f921e60d9aavboxsync
5dda7f07dab8a954e6c4cf2378b15f921e60d9aavboxsync g_fPacketIsLoopedBack = NDIS_FLAGS_IS_LOOPBACK_PACKET;
5dda7f07dab8a954e6c4cf2378b15f921e60d9aavboxsync#endif
5dda7f07dab8a954e6c4cf2378b15f921e60d9aavboxsync
5dda7f07dab8a954e6c4cf2378b15f921e60d9aavboxsync Status = vboxNetFltWinJobInitQueue(&g_JobQueue);
5dda7f07dab8a954e6c4cf2378b15f921e60d9aavboxsync Assert(Status == STATUS_SUCCESS);
5dda7f07dab8a954e6c4cf2378b15f921e60d9aavboxsync if(Status == STATUS_SUCCESS)
5dda7f07dab8a954e6c4cf2378b15f921e60d9aavboxsync {
5dda7f07dab8a954e6c4cf2378b15f921e60d9aavboxsync /* note: we do it after we initialize the Job Queue */
5dda7f07dab8a954e6c4cf2378b15f921e60d9aavboxsync vboxNetFltWinStartInitIdcProbing();
5dda7f07dab8a954e6c4cf2378b15f921e60d9aavboxsync
5dda7f07dab8a954e6c4cf2378b15f921e60d9aavboxsync#ifndef VBOX_NETFLT_ONDEMAND_BIND
69a0f42fa2c531eb2cffb6d6f482d828d9adab34vboxsync Status = vboxNetFltWinMpRegister(DriverObject, RegistryPath);
5dda7f07dab8a954e6c4cf2378b15f921e60d9aavboxsync Assert(Status == STATUS_SUCCESS);
5dda7f07dab8a954e6c4cf2378b15f921e60d9aavboxsync if (Status == NDIS_STATUS_SUCCESS)
5dda7f07dab8a954e6c4cf2378b15f921e60d9aavboxsync#endif
5dda7f07dab8a954e6c4cf2378b15f921e60d9aavboxsync {
5dda7f07dab8a954e6c4cf2378b15f921e60d9aavboxsync#ifndef VBOXNETADP
5dda7f07dab8a954e6c4cf2378b15f921e60d9aavboxsync Status = vboxNetFltWinPtRegister(DriverObject, RegistryPath);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(Status == STATUS_SUCCESS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (Status == NDIS_STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinAssociateMiniportProtocol();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return STATUS_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync//#ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// vboxNetFltWinPtDeregister();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync//#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOX_NETFLT_ONDEMAND_BIND
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinMpDeregister();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinJobFiniQueue(&g_JobQueue);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinFiniNetFlt();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = NDIS_STATUS_FAILURE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisFreeSpinLock(&g_GlobalLock);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return(Status);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
c657bea826c7455c93bd45eaebab63a4c7742c42vboxsync#if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP)
c657bea826c7455c93bd45eaebab63a4c7742c42vboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * creates and initializes the packet to be sent to the underlying miniport given a packet posted to our miniport edge
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * according to DDK docs we must create our own packet rather than posting the one passed to us
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(NDIS_STATUS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncvboxNetFltWinPrepareSendPacket(
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync IN PADAPT pAdapt,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync IN PNDIS_PACKET pPacket,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync OUT PNDIS_PACKET *ppMyPacket
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*, IN bool bNetFltActive */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync )
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_STATUS fStatus;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisAllocatePacket(&fStatus,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ppMyPacket,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pAdapt->hSendPacketPoolHandle);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (fStatus == NDIS_STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PSEND_RSVD pSendRsvd;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pSendRsvd = (PSEND_RSVD)((*ppMyPacket)->ProtocolReserved);
afed5ab737f4aacfae3fe73776f40e989190a7cavboxsync pSendRsvd->pOriginalPkt = pPacket;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pSendRsvd->pBufToFree = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_PACKET_FIRST_NDIS_BUFFER(*ppMyPacket) = NDIS_PACKET_FIRST_NDIS_BUFFER(pPacket);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_PACKET_LAST_NDIS_BUFFER(*ppMyPacket) = NDIS_PACKET_LAST_NDIS_BUFFER(pPacket);
8a132edc1577cbe2a19cd778c1b2bea6ae5e8515vboxsync
8a132edc1577cbe2a19cd778c1b2bea6ae5e8515vboxsync vboxNetFltWinCopyPacketInfoOnSend(*ppMyPacket, pPacket);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifdef VBOX_LOOPBACK_USEFLAGS
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisGetPacketFlags(*ppMyPacket) |= g_fPacketDontLoopBack;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *ppMyPacket = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return fStatus;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * creates and initializes the packet to be sent to the upperlying protocol given a packet indicated to our protocol edge
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * according to DDK docs we must create our own packet rather than posting the one passed to us
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(NDIS_STATUS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncvboxNetFltWinPrepareRecvPacket(
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync IN PADAPT pAdapt,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync IN PNDIS_PACKET pPacket,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync OUT PNDIS_PACKET *ppMyPacket,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync IN bool bDpr
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync )
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_STATUS fStatus;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Get a packet off the pool and indicate that up
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(bDpr)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisDprAllocatePacket(&fStatus,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ppMyPacket,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pAdapt->hRecvPacketPoolHandle);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisAllocatePacket(&fStatus,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ppMyPacket,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pAdapt->hRecvPacketPoolHandle);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (fStatus == NDIS_STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PRECV_RSVD pRecvRsvd;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pRecvRsvd = (PRECV_RSVD)((*ppMyPacket)->MiniportReserved);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pRecvRsvd->pOriginalPkt = pPacket;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pRecvRsvd->pBufToFree = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_PACKET_FIRST_NDIS_BUFFER(*ppMyPacket) = NDIS_PACKET_FIRST_NDIS_BUFFER(pPacket);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_PACKET_LAST_NDIS_BUFFER(*ppMyPacket) = NDIS_PACKET_LAST_NDIS_BUFFER(pPacket);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync fStatus = vboxNetFltWinCopyPacketInfoOnRecv(*ppMyPacket, pPacket);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *ppMyPacket = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return fStatus;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * initializes the ADAPT (our context structure) and binds to the given adapter
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#if defined(VBOX_NETFLT_ONDEMAND_BIND)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PADAPT pAdapt)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#elif defined(VBOXNETADP)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PADAPT *ppAdapt, NDIS_HANDLE hMiniportAdapter, PNDIS_STRING pBindToMiniportName /* actually this is our miniport name*/, NDIS_HANDLE hWrapperConfigurationContext)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PADAPT *ppAdapt, PNDIS_STRING pOurMiniportName, PNDIS_STRING pBindToMiniportName)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_STATUS Status;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync do
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOX_NETFLT_ONDEMAND_BIND
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ANSI_STRING AnsiString;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc;
afed5ab737f4aacfae3fe73776f40e989190a7cavboxsync PVBOXNETFLTINS pInstance;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync USHORT cbAnsiName = pBindToMiniportName->Length;/* the lenght is is bytes ; *2 ;RtlUnicodeStringToAnsiSize(pBindToMiniportName)*/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync CREATE_INSTANCE_CONTEXT Context;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
8a132edc1577cbe2a19cd778c1b2bea6ae5e8515vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Context.pOurName = pOurMiniportName;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Context.pBindToName = pBindToMiniportName;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Context.hMiniportAdapter = hMiniportAdapter;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Context.hWrapperConfigurationContext = hWrapperConfigurationContext;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Context.Status = NDIS_STATUS_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AnsiString.Buffer = 0; /* will be allocated by RtlUnicodeStringToAnsiString */
8a132edc1577cbe2a19cd778c1b2bea6ae5e8515vboxsync AnsiString.Length = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AnsiString.MaximumLength = cbAnsiName;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = RtlUnicodeStringToAnsiString(&AnsiString, pBindToMiniportName, true);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(Status != STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = vboxNetFltSearchCreateInstance(&g_VBoxNetFltGlobals, AnsiString.Buffer, &pInstance, &Context);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RtlFreeAnsiString(&AnsiString);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(RT_FAILURE(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = Context.Status != NDIS_STATUS_SUCCESS ? Context.Status : NDIS_STATUS_FAILURE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pInstance);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(rc == VINF_ALREADY_INITIALIZED)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PADAPT pAdapt = PVBOXNETFLTINS_2_PADAPT(pInstance);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* the case when our adapter was unbound while IntNet was connected to it */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* the instance remains valid until intNet disconnects from it, we simply search and re-use it*/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* re-initialize PADAPT */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = vboxNetFltWinAttachToInterface(pInstance, &Context, true);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(RT_FAILURE(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = Context.Status != NDIS_STATUS_SUCCESS ? Context.Status : NDIS_STATUS_FAILURE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* release netflt */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltRelease(pInstance, false);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *ppAdapt = PVBOXNETFLTINS_2_PADAPT(pInstance);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = vboxNetFltWinPtAllocInitPADAPT(pAdapt);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (Status != NDIS_STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
afed5ab737f4aacfae3fe73776f40e989190a7cavboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = vboxNetFltWinPtDoBinding(pAdapt);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (Status != NDIS_STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinPtFiniPADAPT(pAdapt);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
ab1239d8445aa1fd4afddb7d0c8b90bbdc742010vboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }while(FALSE);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return Status;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * initializes the ADAPT
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifdef VBOX_NETFLT_ONDEMAND_BIND
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtAllocInitPADAPT(PADAPT pAdapt)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_STATUS Status;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync do
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = vboxNetFltWinPtInitPADAPT(pAdapt);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (Status != NDIS_STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = NDIS_STATUS_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync } while(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return Status;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * unbinds from the adapter we are bound to and deinitializes the ADAPT
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic NDIS_STATUS vboxNetFltWinPtFiniUnbind(PADAPT pAdapt)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_STATUS Status;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("==> vboxNetFltWinPtFiniUnbind: Adapt %p\n", pAdapt));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync do
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = vboxNetFltWinPtDoUnbinding(pAdapt, true);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(Status != NDIS_STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(0);
19b725c530eb49600728765de7ed451cbe290740vboxsync /* TODO: should we break ? */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* break; */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinPtFiniPADAPT(pAdapt);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync } while(0);
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync LogFlow(("<== vboxNetFltWinPtFiniUnbind: Adapt %p\n", pAdapt));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return Status;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * deinitializes the ADAPT
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(VOID) vboxNetFltWinPtFiniPADAPT(PADAPT pAdapt)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("<== vboxNetFltWinPtFiniPADAPT : pAdapt %p\n", pAdapt));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
10e1bc06b2908a0af56d92ffdbadd25b36a5ef61vboxsync Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
8f7bc6ad2b7bbcb4b3b96248cd2478e45f2e3b88vboxsync#ifndef VBOXNETADP
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync if(pAdapt->DeviceName.Buffer)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
8f7bc6ad2b7bbcb4b3b96248cd2478e45f2e3b88vboxsync vboxNetFltWinMemFree(pAdapt->DeviceName.Buffer);
ec588a4ac8429a8b6c744544818b3ce3b2c75690vboxsync }
9b45880674da6f82ca27cc28b0272de3dd3cc7dfvboxsync
9b45880674da6f82ca27cc28b0272de3dd3cc7dfvboxsync
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync FINI_INTERLOCKED_SINGLE_LIST(&pAdapt->TransferDataList);
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync# if defined(DEBUG_NETFLT_LOOPBACK) || !defined(VBOX_LOOPBACK_USEFLAGS)
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync FINI_INTERLOCKED_SINGLE_LIST(&pAdapt->SendPacketQueue);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOX_NETFLT_ONDEMAND_BIND
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* moved to vboxNetFltWinDetachFromInterfaceWorker */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinQuFiniPacketQueue(pAdapt);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinFiniBuffers(pAdapt);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
19b725c530eb49600728765de7ed451cbe290740vboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Free the memory here, if was not released earlier(by calling the HaltHandler)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinPtFreeAllPacketPools (pAdapt);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = RTSemFastMutexDestroy(pAdapt->hSynchRequestMutex); AssertRC(rc);
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("<== vboxNetFltWinPtFiniPADAPT : pAdapt %p\n", pAdapt));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(VOID) vboxNetFltWinPtFiniPADAPT(PADAPT pAdapt);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitPADAPT(IN PADAPT pAdapt, IN PNDIS_STRING pOurDeviceName)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitPADAPT(IN PADAPT pAdapt)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_STATUS Status;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc;
10e1bc06b2908a0af56d92ffdbadd25b36a5ef61vboxsync#endif
8f7bc6ad2b7bbcb4b3b96248cd2478e45f2e3b88vboxsync BOOLEAN bCallFiniOnFail = FALSE;
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("==> vboxNetFltWinPtInitPADAPT : pAdapt %p\n", pAdapt));
8f7bc6ad2b7bbcb4b3b96248cd2478e45f2e3b88vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync do
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
9b45880674da6f82ca27cc28b0272de3dd3cc7dfvboxsync NdisZeroMemory(pAdapt, sizeof(ADAPT));
9b45880674da6f82ca27cc28b0272de3dd3cc7dfvboxsync#ifndef VBOXNETADP
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync NdisInitializeEvent(&pAdapt->hEvent);
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync KeInitializeEvent(&pAdapt->hSynchCompletionEvent, SynchronizationEvent, FALSE);
ec588a4ac8429a8b6c744544818b3ce3b2c75690vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
9b45880674da6f82ca27cc28b0272de3dd3cc7dfvboxsync * Allocate a packet pool for sends. We need this to pass sends down.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * We cannot use the same packet descriptor that came down to our send
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * handler (see also NDIS 5.1 packet stacking).
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisAllocatePacketPoolEx(&Status,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync &pAdapt->hSendPacketPoolHandle,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync MIN_PACKET_POOL_SIZE,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync MAX_PACKET_POOL_SIZE - MIN_PACKET_POOL_SIZE,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync sizeof(SEND_RSVD));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (Status != NDIS_STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pAdapt->hSendPacketPoolHandle = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync Status = vboxNetFltWinInitBuffers(pAdapt);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (Status != NDIS_STATUS_SUCCESS)
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bCallFiniOnFail = TRUE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = RTSemFastMutexCreate(&pAdapt->hSynchRequestMutex);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(RT_FAILURE(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = NDIS_STATUS_FAILURE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOX_NETFLT_ONDEMAND_BIND
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = vboxNetFltWinMemAlloc((PVOID*)&pAdapt->DeviceName.Buffer, pOurDeviceName->Length);
9c425bdea5f0991df62922b1584b805a86f2f898vboxsync if(Status != NDIS_STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync Assert(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pAdapt->DeviceName.Buffer = NULL;
e4ea543752422f1139923e3e506c625b0a1827c5vboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pAdapt->DeviceName.MaximumLength = pOurDeviceName->Length;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pAdapt->DeviceName.Length = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = vboxNetFltWinCopyString(&pAdapt->DeviceName, pOurDeviceName);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(Status != NDIS_STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# endif
e4ea543752422f1139923e3e506c625b0a1827c5vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Allocate a packet pool for receives. We need this to indicate receives.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Same consideration as sends (see also NDIS 5.1 packet stacking).
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisAllocatePacketPoolEx(&Status,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync &pAdapt->hRecvPacketPoolHandle,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync MIN_PACKET_POOL_SIZE,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync MAX_PACKET_POOL_SIZE - MIN_PACKET_POOL_SIZE,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PROTOCOL_RESERVED_SIZE_IN_PACKET);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (Status != NDIS_STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pAdapt->hRecvPacketPoolHandle = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
9c425bdea5f0991df62922b1584b805a86f2f898vboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync NdisInitializeEvent(&pAdapt->MiniportInitEvent);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
e4ea543752422f1139923e3e506c625b0a1827c5vboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pAdapt->PTState.PowerState = NdisDeviceStateD3;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinSetOpState(&pAdapt->PTState, kVBoxNetDevOpState_Deinitialized);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync INIT_INTERLOCKED_SINGLE_LIST(&pAdapt->TransferDataList);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# if defined(DEBUG_NETFLT_LOOPBACK) || !defined(VBOX_LOOPBACK_USEFLAGS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync INIT_INTERLOCKED_SINGLE_LIST(&pAdapt->SendPacketQueue);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
e4ea543752422f1139923e3e506c625b0a1827c5vboxsync /* TODO: do we need it here ?? */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pAdapt->MPState.PowerState = NdisDeviceStateD3;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifdef VBOX_NETFLT_ONDEMAND_BIND
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = vboxNetFltWinConnectIt(pNetFlt);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(RT_FAILURE(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = NDIS_STATUS_FAILURE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* moved to vboxNetFltOsInitInstance */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync } while(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (Status != NDIS_STATUS_SUCCESS)
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(bCallFiniOnFail)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinPtFiniPADAPT(pAdapt);
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync LogFlow(("<== vboxNetFltWinPtInitPADAPT : pAdapt %p, Status %x\n", pAdapt, Status));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync return Status;
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * match packets
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#define NEXT_LIST_ENTRY(_Entry) ((_Entry)->Flink)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#define PREV_LIST_ENTRY(_Entry) ((_Entry)->Blink)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#define FIRST_LIST_ENTRY NEXT_LIST_ENTRY
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#define LAST_LIST_ENTRY PREV_LIST_ENTRY
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#define MIN(_a, _b) ((_a) < (_b) ? (_a) : (_b))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync#ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifdef DEBUG_misha
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsyncRTMAC g_vboxNetFltWinVerifyMACBroadcast = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncRTMAC g_vboxNetFltWinVerifyMACGuest = {0x08, 0x00, 0x27, 0x01, 0x02, 0x03};
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(PRTNETETHERHDR) vboxNetFltWinGetEthHdr(PNDIS_PACKET pPacket)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync UINT cBufCount1;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PNDIS_BUFFER pBuffer1;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync UINT uTotalPacketLength1;
e4ea543752422f1139923e3e506c625b0a1827c5vboxsync RTNETETHERHDR* pEth;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync UINT cbLength1 = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync UINT i = 0;
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisQueryPacket(pPacket, NULL, &cBufCount1, &pBuffer1, &uTotalPacketLength1);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pBuffer1);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(uTotalPacketLength1 >= ETH_HEADER_SIZE);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(uTotalPacketLength1 < ETH_HEADER_SIZE)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisQueryBufferSafe(pBuffer1, &pEth, &cbLength1, NormalPagePriority);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(cbLength1 >= ETH_HEADER_SIZE);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(cbLength1 < ETH_HEADER_SIZE)
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync return NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return pEth;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(PRTNETETHERHDR) vboxNetFltWinGetEthHdrSG(PINTNETSG pSG)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pSG->cSegsUsed);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pSG->cSegsAlloc >= pSG->cSegsUsed);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pSG->aSegs[0].cb >= ETH_HEADER_SIZE);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(!pSG->cSegsUsed)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(pSG->aSegs[0].cb < ETH_HEADER_SIZE)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return (PRTNETETHERHDR)pSG->aSegs[0].pv;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(bool) vboxNetFltWinCheckMACs(PNDIS_PACKET pPacket, PRTMAC pDst, PRTMAC pSrc)
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PRTNETETHERHDR pHdr = vboxNetFltWinGetEthHdr(pPacket);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pHdr);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync if(!pHdr)
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync return false;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(pDst && memcmp(pDst, &pHdr->DstMac, sizeof(RTMAC)))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return false;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(pSrc && memcmp(pSrc, &pHdr->SrcMac, sizeof(RTMAC)))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return false;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return true;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(bool) vboxNetFltWinCheckMACsSG(PINTNETSG pSG, PRTMAC pDst, PRTMAC pSrc)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PRTNETETHERHDR pHdr = vboxNetFltWinGetEthHdrSG(pSG);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pHdr);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(!pHdr)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return false;
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(pDst && memcmp(pDst, &pHdr->DstMac, sizeof(RTMAC)))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return false;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(pSrc && memcmp(pSrc, &pHdr->SrcMac, sizeof(RTMAC)))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return false;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return true;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# if !defined(VBOX_LOOPBACK_USEFLAGS) || defined(DEBUG_NETFLT_PACKETS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * answers whether the two given packets match based on the packet length and the first cbMatch bytes of the packets
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * if cbMatch < 0 matches complete packets.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
9c425bdea5f0991df62922b1584b805a86f2f898vboxsyncDECLHIDDEN(bool) vboxNetFltWinMatchPackets(PNDIS_PACKET pPacket1, PNDIS_PACKET pPacket2, const INT cbMatch)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync UINT cBufCount1;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PNDIS_BUFFER pBuffer1;
e4ea543752422f1139923e3e506c625b0a1827c5vboxsync UINT uTotalPacketLength1;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync uint8_t* pMemBuf1;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync UINT cbLength1 = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync UINT cBufCount2;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PNDIS_BUFFER pBuffer2;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync UINT uTotalPacketLength2;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync uint8_t* pMemBuf2;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync UINT cbLength2 = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bool bMatch = true;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifdef DEBUG_NETFLT_PACKETS
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bool bCompleteMatch = false;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisQueryPacket(pPacket1, NULL, &cBufCount1, &pBuffer1, &uTotalPacketLength1);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisQueryPacket(pPacket2, NULL, &cBufCount2, &pBuffer2, &uTotalPacketLength2);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
9c425bdea5f0991df62922b1584b805a86f2f898vboxsync Assert(pBuffer1);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pBuffer2);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(uTotalPacketLength1 != uTotalPacketLength2)
e4ea543752422f1139923e3e506c625b0a1827c5vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bMatch = false;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync UINT ucbLength2Match = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync UINT ucbMatch;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(cbMatch < 0 || (UINT)cbMatch > uTotalPacketLength1)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* NOTE: assuming uTotalPacketLength1 == uTotalPacketLength2*/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ucbMatch = uTotalPacketLength1;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifdef DEBUG_NETFLT_PACKETS
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bCompleteMatch = true;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ucbMatch = (UINT)cbMatch;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync for(;;)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(!cbLength1)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisQueryBufferSafe(pBuffer1, &pMemBuf1, &cbLength1, NormalPagePriority);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisGetNextBuffer(pBuffer1, &pBuffer1);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pMemBuf1);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(ucbLength2Match);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pMemBuf1 += ucbLength2Match;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(!cbLength2)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisQueryBufferSafe(pBuffer2, &pMemBuf2, &cbLength2, NormalPagePriority);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisGetNextBuffer(pBuffer2, &pBuffer2);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pMemBuf2);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(ucbLength2Match);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pMemBuf2 += ucbLength2Match;
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
1b7f3a92e42fb9cabf96cf31c20481da466edf76vboxsync ucbLength2Match = MIN(ucbMatch, cbLength1);
1b7f3a92e42fb9cabf96cf31c20481da466edf76vboxsync ucbLength2Match = MIN(ucbMatch, cbLength2);
1b7f3a92e42fb9cabf96cf31c20481da466edf76vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(memcmp((PVOID*)pMemBuf1, (PVOID*)pMemBuf2, ucbLength2Match))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bMatch = false;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ucbMatch -= ucbLength2Match;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(!ucbMatch)
e7074f973370e187bac5f4d3dd0cb193b4dfce62vboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync cbLength1 -= ucbLength2Match;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync cbLength2 -= ucbLength2Match;
e7074f973370e187bac5f4d3dd0cb193b4dfce62vboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
8f7bc6ad2b7bbcb4b3b96248cd2478e45f2e3b88vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifdef DEBUG_NETFLT_PACKETS
e7074f973370e187bac5f4d3dd0cb193b4dfce62vboxsync if(bMatch && !bCompleteMatch)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* check that the packets fully match */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync DBG_CHECK_PACKETS(pPacket1, pPacket2);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
4cad44a5f7cfa7db8d5fb255a1df3b3cd1687853vboxsync
d4e6f63a0c6bcae052cc381e93f0224111b19753vboxsync return bMatch;
e7074f973370e187bac5f4d3dd0cb193b4dfce62vboxsync}
4cad44a5f7cfa7db8d5fb255a1df3b3cd1687853vboxsync
8f7bc6ad2b7bbcb4b3b96248cd2478e45f2e3b88vboxsync/*
d4e6f63a0c6bcae052cc381e93f0224111b19753vboxsync * answers whether the ndis packet and PINTNETSG match based on the packet length and the first cbMatch bytes of the packet and PINTNETSG
e7074f973370e187bac5f4d3dd0cb193b4dfce62vboxsync * if cbMatch < 0 matches complete packets.
4cad44a5f7cfa7db8d5fb255a1df3b3cd1687853vboxsync */
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsyncDECLHIDDEN(bool) vboxNetFltWinMatchPacketAndSG(PNDIS_PACKET pPacket, PINTNETSG pSG, const INT cbMatch)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
585f64d6f624f9e683321dabeb21b0eb2e6aa473vboxsync UINT cBufCount1;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PNDIS_BUFFER pBuffer1;
54fe68d807196dc565de24055996e634ee40ee92vboxsync UINT uTotalPacketLength1;
54fe68d807196dc565de24055996e634ee40ee92vboxsync uint8_t* pMemBuf1;
54fe68d807196dc565de24055996e634ee40ee92vboxsync UINT cbLength1 = 0;
54fe68d807196dc565de24055996e634ee40ee92vboxsync UINT uTotalPacketLength2 = pSG->cbTotal;
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync uint8_t* pMemBuf2;
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync UINT cbLength2 = 0;
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync bool bMatch = true;
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync bool bCompleteMatch = false;
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync UINT i = 0;
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync
ec588a4ac8429a8b6c744544818b3ce3b2c75690vboxsync NdisQueryPacket(pPacket, NULL, &cBufCount1, &pBuffer1, &uTotalPacketLength1);
ec588a4ac8429a8b6c744544818b3ce3b2c75690vboxsync
ec588a4ac8429a8b6c744544818b3ce3b2c75690vboxsync Assert(pBuffer1);
ec588a4ac8429a8b6c744544818b3ce3b2c75690vboxsync Assert(pSG->cSegsUsed);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pSG->cSegsAlloc >= pSG->cSegsUsed);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(uTotalPacketLength1 != uTotalPacketLength2)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bMatch = false;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync UINT ucbLength2Match = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync UINT ucbMatch;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(cbMatch < 0 || (UINT)cbMatch > uTotalPacketLength1)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* NOTE: assuming uTotalPacketLength1 == uTotalPacketLength2*/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ucbMatch = uTotalPacketLength1;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bCompleteMatch = true;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
10e1bc06b2908a0af56d92ffdbadd25b36a5ef61vboxsync {
8f7bc6ad2b7bbcb4b3b96248cd2478e45f2e3b88vboxsync ucbMatch = (UINT)cbMatch;
5be6801527b2bb09f4b481e28d771f366961cdacvboxsync }
54fe68d807196dc565de24055996e634ee40ee92vboxsync
54fe68d807196dc565de24055996e634ee40ee92vboxsync for(;;)
54fe68d807196dc565de24055996e634ee40ee92vboxsync {
54fe68d807196dc565de24055996e634ee40ee92vboxsync if(!cbLength1)
ec588a4ac8429a8b6c744544818b3ce3b2c75690vboxsync {
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync NdisQueryBufferSafe(pBuffer1, &pMemBuf1, &cbLength1, NormalPagePriority);
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync NdisGetNextBuffer(pBuffer1, &pBuffer1);
00a5cf534a070f8b6b2b31eca62729debb3fa1d4vboxsync }
5be6801527b2bb09f4b481e28d771f366961cdacvboxsync else
5be6801527b2bb09f4b481e28d771f366961cdacvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pMemBuf1);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(ucbLength2Match);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pMemBuf1 += ucbLength2Match;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(!cbLength2)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(i < pSG->cSegsUsed);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pMemBuf2 = (uint8_t*)pSG->aSegs[i].pv;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync cbLength2 = pSG->aSegs[i].cb;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync i++;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pMemBuf2);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(ucbLength2Match);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pMemBuf2 += ucbLength2Match;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ucbLength2Match = MIN(ucbMatch, cbLength1);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ucbLength2Match = MIN(ucbMatch, cbLength2);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(memcmp((PVOID*)pMemBuf1, (PVOID*)pMemBuf2, ucbLength2Match))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bMatch = false;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ucbMatch -= ucbLength2Match;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(!ucbMatch)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync cbLength1 -= ucbLength2Match;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync cbLength2 -= ucbLength2Match;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(bMatch && !bCompleteMatch)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* check that the packets fully match */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync DBG_CHECK_PACKET_AND_SG(pPacket, pSG);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return bMatch;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# if 0
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * answers whether the two PINTNETSGs match based on the packet length and the first cbMatch bytes of the PINTNETSG
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * if cbMatch < 0 matches complete packets.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic bool vboxNetFltWinMatchSGs(PINTNETSG pSG1, PINTNETSG pSG2, const INT cbMatch)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync UINT uTotalPacketLength1 = pSG1->cbTotal;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PVOID pMemBuf1;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync UINT cbLength1 = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync UINT i1 = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync UINT uTotalPacketLength2 = pSG2->cbTotal;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PVOID pMemBuf2;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync UINT cbLength2 = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bool bMatch = true;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bool bCompleteMatch = false;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync UINT i2 = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pSG1->cSegsUsed);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pSG2->cSegsUsed);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pSG1->cSegsAlloc >= pSG1->cSegsUsed);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pSG2->cSegsAlloc >= pSG2->cSegsUsed);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
e4ea543752422f1139923e3e506c625b0a1827c5vboxsync if(uTotalPacketLength1 != uTotalPacketLength2)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bMatch = false;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync UINT ucbMatch;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(cbMatch < 0 || (UINT)cbMatch > uTotalPacketLength1)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* NOTE: assuming uTotalPacketLength1 == uTotalPacketLength2*/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ucbMatch = uTotalPacketLength1;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bCompleteMatch = true;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ucbMatch = (UINT)cbMatch;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync do
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync UINT ucbLength2Match;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(!cbLength1)
e4ea543752422f1139923e3e506c625b0a1827c5vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(i1 < pSG1->cSegsUsed);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pMemBuf1 = pSG1->aSegs[i1].pv;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync cbLength1 = pSG1->aSegs[i1].cb;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync i1++;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(!cbLength2)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(i2 < pSG2->cSegsUsed);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pMemBuf2 = pSG2->aSegs[i2].pv;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync cbLength2 = pSG2->aSegs[i2].cb;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync i2++;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ucbLength2Match = MIN(ucbMatch, cbLength1);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ucbLength2Match = MIN(ucbMatch, cbLength2);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(memcmp(pMemBuf1, pMemBuf2, ucbLength2Match))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bMatch = false;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ucbMatch -= ucbLength2Match;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync cbLength1 -= ucbLength2Match;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync cbLength2 -= ucbLength2Match;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync } while (ucbMatch);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(bMatch && !bCompleteMatch)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* check that the packets fully match */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync DBG_CHECK_SGS(pSG1, pSG2);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return bMatch;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
e4ea543752422f1139923e3e506c625b0a1827c5vboxsyncstatic void vboxNetFltWinFiniNetFltBase()
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync do
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltDeleteGlobals(&g_VBoxNetFltGlobals);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Undo the work done during start (in reverse order).
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync memset(&g_VBoxNetFltGlobals, 0, sizeof(g_VBoxNetFltGlobals));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTLogDestroy(RTLogRelSetDefaultInstance(NULL));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTLogDestroy(RTLogSetDefaultInstance(NULL));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTR0Term();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync } while (0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int vboxNetFltWinTryFiniIdc()
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinStopInitIdcProbing();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(g_bIdcInitialized)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = vboxNetFltTryDeleteIdc(&g_VBoxNetFltGlobals);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(RT_SUCCESS(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync g_bIdcInitialized = false;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = VINF_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int vboxNetFltWinFiniNetFlt()
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc = vboxNetFltWinTryFiniIdc();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(RT_SUCCESS(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinFiniNetFltBase();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * base netflt initialization
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int vboxNetFltWinInitNetFltBase()
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync do
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(!g_bIdcInitialized);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = RTR0Init(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!RT_SUCCESS(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync memset(&g_VBoxNetFltGlobals, 0, sizeof(g_VBoxNetFltGlobals));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = vboxNetFltInitGlobals(&g_VBoxNetFltGlobals);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!RT_SUCCESS(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTR0Term();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }while(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync * initialize IDC
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsyncstatic int vboxNetFltWinInitIdc()
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync int rc;
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync do
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(g_bIdcInitialized)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifdef VBOX_NETFLT_ONDEMAND_BIND
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = VINF_ALREADY_INITIALIZED;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * connect to the support driver.
e4ea543752422f1139923e3e506c625b0a1827c5vboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * This will call back vboxNetFltOsOpenSupDrv (and maybe vboxNetFltOsCloseSupDrv)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * for establishing the connect to the support driver.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = vboxNetFltInitIdc(&g_VBoxNetFltGlobals);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!RT_SUCCESS(rc))
e4ea543752422f1139923e3e506c625b0a1827c5vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync g_bIdcInitialized = true;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync } while (0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic void vboxNetFltWinInitIdcProbingWorker(PINIT_IDC_INFO pInitIdcInfo)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc = vboxNetFltWinInitIdc();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(RT_FAILURE(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync bool bInterupted = ASMAtomicUoReadBool(&pInitIdcInfo->bStop);
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync if(!bInterupted)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTThreadSleep(1000); /* 1 s */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bInterupted = ASMAtomicUoReadBool(&pInitIdcInfo->bStop);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(!bInterupted)
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync {
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync vboxNetFltWinJobEnqueueJob(&g_JobQueue, &pInitIdcInfo->Job, false);
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync return;
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* it's interupted */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = VERR_INTERRUPTED;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ASMAtomicUoWriteU32(&pInitIdcInfo->rc, rc);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync KeSetEvent(&pInitIdcInfo->hCompletionEvent, 0, FALSE);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int vboxNetFltWinStopInitIdcProbing()
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(!g_InitIdcInfo.bInitialized)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VERR_INVALID_STATE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ASMAtomicUoWriteBool(&g_InitIdcInfo.bStop, true);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync KeWaitForSingleObject(&g_InitIdcInfo.hCompletionEvent, Executive, KernelMode, FALSE, NULL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return g_InitIdcInfo.rc;
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int vboxNetFltWinStartInitIdcProbing()
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(!g_bIdcInitialized);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync KeInitializeEvent(&g_InitIdcInfo.hCompletionEvent, NotificationEvent, FALSE);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync g_InitIdcInfo.bStop = false;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync g_InitIdcInfo.bInitialized = true;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinJobInit(&g_InitIdcInfo.Job, vboxNetFltWinInitIdcProbingWorker, &g_InitIdcInfo, false);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinJobEnqueueJob(&g_JobQueue, &g_InitIdcInfo.Job, false);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VINF_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int vboxNetFltWinInitNetFlt()
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync do
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = vboxNetFltWinInitNetFltBase();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(RT_FAILURE(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
6f516ad9911d9037a18778742caa955fe362f8ffvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * connect to the support driver.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * This will call back vboxNetFltOsOpenSupDrv (and maybe vboxNetFltOsCloseSupDrv)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * for establishing the connect to the support driver.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = vboxNetFltWinInitIdc();
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync if (RT_FAILURE(rc))
fe49486f3c0fc3c327138e9a8f9ea9911d7c0d64vboxsync {
fe49486f3c0fc3c327138e9a8f9ea9911d7c0d64vboxsync Assert(0);
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync vboxNetFltWinFiniNetFltBase();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync } while (0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
6f516ad9911d9037a18778742caa955fe362f8ffvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* detach*/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int vboxNetFltWinDeleteInstance(PVBOXNETFLTINS pThis)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PADAPT pAdapt = PVBOXNETFLTINS_2_PADAPT(pThis);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_STATUS Status;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("vboxNetFltWinDeleteInstance: pThis=%p \n", pThis));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pAdapt);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pThis);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pThis->fDisconnectedFromHost);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(!pThis->fRediscoveryPending);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(!pThis->fActive);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pAdapt->PTState.OpState == kVBoxNetDevOpState_Deinitialized);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(!pAdapt->hBindingHandle);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
6f516ad9911d9037a18778742caa955fe362f8ffvboxsync Assert(pAdapt->MPState.OpState == kVBoxNetDevOpState_Deinitialized);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(!pThis->u.s.PacketQueueWorker.pSG);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// Assert(!pAdapt->hMiniportHandle);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOX_NETFLT_ONDEMAND_BIND
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = vboxNetFltWinMpDereferenceControlDevice();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(Status == NDIS_STATUS_SUCCESS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync Status = vboxNetFltWinPtFiniUnbind(pAdapt);
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync if(Status != NDIS_STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync Assert(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* pDetachInfo->Status = VERR_GENERAL_FAILURE; */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
6f516ad9911d9037a18778742caa955fe362f8ffvboxsync RTSemMutexDestroy(pThis->u.s.hAdaptMutex);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VINF_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic NDIS_STATUS vboxNetFltWinDisconnectIt(PVBOXNETFLTINS pInstance)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
6f516ad9911d9037a18778742caa955fe362f8ffvboxsync vboxNetFltWinQuFiniPacketQueue(pInstance);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return NDIS_STATUS_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* detach*/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLHIDDEN(NDIS_STATUS) vboxNetFltWinDetachFromInterface(PADAPT pAdapt, bool bOnUnbind)
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PVBOXNETFLTINS pThis = PADAPT_2_PVBOXNETFLTINS(pAdapt);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_STATUS Status;
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync int rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("vboxNetFltWinDetachFromInterface: pThis=%p\n", pThis));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
6f516ad9911d9037a18778742caa955fe362f8ffvboxsync Assert(pAdapt);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pThis);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* Assert(!pThis->fActive); */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* paranoya to ensyre the instance is not removed while we're waiting on the mutex
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * in case ndis does something unpredictable, e.g. calls our miniport halt independently
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * from protocol unbind and concurrently with it*/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltRetain(pThis, false);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = RTSemMutexRequest(pThis->u.s.hAdaptMutex, RT_INDEFINITE_WAIT);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(RT_SUCCESS(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOX_NETFLT_ONDEMAND_BIND
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(vboxNetFltWinGetAdaptState(pAdapt) == kVBoxAdaptState_Connected);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Initialized);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(vboxNetFltWinGetOpState(&pAdapt->PTState) == kVBoxNetDevOpState_Initialized);
e4ea543752422f1139923e3e506c625b0a1827c5vboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// if(
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync//#ifdef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Initialized
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync//#else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// vboxNetFltWinGetOpState(&pAdapt->PTState) == kVBoxNetDevOpState_Initialized
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync//// && vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Initialized
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync//#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// )
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(vboxNetFltWinGetAdaptState(pAdapt) == kVBoxAdaptState_Connected)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinSetAdaptState(pAdapt, kVBoxAdaptState_Disconnecting);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = vboxNetFltWinPtDoUnbinding(pAdapt, bOnUnbind);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = vboxNetFltWinMpDoDeinitialization(pAdapt);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(Status == NDIS_STATUS_SUCCESS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinSetAdaptState(pAdapt, kVBoxAdaptState_Disconnected);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitialized);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
e4ea543752422f1139923e3e506c625b0a1827c5vboxsync Assert(vboxNetFltWinGetOpState(&pAdapt->PTState) == kVBoxNetDevOpState_Deinitialized);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// /* paranoya */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync//#ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// vboxNetFltWinSetOpState(&pAdapt->PTState, kVBoxNetDevOpState_Deinitialized);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync//#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinPtFiniPADAPT(pAdapt);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* we're unbinding, make an unbind-related release */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltRelease(pThis, false);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = vboxNetFltWinPtFiniUnbind(pAdapt);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(Status != NDIS_STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* pDetachInfo->Status = VERR_GENERAL_FAILURE; */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
e4ea543752422f1139923e3e506c625b0a1827c5vboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertBreakpoint();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pAdapt->Status = NDIS_STATUS_FAILURE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(!bOnUnbind)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = NDIS_STATUS_FAILURE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTSemMutexRelease(pThis->u.s.hAdaptMutex);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertBreakpoint();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = NDIS_STATUS_FAILURE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
e4ea543752422f1139923e3e506c625b0a1827c5vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* release for the retain we made before waining on the mutex */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltRelease(pThis, false);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return Status;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Worker for vboxNetFltWinAttachToInterface.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pAttachInfo Structure for communicating with
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * vboxNetFltWinAttachToInterface.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic void vboxNetFltWinAttachToInterfaceWorker(PATTACH_INFO pAttachInfo)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PVBOXNETFLTINS pThis = pAttachInfo->pNetFltIf;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PADAPT pAdapt = PVBOXNETFLTINS_2_PADAPT(pThis);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
e4ea543752422f1139923e3e506c625b0a1827c5vboxsync Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* to ensure we're not removed while we're here */
03b30e5529d152055c46b6a3d9798bbdebb98f82vboxsync vboxNetFltRetain(pThis, false);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = RTSemMutexRequest(pThis->u.s.hAdaptMutex, RT_INDEFINITE_WAIT);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(RT_SUCCESS(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(vboxNetFltWinGetAdaptState(pAdapt) == kVBoxAdaptState_Disconnected);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitialized);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
10e1bc06b2908a0af56d92ffdbadd25b36a5ef61vboxsync Assert(vboxNetFltWinGetOpState(&pAdapt->PTState) == kVBoxNetDevOpState_Deinitialized);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// if(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitialized
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync//#ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// && vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitialized
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync//#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// )
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(vboxNetFltWinGetAdaptState(pAdapt) == kVBoxAdaptState_Disconnected)
e4ea543752422f1139923e3e506c625b0a1827c5vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOX_NETFLT_ONDEMAND_BIND
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(pAttachInfo->fRediscovery)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* rediscovery means adaptor bind is performed while intnet is already using it
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * i.e. adaptor was unbound while being used by intnet and now being bound back again */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(((VBOXNETFTLINSSTATE)ASMAtomicUoReadU32((uint32_t volatile *)&pThis->enmState)) == kVBoxNetFltInsState_Connected);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = vboxNetFltWinPtInitPADAPT(pAdapt, pAttachInfo->pCreateContext->pOurName);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = vboxNetFltWinPtInitPADAPT(pAdapt);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(Status == NDIS_STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinSetAdaptState(pAdapt, kVBoxAdaptState_Connecting);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = vboxNetFltWinPtDoBinding(pAdapt, pAttachInfo->pCreateContext->pOurName, pAttachInfo->pCreateContext->pBindToName);
8f7bc6ad2b7bbcb4b3b96248cd2478e45f2e3b88vboxsync#else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = vboxNetFltWinMpDoInitialization(pAdapt, pAttachInfo->pCreateContext->hMiniportAdapter, pAttachInfo->pCreateContext->hWrapperConfigurationContext);
8f7bc6ad2b7bbcb4b3b96248cd2478e45f2e3b88vboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (Status == NDIS_STATUS_SUCCESS)
e4ea543752422f1139923e3e506c625b0a1827c5vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(pAttachInfo->fRediscovery || (Status = vboxNetFltWinMpReferenceControlDevice()) == NDIS_STATUS_SUCCESS)
8f7bc6ad2b7bbcb4b3b96248cd2478e45f2e3b88vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
8f7bc6ad2b7bbcb4b3b96248cd2478e45f2e3b88vboxsync if(pAdapt->Status == NDIS_STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinSetAdaptState(pAdapt, kVBoxAdaptState_Connected);
8f7bc6ad2b7bbcb4b3b96248cd2478e45f2e3b88vboxsync// Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Initialized);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(vboxNetFltWinGetOpState(&pAdapt->PTState) == kVBoxNetDevOpState_Initialized);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// /* paranoya */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync//// vboxNetFltWinSetAdaptState(&pAdapt->MPState, kVBoxNetDevOpState_Initialized);
40f47bc231ff6c86a7ddc3295eed7010e889e78avboxsync//#ifndef VBOXNETADP
40f47bc231ff6c86a7ddc3295eed7010e889e78avboxsync// vboxNetFltWinSetOpState(&pAdapt->PTState, kVBoxNetDevOpState_Initialized);
40f47bc231ff6c86a7ddc3295eed7010e889e78avboxsync//#endif
40f47bc231ff6c86a7ddc3295eed7010e889e78avboxsync
40f47bc231ff6c86a7ddc3295eed7010e889e78avboxsync RTSpinlockAcquire(pThis->hSpinlock, &Tmp);
40f47bc231ff6c86a7ddc3295eed7010e889e78avboxsync
40f47bc231ff6c86a7ddc3295eed7010e889e78avboxsync /* 4. mark as connected */
40f47bc231ff6c86a7ddc3295eed7010e889e78avboxsync ASMAtomicUoWriteBool(&pThis->fDisconnectedFromHost, false);
40f47bc231ff6c86a7ddc3295eed7010e889e78avboxsync
e4ea543752422f1139923e3e506c625b0a1827c5vboxsync RTSpinlockRelease(pThis->hSpinlock, &Tmp);
40f47bc231ff6c86a7ddc3295eed7010e889e78avboxsync
40f47bc231ff6c86a7ddc3295eed7010e889e78avboxsync pAttachInfo->Status = VINF_SUCCESS;
40f47bc231ff6c86a7ddc3295eed7010e889e78avboxsync pAttachInfo->pCreateContext->Status = NDIS_STATUS_SUCCESS;
40f47bc231ff6c86a7ddc3295eed7010e889e78avboxsync
40f47bc231ff6c86a7ddc3295eed7010e889e78avboxsync RTSemMutexRelease(pThis->u.s.hAdaptMutex);
40f47bc231ff6c86a7ddc3295eed7010e889e78avboxsync
40f47bc231ff6c86a7ddc3295eed7010e889e78avboxsync vboxNetFltRelease(pThis, false);
40f47bc231ff6c86a7ddc3295eed7010e889e78avboxsync
40f47bc231ff6c86a7ddc3295eed7010e889e78avboxsync return;
40f47bc231ff6c86a7ddc3295eed7010e889e78avboxsync }
40f47bc231ff6c86a7ddc3295eed7010e889e78avboxsync AssertBreakpoint();
40f47bc231ff6c86a7ddc3295eed7010e889e78avboxsync
40f47bc231ff6c86a7ddc3295eed7010e889e78avboxsync if(!pAttachInfo->fRediscovery)
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync {
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync vboxNetFltWinMpDereferenceControlDevice();
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync }
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync }
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync AssertBreakpoint();
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync#ifndef VBOXNETADP
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync vboxNetFltWinPtDoUnbinding(pAdapt, true);
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync#else
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync vboxNetFltWinMpDoDeinitialization(pAdapt);
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync#endif
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync }
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync AssertBreakpoint();
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync vboxNetFltWinPtFiniPADAPT(pAdapt);
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync }
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync AssertBreakpoint();
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync vboxNetFltWinSetAdaptState(pAdapt, kVBoxAdaptState_Disconnected);
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitialized);
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync#ifndef VBOXNETADP
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync Assert(vboxNetFltWinGetOpState(&pAdapt->PTState) == kVBoxNetDevOpState_Deinitialized);
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync#endif
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync// /* paranoya */
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync// vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized);
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync//#ifndef VBOXNETADP
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync// vboxNetFltWinSetOpState(&pAdapt->PTState, kVBoxNetDevOpState_Deinitialized);
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync//#endif
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync }
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync AssertBreakpoint();
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync#else /* VBOX_NETFLT_ONDEMAND_BIND */
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync Status = vboxNetFltWinPtInitBind(pAdapt);
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync if (Status != NDIS_STATUS_SUCCESS)
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync {
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync pAttachInfo->Status = VERR_GENERAL_FAILURE;
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync break;
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync }
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync Status = vboxNetFltWinGetMacAddress(pAdapt, &pThis->u.s.Mac);
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync if (Status != NDIS_STATUS_SUCCESS)
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync {
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync vboxNetFltWinPtFiniUnbind(pAdapt);
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync pAttachInfo->Status = VERR_GENERAL_FAILURE;
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync break;
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync }
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync#endif /* VBOX_NETFLT_ONDEMAND_BIND */
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync pAttachInfo->Status = VERR_GENERAL_FAILURE;
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync pAttachInfo->pCreateContext->Status = Status;
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync RTSemMutexRelease(pThis->u.s.hAdaptMutex);
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync }
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync else
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync {
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync AssertBreakpoint();
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync pAttachInfo->Status = rc;
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync }
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync vboxNetFltRelease(pThis, false);
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync return;
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync}
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Common code for vboxNetFltOsInitInstance and
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * vboxNetFltOsMaybeRediscovered.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @returns IPRT status code.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pThis The instance.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param fRediscovery True if vboxNetFltOsMaybeRediscovered is calling,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * false if it's vboxNetFltOsInitInstance.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int vboxNetFltWinAttachToInterface(PVBOXNETFLTINS pThis, void * pContext, bool fRediscovery)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ATTACH_INFO Info;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Info.pNetFltIf = pThis;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Info.fRediscovery = fRediscovery;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Info.pCreateContext = (PCREATE_INSTANCE_CONTEXT)pContext;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifdef VBOX_NETFLT_ONDEMAND_BIND
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* packet queue worker thread gets created on attach interface, need to do it via job at passive level */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinJobSynchExecAtPassive((JOB_ROUTINE)vboxNetFltWinAttachToInterfaceWorker, &Info);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinAttachToInterfaceWorker(&Info);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return Info.Status;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * The OS specific interface definition
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncbool vboxNetFltOsMaybeRediscovered(PVBOXNETFLTINS pThis)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* AttachToInterface true if disconnected */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return !ASMAtomicUoReadBool(&pThis->fDisconnectedFromHost);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncint vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, PINTNETSG pSG, uint32_t fDst)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc = VINF_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync uint32_t cRefs = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PADAPT pAdapt;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#if !defined(VBOXNETADP) && !defined(VBOX_NETFLT_ONDEMAND_BIND)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(fDst & INTNETTRUNKDIR_WIRE)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync cRefs++;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
9c425bdea5f0991df62922b1584b805a86f2f898vboxsync if(fDst & INTNETTRUNKDIR_HOST)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync cRefs++;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(fDst & INTNETTRUNKDIR_WIRE || fDst & INTNETTRUNKDIR_HOST)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync cRefs = 1;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync#endif
d86aa8a95e908fa0d5e88ed662ea0a919f17756fvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertReturn(cRefs, VINF_SUCCESS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pAdapt = PVBOXNETFLTINS_2_PADAPT(pThis);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(!vboxNetFltWinIncReferenceAdapt(pAdapt, cRefs))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VERR_GENERAL_FAILURE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if ((fDst & INTNETTRUNKDIR_WIRE)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# ifdef VBOX_NETFLT_ONDEMAND_BIND
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync || (fDst & INTNETTRUNKDIR_HOST)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# endif
d86aa8a95e908fa0d5e88ed662ea0a919f17756fvboxsync )
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
9c425bdea5f0991df62922b1584b805a86f2f898vboxsync PNDIS_PACKET pPacket;
9c425bdea5f0991df62922b1584b805a86f2f898vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pPacket = vboxNetFltWinNdisPacketFromSG(pAdapt, pSG, NULL /*pBufToFree*/,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync true /*fToWire*/, true /*fCopyMemory*/);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (pPacket)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
10e1bc06b2908a0af56d92ffdbadd25b36a5ef61vboxsync NDIS_STATUS fStatus;
9c425bdea5f0991df62922b1584b805a86f2f898vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#if defined(DEBUG_NETFLT_PACKETS) || !defined(VBOX_LOOPBACK_USEFLAGS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinLbPutSendPacket(pAdapt, pPacket, true /* bFromIntNet */);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
9c425bdea5f0991df62922b1584b805a86f2f898vboxsync NdisSend(&fStatus, pAdapt->hBindingHandle, pPacket);
8f7bc6ad2b7bbcb4b3b96248cd2478e45f2e3b88vboxsync if (fStatus != NDIS_STATUS_PENDING)
8f7bc6ad2b7bbcb4b3b96248cd2478e45f2e3b88vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#if defined(DEBUG_NETFLT_PACKETS) || !defined(VBOX_LOOPBACK_USEFLAGS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* the status is NOT pending, complete the packet */
40f47bc231ff6c86a7ddc3295eed7010e889e78avboxsync bool bTmp = vboxNetFltWinLbRemoveSendPacket(pAdapt, pPacket);
40f47bc231ff6c86a7ddc3295eed7010e889e78avboxsync Assert(bTmp);
40f47bc231ff6c86a7ddc3295eed7010e889e78avboxsync#endif
40f47bc231ff6c86a7ddc3295eed7010e889e78avboxsync if(!NT_SUCCESS(fStatus))
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync {
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync /* TODO: convert status to VERR_xxx */
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync rc = VERR_GENERAL_FAILURE;
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync }
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync vboxNetFltWinFreeSGNdisPacket(pPacket, true);
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync }
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync else
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync {
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync /* pending, dereference on packet complete */
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync cRefs--;
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = VERR_NO_MEMORY;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOX_NETFLT_ONDEMAND_BIND
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (fDst & INTNETTRUNKDIR_HOST)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(cRefs)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PNDIS_PACKET pPacket = vboxNetFltWinNdisPacketFromSG(pAdapt, pSG, NULL /*pBufToFree*/,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync false /*fToWire*/, true /*fCopyMemory*/);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (pPacket)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisMIndicateReceivePacket(pAdapt->hMiniportHandle, &pPacket, 1);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync cRefs--;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifdef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync STATISTIC_INCREASE(pAdapt->cRxSuccess);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifdef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync STATISTIC_INCREASE(pAdapt->cRxError);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = VERR_NO_MEMORY;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(cRefs <= 2);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(cRefs)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinDecReferenceAdapt(pAdapt, cRefs);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncbool vboxNetFltPortOsIsPromiscuous(PVBOXNETFLTINS pThis)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
19ec3aeb41eef3f3c5fd02d2412f01811ef6fcf8vboxsync PADAPT pAdapt = PVBOXNETFLTINS_2_PADAPT(pThis);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(VBOXNETFLT_PROMISCUOUS_SUPPORTED(pAdapt))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bool bPromiscuous;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(!vboxNetFltWinReferenceAdapt(pAdapt))
8f7bc6ad2b7bbcb4b3b96248cd2478e45f2e3b88vboxsync return false;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bPromiscuous = (pAdapt->fUpperProtocolSetFilter & NDIS_PACKET_TYPE_PROMISCUOUS) == NDIS_PACKET_TYPE_PROMISCUOUS;
ec588a4ac8429a8b6c744544818b3ce3b2c75690vboxsync /*vboxNetFltWinIsPromiscuous(pAdapt);*/
ec588a4ac8429a8b6c744544818b3ce3b2c75690vboxsync
ec588a4ac8429a8b6c744544818b3ce3b2c75690vboxsync vboxNetFltWinDereferenceAdapt(pAdapt);
ec588a4ac8429a8b6c744544818b3ce3b2c75690vboxsync return bPromiscuous;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return false;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return true;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncvoid vboxNetFltPortOsGetMacAddress(PVBOXNETFLTINS pThis, PRTMAC pMac)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *pMac = pThis->u.s.Mac;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncbool vboxNetFltPortOsIsHostMac(PVBOXNETFLTINS pThis, PCRTMAC pMac)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* ASSUMES that the MAC address never changes. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return pThis->u.s.Mac.au16[0] == pMac->au16[0]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync && pThis->u.s.Mac.au16[1] == pMac->au16[1]
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync && pThis->u.s.Mac.au16[2] == pMac->au16[2];
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncvoid vboxNetFltPortOsSetActive(PVBOXNETFLTINS pThis, bool fActive)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_STATUS Status;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PADAPT pAdapt = PVBOXNETFLTINS_2_PADAPT(pThis);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* we first wait for all pending ops to complete
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * this might include all packets queued for processing */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync for(;;)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(fActive)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(!pThis->u.s.cModePassThruRefs)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(!pThis->u.s.cModeNetFltRefs)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinSleep(2);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(!vboxNetFltWinReferenceAdapt(pAdapt))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* the packets put to ReceiveQueue Array are currently not holding the references,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * simply need to flush them */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinPtFlushReceiveQueue(pAdapt, false /*fReturn*/);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(fActive)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifdef DEBUG_misha
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_PHYSICAL_MEDIUM PhMedium;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bool bPromiscSupported;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = vboxNetFltWinQueryPhysicalMedium(pAdapt, &PhMedium);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(Status != NDIS_STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync DBGPRINT(("vboxNetFltWinQueryPhysicalMedium failed, Status (0x%x), setting medium to NdisPhysicalMediumUnspecified\n", Status));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(Status == NDIS_STATUS_NOT_SUPPORTED);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(Status != NDIS_STATUS_NOT_SUPPORTED)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel(("vboxNetFltWinQueryPhysicalMedium failed, Status (0x%x), setting medium to NdisPhysicalMediumUnspecified\n", Status));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PhMedium = NdisPhysicalMediumUnspecified;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync DBGPRINT(("(SUCCESS) vboxNetFltWinQueryPhysicalMedium SUCCESS\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bPromiscSupported = (!(PhMedium == NdisPhysicalMediumWirelessWan
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync || PhMedium == NdisPhysicalMediumWirelessLan
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync || PhMedium == NdisPhysicalMediumNative802_11
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync || PhMedium == NdisPhysicalMediumBluetooth
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*|| PhMedium == NdisPhysicalMediumWiMax */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ));
afed5ab737f4aacfae3fe73776f40e989190a7cavboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(bPromiscSupported == VBOXNETFLT_PROMISCUOUS_SUPPORTED(pAdapt));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(VBOXNETFLT_PROMISCUOUS_SUPPORTED(pAdapt))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = vboxNetFltWinSetPromiscuous(pAdapt, fActive);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(Status != NDIS_STATUS_SUCCESS)
6f516ad9911d9037a18778742caa955fe362f8ffvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync DBGPRINT(("vboxNetFltWinSetPromiscuous failed, Status (0x%x), fActive (%d)\n", Status, fActive));
6f516ad9911d9037a18778742caa955fe362f8ffvboxsync Assert(0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel(("vboxNetFltWinSetPromiscuous failed, Status (0x%x), fActive (%d)\n", Status, fActive));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync#else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# ifdef VBOXNETADP_REPORT_DISCONNECTED
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(fActive)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisMIndicateStatus(pAdapt->hMiniportHandle,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_STATUS_MEDIA_CONNECT,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync (PVOID)NULL,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync 0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisMIndicateStatus(pAdapt->hMiniportHandle,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_STATUS_MEDIA_DISCONNECT,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync (PVOID)NULL,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync 0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(fActive)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* indicate status change to make the ip settings be re-picked for dhcp */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisMIndicateStatus(pAdapt->hMiniportHandle,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_STATUS_MEDIA_DISCONNECT,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync (PVOID)NULL,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync 0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NdisMIndicateStatus(pAdapt->hMiniportHandle,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_STATUS_MEDIA_CONNECT,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync (PVOID)NULL,
e4ea543752422f1139923e3e506c625b0a1827c5vboxsync 0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinDereferenceAdapt(pAdapt);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncint vboxNetFltOsDisconnectIt(PVBOXNETFLTINS pThis)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_STATUS Status = vboxNetFltWinDisconnectIt(pThis);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return Status == NDIS_STATUS_SUCCESS ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic void vboxNetFltWinConnectItWorker(PWORKER_INFO pInfo)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NDIS_STATUS Status;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PVBOXNETFLTINS pInstance = pInfo->pNetFltIf;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PADAPT pAdapt = PVBOXNETFLTINS_2_PADAPT(pInstance);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* this is not a rediscovery, initialize Mac cache */
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync if(vboxNetFltWinReferenceAdapt(pAdapt))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = vboxNetFltWinGetMacAddress(pAdapt, &pInstance->u.s.Mac);
8e8844a522f5d335f177a0313b03067d79cce201vboxsync if (Status == NDIS_STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = vboxNetFltWinQuInitPacketQueue(pInstance);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if(Status == NDIS_STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pInfo->Status = VINF_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pInfo->Status = VERR_GENERAL_FAILURE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pInfo->Status = VERR_INTNET_FLT_IF_FAILED;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinDereferenceAdapt(pAdapt);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pInfo->Status = VERR_INTNET_FLT_IF_NOT_FOUND;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int vboxNetFltWinConnectIt(PVBOXNETFLTINS pThis)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync WORKER_INFO Info;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Info.pNetFltIf = pThis;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinJobSynchExecAtPassive(vboxNetFltWinConnectItWorker, &Info);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return Info.Status;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncint vboxNetFltOsConnectIt(PVBOXNETFLTINS pThis)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return vboxNetFltWinConnectIt(pThis);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncvoid vboxNetFltOsDeleteInstance(PVBOXNETFLTINS pThis)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
1b7f3a92e42fb9cabf96cf31c20481da466edf76vboxsync vboxNetFltWinDeleteInstance(pThis);
1b7f3a92e42fb9cabf96cf31c20481da466edf76vboxsync}
1b7f3a92e42fb9cabf96cf31c20481da466edf76vboxsync
1b7f3a92e42fb9cabf96cf31c20481da466edf76vboxsyncint vboxNetFltOsInitInstance(PVBOXNETFLTINS pThis, void *pvContext)
1b7f3a92e42fb9cabf96cf31c20481da466edf76vboxsync{
1b7f3a92e42fb9cabf96cf31c20481da466edf76vboxsync int rc = RTSemMutexCreate(&pThis->u.s.hAdaptMutex);
1b7f3a92e42fb9cabf96cf31c20481da466edf76vboxsync if (RT_SUCCESS(rc))
2c18de2f539f8bbbf731bebcf0eaffbdd8da20a5vboxsync {
1b7f3a92e42fb9cabf96cf31c20481da466edf76vboxsync rc = vboxNetFltWinAttachToInterface(pThis, pvContext, false /*fRediscovery*/ );
2c18de2f539f8bbbf731bebcf0eaffbdd8da20a5vboxsync if (RT_SUCCESS(rc))
1b7f3a92e42fb9cabf96cf31c20481da466edf76vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTSemMutexDestroy(pThis->u.s.hAdaptMutex);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncint vboxNetFltOsPreInitInstance(PVBOXNETFLTINS pThis)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PADAPT pAdapt = PVBOXNETFLTINS_2_PADAPT(pThis);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pThis->u.s.cModeNetFltRefs = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pThis->u.s.cModePassThruRefs = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinSetAdaptState(pAdapt, kVBoxAdaptState_Disconnected);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef VBOXNETADP
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxNetFltWinSetOpState(&pAdapt->PTState, kVBoxNetDevOpState_Deinitialized);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VINF_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync