diff options
Diffstat (limited to 'src/VBox/HostDrivers/VBoxNetFlt')
52 files changed, 8484 insertions, 13936 deletions
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/Makefile.kmk b/src/VBox/HostDrivers/VBoxNetFlt/Makefile.kmk index 3f85bc6e1..c34e0be66 100644 --- a/src/VBox/HostDrivers/VBoxNetFlt/Makefile.kmk +++ b/src/VBox/HostDrivers/VBoxNetFlt/Makefile.kmk @@ -1,4 +1,4 @@ -# $Id: Makefile.kmk $ +# $Id: Makefile.kmk 37982 2011-07-15 14:35:40Z vboxsync $ ## @file # Sub-Makefile for the Network Filter Driver (VBoxNetFlt). # @@ -30,25 +30,25 @@ if defined(VBOX_SIGNING_MODE) && "$(KBUILD_TARGET)" == "win" VBoxNetFlt_NOINST = true endif VBoxNetFlt_DEFS = IN_RT_R0 IN_SUP_STATIC -VBoxNetFlt_SDKS.win = W2K3DDK WINPSDKINCS VBoxNetFlt_INCS = . VBoxNetFlt_SOURCES.darwin = \ darwin/VBoxNetFlt-darwin.cpp #VBoxNetFlt_SOURCES.darwin += \ # darwin/VBoxNetAdapter-darwin.cpp +VBoxNetFlt_SDKS.win = WINDDKWLH WINPSDKINCS VBoxNetFlt_SOURCES.win = \ - win/VBoxNetFlt-win.c \ - win/VBoxNetFltPt-win.c \ - win/VBoxNetFlt-win.rc -ifdef VBOX_NETFLT_ONDEMAND_BIND - VBoxNetFlt_DEFS.win += VBOX_NETFLT_ONDEMAND_BIND -else - VBoxNetFlt_DEFS.win += VBOXNETFLT_STATIC_CONFIG - VBoxNetFlt_DEFS.win += VBOXNETFLT_NO_PACKET_QUEUE - VBoxNetFlt_DEFS.win += NDIS_MINIPORT_DRIVER NDIS_WDM=1 BINARY_COMPATIBLE=0 - VBoxNetFlt_DEFS.win += NDIS50_MINIPORT=1 NDIS50=1 - VBoxNetFlt_SOURCES.win += win/VBoxNetFltMp-win.c -endif + win/drv/VBoxNetFltP-win.cpp \ + win/drv/VBoxNetFltM-win.cpp \ + win/drv/VBoxNetFltRt-win.cpp \ + win/drv/VBoxNetFlt-win.rc +# with WINDDKWLH the WIN9X_COMPAT_SPINLOCK is needed to avoid inline declaration of KeInitializeSpinLock +# otherwise the linker would complain about dumplicate _KeInitializeSpinLock@4 definition +# in ntoskrnl.lib and our object files +VBoxNetFlt_DEFS.win += WIN9X_COMPAT_SPINLOCK=1 +VBoxNetFlt_DEFS.win += VBOXNETFLT_STATIC_CONFIG +VBoxNetFlt_DEFS.win += VBOXNETFLT_NO_PACKET_QUEUE +VBoxNetFlt_DEFS.win += NDIS_MINIPORT_DRIVER NDIS_WDM=1 BINARY_COMPATIBLE=0 +VBoxNetFlt_DEFS.win += NDIS50_MINIPORT=1 NDIS50=1 ifdef VBOX_LOOPBACK_USEFLAGS VBoxNetFlt_DEFS.win += VBOX_LOOPBACK_USEFLAGS endif @@ -57,9 +57,9 @@ VBoxNetFlt_SOURCES = VBoxNetFlt.c VBoxNetFlt_LDFLAGS.win.x86 = -Entry:DriverEntry@8 VBoxNetFlt_LDFLAGS.win.amd64 = -Entry:DriverEntry VBoxNetFlt_LIBS.win = \ - $(PATH_SDK_W2K3DDK_LIB)/ntoskrnl.lib \ - $(PATH_SDK_W2K3DDK_LIB)/hal.lib \ - $(PATH_SDK_W2K3DDK_LIB)/ndis.lib \ + $(PATH_SDK_WINDDKWLH_LIB)/ntoskrnl.lib \ + $(PATH_SDK_WINDDKWLH_LIB)/hal.lib \ + $(PATH_SDK_WINDDKWLH_LIB)/ndis.lib \ $(PATH_LIB)/RuntimeR0Drv$(VBOX_SUFF_LIB) VBoxNetFlt_LIBS = \ $(PATH_LIB)/SUPR0IdcClient$(VBOX_SUFF_LIB) @@ -106,35 +106,35 @@ VBoxNetFlt-inf_INST = $(INST_BIN) VBoxNetFlt-inf_MODE = a+r,u+w VBoxNetFlt-inf_SOURCES = \ $(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFlt.inf \ - $(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFlt_m.inf + $(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFltM.inf VBoxNetFlt-inf_CLEAN = $(VBoxNetFlt-inf_SOURCES) VBoxNetFlt-inf_BLDDIRS = $(PATH_TARGET)/VBoxNetFltCat.dir -$(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFlt.inf: $(PATH_SUB_CURRENT)/win/VBoxNetFlt.inf $(MAKEFILE_CURRENT) | $$(dir $$@) +$(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFlt.inf: $(PATH_SUB_CURRENT)/win/drv/VBoxNetFlt.inf $(MAKEFILE_CURRENT) | $$(dir $$@) $(call MSG_GENERATE,VBoxNetFlt-inf,$@,$<) $(call VBOX_EDIT_INF_FN,$<,$@) -$(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFlt_m.inf: $(PATH_SUB_CURRENT)/win/VBoxNetFlt_m.inf $(MAKEFILE_CURRENT) | $$(dir $$@) +$(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFltM.inf: $(PATH_SUB_CURRENT)/win/drv/VBoxNetFltM.inf $(MAKEFILE_CURRENT) | $$(dir $$@) $(call MSG_GENERATE,VBoxNetFlt-inf,$@,$<) $(call VBOX_EDIT_INF_FN,$<,$@) ifdef VBOX_SIGNING_MODE VBoxNetFlt-inf_SOURCES += \ $(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFlt.sys \ - $(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFltNotify.dll \ + $(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFltNobj.dll \ $(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFlt.cat -$(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFlt.sys: $$(TARGET_VBoxNetFlt) | $$(dir $$@) +$(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFlt.sys: $$(VBoxNetFlt_1_TARGET) | $$(dir $$@) $(INSTALL) -m 644 $< $(@D) -$(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFltNotify.dll: $$(TARGET_VBoxNetFltNotify) | $$(dir $$@) +$(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFltNobj.dll: $$(VBoxNetFltNobj_1_TARGET) | $$(dir $$@) $(INSTALL) -m 644 $< $(@D) $(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFlt.cat: \ $(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFlt.sys \ - $(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFltNotify.dll \ + $(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFltNobj.dll \ $(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFlt.inf \ - $(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFlt_m.inf + $(PATH_TARGET)/VBoxNetFltCat.dir/VBoxNetFltM.inf $(call MSG_TOOL,Inf2Cat,VBoxNetFlt-inf,$@,$<) $(call VBOX_MAKE_CAT_FN, $(@D),$@) @@ -148,7 +148,7 @@ WinNetConfig_TEMPLATE = VBOXR3STATIC WinNetConfig_DEFS = _WIN32_WINNT=0x0501 _UNICODE UNICODE WinNetConfig_SDKS = WINPSDK W2K3DDK WinNetConfig_SOURCES = \ - win/WinNetConfig.cpp + win/cfg/VBoxNetCfg.cpp WinNetConfig_INCS.win += $(PATH_TOOL_$(VBOX_VCC_TOOL)_INC) # @@ -157,8 +157,10 @@ WinNetConfig_INCS.win += $(PATH_TOOL_$(VBOX_VCC_TOOL)_INC) PROGRAMS.win += NetFltInstall NetFltInstall_TEMPLATE = VBOXR3STATIC NetFltInstall_SDKS = WINPSDK W2K3DDK VBOX_NTDLL -NetFltInstall_SOURCES = win/NetFltInstall.cpp -NetFltInstall_LIBS = $(TARGET_WinNetConfig) \ +NetFltInstall_SOURCES = win/tools/VBoxNetFltInstall.cpp +NetFltInstall_LIBS = \ + $(WinNetConfig_1_TARGET) \ + $(VBoxDrvCfg_1_TARGET) \ $(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/comsupp.lib \ $(PATH_SDK_WINPSDK_LIB)/WbemUuid.Lib @@ -169,8 +171,10 @@ NetFltInstall_LIBS = $(TARGET_WinNetConfig) \ PROGRAMS.win += NetFltUninstall NetFltUninstall_TEMPLATE = VBOXR3STATIC NetFltUninstall_SDKS = WINPSDK W2K3DDK VBOX_NTDLL -NetFltUninstall_SOURCES = win/NetFltUninstall.cpp -NetFltUninstall_LIBS = $(TARGET_WinNetConfig) \ +NetFltUninstall_SOURCES = win/tools/VBoxNetFltUninstall.cpp +NetFltUninstall_LIBS = \ + $(WinNetConfig_1_TARGET) \ + $(VBoxDrvCfg_1_TARGET) \ $(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/comsupp.lib \ $(PATH_SDK_WINPSDK_LIB)/WbemUuid.Lib @@ -180,8 +184,10 @@ NetFltUninstall_LIBS = $(TARGET_WinNetConfig) \ PROGRAMS.win += NetAdpInstall NetAdpInstall_TEMPLATE = VBOXR3STATIC NetAdpInstall_SDKS = WINPSDK W2K3DDK VBOX_NTDLL -NetAdpInstall_SOURCES = win/NetAdpInstall.cpp -NetAdpInstall_LIBS = $(TARGET_WinNetConfig) \ +NetAdpInstall_SOURCES = win/tools/VBoxNetAdpInstall.cpp +NetAdpInstall_LIBS = \ + $(WinNetConfig_1_TARGET) \ + $(VBoxDrvCfg_1_TARGET) \ $(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/comsupp.lib \ $(PATH_SDK_WINPSDK_LIB)/WbemUuid.Lib @@ -192,53 +198,55 @@ NetAdpInstall_LIBS = $(TARGET_WinNetConfig) \ PROGRAMS.win += NetAdpUninstall NetAdpUninstall_TEMPLATE = VBOXR3STATIC NetAdpUninstall_SDKS = WINPSDK W2K3DDK VBOX_NTDLL -NetAdpUninstall_SOURCES = win/NetAdpUninstall.cpp -NetAdpUninstall_LIBS = $(TARGET_WinNetConfig) \ +NetAdpUninstall_SOURCES = win/tools/VBoxNetAdpUninstall.cpp +NetAdpUninstall_LIBS = \ + $(WinNetConfig_1_TARGET) \ + $(VBoxDrvCfg_1_TARGET) \ $(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/comsupp.lib \ $(PATH_SDK_WINPSDK_LIB)/WbemUuid.Lib # -# VBoxNetFltNotify +# VBoxNetFltNobj # -DLLS.win += VBoxNetFltNotify +DLLS.win += VBoxNetFltNobj if defined(VBOX_SIGNING_MODE) -VBoxNetFltNotify_NOINST = true +VBoxNetFltNobj_NOINST = true endif -VBoxNetFltNotify_TEMPLATE = VBOXR3STATIC -VBoxNetFltNotify_SDKS = WINPSDK W2K3DDK VBOX_NTDLL -VBoxNetFltNotify_DEFS = _WIN32_WINNT=0x0500 WIN32 _ATL_STATIC_REGISTRY -VBoxNetFltNotify_INCS = \ - $(VBoxNetFltNotify_0_OUTDIR) -VBoxNetFltNotify_SOURCES = \ - win/notifyobj/VBoxNetFltNotify.cpp \ - win/notifyobj/VBoxNetFltNotify.def \ - win/notifyobj/VBoxNetFltNotify.rc -VBoxNetFltNotify_LIBS = \ +VBoxNetFltNobj_TEMPLATE = VBOXR3STATIC +VBoxNetFltNobj_SDKS = WINPSDK W2K3DDK VBOX_NTDLL +VBoxNetFltNobj_DEFS = _WIN32_WINNT=0x0500 WIN32 _ATL_STATIC_REGISTRY +VBoxNetFltNobj_INCS = \ + $(VBoxNetFltNobj_0_OUTDIR) +VBoxNetFltNobj_SOURCES = \ + win/nobj/VBoxNetFltNobj.cpp \ + win/nobj/VBoxNetFltNobj.def \ + win/nobj/VBoxNetFltNobj.rc +VBoxNetFltNobj_LIBS = \ $(PATH_TOOL_$(VBOX_VCC_TOOL)_ATLMFC_LIB)/atls$(VBOX_VCC_CRT_TYPE).lib -#VBoxNetFltNotify_INTERMEDIATES = -VBoxNetFltNotify_DEPS = \ - $(VBoxNetFltNotify_0_OUTDIR)/VBoxNetFltNotifyn_i.c \ - $(VBoxNetFltNotify_0_OUTDIR)/VBoxNetFltNotifyn_p.c \ - $(VBoxNetFltNotify_0_OUTDIR)/VBoxNetFltNotifyn.h \ - $(VBoxNetFltNotify_0_OUTDIR)/dlldata.c \ - $(VBoxNetFltNotify_0_OUTDIR)/VBoxNetFltNotifyn.tlb -VBoxNetFltNotify_CLEAN = $(VBoxNetFltNotify_DEPS) - -VBOXNETFLT_NOTIFY_IDL ?= $(EXEC_X86_WIN32) $(call VBOX_FN_MAKE_WIN_PATH,$(firstword $(wildcard \ +#VBoxNetFltNobj_INTERMEDIATES = +VBoxNetFltNobj_DEPS = \ + $(VBoxNetFltNobj_0_OUTDIR)/VBoxNetFltNobjT_i.c \ + $(VBoxNetFltNobj_0_OUTDIR)/VBoxNetFltNobjT_p.c \ + $(VBoxNetFltNobj_0_OUTDIR)/VBoxNetFltNobjT.h \ + $(VBoxNetFltNobj_0_OUTDIR)/dlldata.c \ + $(VBoxNetFltNobj_0_OUTDIR)/VBoxNetFltNobjT.tlb +VBoxNetFltNobj_CLEAN = $(VBoxNetFltNobj_DEPS) + +VBOXNETFLT_NOBJ_IDL ?= $(EXEC_X86_WIN32) $(call VBOX_FN_MAKE_WIN_PATH,$(firstword $(wildcard \ $(PATH_SDK_WINPSDK_BIN)/Midl.Exe\ $(PATH_SDK_WINPSDK)/Bin/Midl.Exe\ $(PATH_DEVTOOLS)/win.x86/bin/midl.exe\ ) Sorry_Cannot_Find_The_Midl_Compiler_In_The_PSDK)) -$$(VBoxNetFltNotify_0_OUTDIR)/VBoxNetFltNotifyn_i.c \ -+ $$(VBoxNetFltNotify_0_OUTDIR)/VBoxNetFltNotifyn_p.c \ -+ $$(VBoxNetFltNotify_0_OUTDIR)/VBoxNetFltNotifyn.h \ -+ $$(VBoxNetFltNotify_0_OUTDIR)/dlldata.c \ -+ $$(VBoxNetFltNotify_0_OUTDIR)/VBoxNetFltNotifyn.tlb: \ - $(PATH_SUB_CURRENT)/win/notifyobj/VBoxNetFltNotifyn.idl \ +$$(VBoxNetFltNobj_0_OUTDIR)/VBoxNetFltNobjT_i.c \ ++ $$(VBoxNetFltNobj_0_OUTDIR)/VBoxNetFltNobjT_p.c \ ++ $$(VBoxNetFltNobj_0_OUTDIR)/VBoxNetFltNobjT.h \ ++ $$(VBoxNetFltNobj_0_OUTDIR)/dlldata.c \ ++ $$(VBoxNetFltNobj_0_OUTDIR)/VBoxNetFltNobjT.tlb: \ + $(PATH_SUB_CURRENT)/win/nobj/VBoxNetFltNobjT.idl \ | $$(dir $$@) - $(VBOXNETFLT_NOTIFY_IDL) /nologo \ - /out $(call VBOX_FN_MAKE_WIN_PATH,$(VBoxNetFltNotify_0_OUTDIR)) \ + $(VBOXNETFLT_NOBJ_IDL) /nologo \ + /out $(call VBOX_FN_MAKE_WIN_PATH,$(VBoxNetFltNobj_0_OUTDIR)) \ /cpp_cmd $(subst $(EXEC_X86_WIN32),,$(call VBOX_FN_MAKE_WIN_PATH,$(TOOL_$(VBOX_VCC_TOOL)_CC))) \ $(addprefix /I , $(call VBOX_FN_MAKE_WIN_PATH,$(SDK_W2K3DDK_INCS))) \ $(call VBOX_FN_MAKE_WIN_PATH,$<) @@ -253,13 +261,13 @@ VBoxNetAdp_TEMPLATE = VBOXR0DRV VBoxNetAdp_NOINST = true endif VBoxNetAdp_DEFS = IN_RT_R0 IN_SUP_STATIC -VBoxNetAdp_SDKS = W2K3DDK WINPSDKINCS VBoxNetAdp_INCS := $(PATH_SUB_CURRENT) +VBoxNetAdp_SDKS = WINDDKWLH WINPSDKINCS VBoxNetAdp_SOURCES = \ VBoxNetFlt.c \ - win/VBoxNetFlt-win.c \ - win/VBoxNetFltMp-win.c \ - win/VBoxNetFlt-win.rc + win/drv/VBoxNetFltM-win.cpp \ + win/drv/VBoxNetFltRt-win.cpp \ + win/drv/VBoxNetFlt-win.rc VBoxNetAdp_DEFS += VBOXNETFLT_STATIC_CONFIG VBOXNETADP VBoxNetAdp_DEFS.win += VBOXNETFLT_NO_PACKET_QUEUE VBoxNetAdp_DEFS += NDIS_MINIPORT_DRIVER NDIS_WDM=1 BINARY_COMPATIBLE=0 @@ -283,7 +291,7 @@ VBoxNetAdp-inf_SOURCES = \ VBoxNetAdp-inf_CLEAN = $(VBoxNetAdp-inf_SOURCES) VBoxNetAdp-inf_BLDDIRS = $(PATH_TARGET)/VBoxNetAdpCat.dir -$(PATH_TARGET)/VBoxNetAdpCat.dir/VBoxNetAdp.inf: $(PATH_SUB_CURRENT)/win/VBoxNetAdp.inf $(MAKEFILE_CURRENT) | $$(dir $$@) +$(PATH_TARGET)/VBoxNetAdpCat.dir/VBoxNetAdp.inf: $(PATH_SUB_CURRENT)/win/drv/VBoxNetAdp.inf $(MAKEFILE_CURRENT) | $$(dir $$@) $(call MSG_GENERATE,VBoxNetAdp-inf,$@,$<) $(call VBOX_EDIT_INF_FN,$<,$@) @@ -292,7 +300,7 @@ VBoxNetAdp-inf_SOURCES += \ $(PATH_TARGET)/VBoxNetAdpCat.dir/VBoxNetAdp.sys \ $(PATH_TARGET)/VBoxNetAdpCat.dir/VBoxNetAdp.cat -$(PATH_TARGET)/VBoxNetAdpCat.dir/VBoxNetAdp.sys: $$(TARGET_VBoxNetAdp) | $$(dir $$@) +$(PATH_TARGET)/VBoxNetAdpCat.dir/VBoxNetAdp.sys: $$(VBoxNetAdp_1_TARGET) | $$(dir $$@) $(INSTALL) -m 644 $< $(@D) $(PATH_TARGET)/VBoxNetAdpCat.dir/VBoxNetAdp.cat: \ @@ -322,7 +330,7 @@ vboxnetflt_INCS.linux := \ $(PATH_ROOT)/src/VBox/Runtime/r0drv/linux vboxnetflt_INCS := \ $(PATH_SUB_CURRENT) -vboxnetflt_LDFLAGS.solaris += -N drv/vboxdrv +vboxnetflt_LDFLAGS.solaris += -N drv/vboxdrv -N misc/ctf vboxnetflt_LIBS = \ $(PATH_LIB)/SUPR0IdcClient$(VBOX_SUFF_LIB) ## @todo vboxflt should resolves all the IPRT bits from vboxdrv. diff --git a/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFlt.c b/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFlt.c index bca13618b..033c12f01 100644 --- a/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFlt.c +++ b/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFlt.c @@ -1,4 +1,4 @@ -/* $Id: VBoxNetFlt.c $ */ +/* $Id: VBoxNetFlt.c 33540 2010-10-28 09:27:05Z vboxsync $ */ /** @file * VBoxNetFlt - Network Filter Driver (Host), Common Code. */ diff --git a/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h b/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h index 4eb593a37..ba7439c99 100644 --- a/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h +++ b/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h @@ -1,4 +1,4 @@ -/* $Id: VBoxNetFltInternal.h $ */ +/* $Id: VBoxNetFltInternal.h 36956 2011-05-04 12:54:03Z vboxsync $ */ /** @file * VBoxNetFlt - Network Filter Driver (Host), Internal Header. */ @@ -242,7 +242,7 @@ typedef struct VBOXNETFLTINS /** @name Windows instance data. * @{ */ /** Filter driver device context. */ - ADAPT IfAdaptor; + VBOXNETFLTWIN WinIf; volatile uint32_t cModeNetFltRefs; volatile uint32_t cModePassThruRefs; @@ -252,8 +252,8 @@ typedef struct VBOXNETFLTINS #endif /** The MAC address of the interface. Caching MAC for performance reasons. */ RTMAC MacAddr; - /** mutex used to synchronize ADAPT init/deinit */ - RTSEMMUTEX hAdaptMutex; + /** mutex used to synchronize WinIf init/deinit */ + RTSEMMUTEX hWinIfMutex; /** @} */ # else # error "PORTME" diff --git a/src/VBox/HostDrivers/VBoxNetFlt/darwin/VBoxNetFlt-darwin.cpp b/src/VBox/HostDrivers/VBoxNetFlt/darwin/VBoxNetFlt-darwin.cpp index 16c094265..fcc31dce8 100644 --- a/src/VBox/HostDrivers/VBoxNetFlt/darwin/VBoxNetFlt-darwin.cpp +++ b/src/VBox/HostDrivers/VBoxNetFlt/darwin/VBoxNetFlt-darwin.cpp @@ -1,4 +1,4 @@ -/* $Id: VBoxNetFlt-darwin.cpp $ */ +/* $Id: VBoxNetFlt-darwin.cpp 33676 2010-11-02 09:48:24Z vboxsync $ */ /** @file * VBoxNetFlt - Network Filter Driver (Host), Darwin Specific Code. */ diff --git a/src/VBox/HostDrivers/VBoxNetFlt/freebsd/Makefile b/src/VBox/HostDrivers/VBoxNetFlt/freebsd/Makefile index a6792b019..20ba2da61 100644 --- a/src/VBox/HostDrivers/VBoxNetFlt/freebsd/Makefile +++ b/src/VBox/HostDrivers/VBoxNetFlt/freebsd/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile $ +# $Id: Makefile 36385 2011-03-24 06:15:17Z vboxsync $ ## @file # Makefile for the VirtualBox FreeBSD Host Driver. # diff --git a/src/VBox/HostDrivers/VBoxNetFlt/freebsd/VBoxNetFlt-freebsd.c b/src/VBox/HostDrivers/VBoxNetFlt/freebsd/VBoxNetFlt-freebsd.c index eadb7007d..38ee00d99 100644 --- a/src/VBox/HostDrivers/VBoxNetFlt/freebsd/VBoxNetFlt-freebsd.c +++ b/src/VBox/HostDrivers/VBoxNetFlt/freebsd/VBoxNetFlt-freebsd.c @@ -1,4 +1,4 @@ -/* $Id: VBoxNetFlt-freebsd.c $ */ +/* $Id: VBoxNetFlt-freebsd.c 37423 2011-06-12 18:37:56Z vboxsync $ */ /** @file * VBoxNetFlt - Network Filter Driver (Host), FreeBSD Specific Code. */ @@ -83,27 +83,27 @@ static ng_disconnect_t ng_vboxnetflt_disconnect; static int ng_vboxnetflt_mod_event(module_t mod, int event, void *data); /** Netgraph node type */ -#define NG_VBOXNETFLT_NODE_TYPE "vboxnetflt" +#define NG_VBOXNETFLT_NODE_TYPE "vboxnetflt" /** Netgraph message cookie */ -#define NGM_VBOXNETFLT_COOKIE 0x56424f58 +#define NGM_VBOXNETFLT_COOKIE 0x56424f58 /** Input netgraph hook name */ -#define NG_VBOXNETFLT_HOOK_IN "input" +#define NG_VBOXNETFLT_HOOK_IN "input" /** Output netgraph hook name */ -#define NG_VBOXNETFLT_HOOK_OUT "output" +#define NG_VBOXNETFLT_HOOK_OUT "output" /** mbuf tag identifier */ -#define MTAG_VBOX 0x56424f58 +#define MTAG_VBOX 0x56424f58 /** mbuf packet tag */ -#define PACKET_TAG_VBOX 128 +#define PACKET_TAG_VBOX 128 #if defined(__FreeBSD_version) && __FreeBSD_version >= 800500 # include <sys/jail.h> # include <net/vnet.h> -# define VBOXCURVNET_SET(arg) CURVNET_SET_QUIET(arg) -# define VBOXCURVNET_SET_FROM_UCRED() VBOXCURVNET_SET(CRED_TO_VNET(curthread->td_ucred)) -# define VBOXCURVNET_RESTORE() CURVNET_RESTORE() +# define VBOXCURVNET_SET(arg) CURVNET_SET_QUIET(arg) +# define VBOXCURVNET_SET_FROM_UCRED() VBOXCURVNET_SET(CRED_TO_VNET(curthread->td_ucred)) +# define VBOXCURVNET_RESTORE() CURVNET_RESTORE() #else /* !defined(__FreeBSD_version) || __FreeBSD_version < 800500 */ @@ -127,16 +127,16 @@ static const struct ng_cmdlist ng_vboxnetflt_cmdlist[] = */ static struct ng_type ng_vboxnetflt_typestruct = { - .version = NG_ABI_VERSION, - .name = NG_VBOXNETFLT_NODE_TYPE, - .mod_event = vboxnetflt_modevent, - .constructor = ng_vboxnetflt_constructor, - .rcvmsg = ng_vboxnetflt_rcvmsg, - .shutdown = ng_vboxnetflt_shutdown, - .newhook = ng_vboxnetflt_newhook, - .rcvdata = ng_vboxnetflt_rcvdata, - .disconnect = ng_vboxnetflt_disconnect, - .cmdlist = ng_vboxnetflt_cmdlist, + .version = NG_ABI_VERSION, + .name = NG_VBOXNETFLT_NODE_TYPE, + .mod_event = vboxnetflt_modevent, + .constructor= ng_vboxnetflt_constructor, + .rcvmsg = ng_vboxnetflt_rcvmsg, + .shutdown = ng_vboxnetflt_shutdown, + .newhook = ng_vboxnetflt_newhook, + .rcvdata = ng_vboxnetflt_rcvdata, + .disconnect = ng_vboxnetflt_disconnect, + .cmdlist = ng_vboxnetflt_cmdlist, }; NETGRAPH_INIT(vboxnetflt, &ng_vboxnetflt_typestruct); diff --git a/src/VBox/HostDrivers/VBoxNetFlt/freebsd/files_vboxnetflt b/src/VBox/HostDrivers/VBoxNetFlt/freebsd/files_vboxnetflt index 691e18fe7..3189c4955 100755..100644 --- a/src/VBox/HostDrivers/VBoxNetFlt/freebsd/files_vboxnetflt +++ b/src/VBox/HostDrivers/VBoxNetFlt/freebsd/files_vboxnetflt @@ -1,5 +1,5 @@ #!/bin/sh -# $Id: files_vboxnetflt $ +# $Id: files_vboxnetflt 36190 2011-03-07 16:28:50Z vboxsync $ ## @file # Shared file between Makefile.kmk and export_modules # diff --git a/src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c b/src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c index 59f8ad78a..d1c7f284e 100644 --- a/src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c +++ b/src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c @@ -1,4 +1,4 @@ -/* $Id: VBoxNetFlt-linux.c $ */ +/* $Id: VBoxNetFlt-linux.c 38063 2011-07-19 09:58:08Z vboxsync $ */ /** @file * VBoxNetFlt - Network Filter Driver (Host), Linux Specific Code. */ @@ -50,8 +50,9 @@ #define VBOXNETFLT_OS_SPECFIC 1 #include "../VBoxNetFltInternal.h" +#define VBOXNETFLT_WITH_FILTER_HOST2GUEST_SKBS_EXPERIMENT #ifdef CONFIG_NET_SCHED -# define VBOXNETFLT_WITH_QDISC /* Comment this out to disable qdisc support */ +/*# define VBOXNETFLT_WITH_QDISC Comment this out to disable qdisc support */ # ifdef VBOXNETFLT_WITH_QDISC # include <net/pkt_sched.h> # endif /* VBOXNETFLT_WITH_QDISC */ @@ -93,7 +94,8 @@ # endif #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13) +#ifdef VBOXNETFLT_WITH_QDISC +# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13) static inline int qdisc_drop(struct sk_buff *skb, struct Qdisc *sch) { kfree_skb(skb); @@ -101,7 +103,8 @@ static inline int qdisc_drop(struct sk_buff *skb, struct Qdisc *sch) return NET_XMIT_DROP; } -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13) */ +# endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13) */ +#endif /* VBOXNETFLT_WITH_QDISC */ #ifndef NET_IP_ALIGN # define NET_IP_ALIGN 2 @@ -902,7 +905,10 @@ static int vboxNetFltLinuxStartXmitFilter(struct sk_buff *pSkb, struct net_devic */ if ( !VALID_PTR(pOverride) || pOverride->u32Magic != VBOXNETDEVICEOPSOVERRIDE_MAGIC - || !VALID_PTR(pOverride->pOrgOps)) +# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) + || !VALID_PTR(pOverride->pOrgOps) +# endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) */ + ) { printk("vboxNetFltLinuxStartXmitFilter: bad override %p\n", pOverride); dev_kfree_skb(pSkb); @@ -952,6 +958,9 @@ static void vboxNetFltLinuxHookDev(PVBOXNETFLTINS pThis, struct net_device *pDev PVBOXNETDEVICEOPSOVERRIDE pOverride; RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; + /* Cancel override if ethtool_ops is missing (host-only case, #5712) */ + if (!VALID_PTR(pDev->OVR_OPS)) + return; pOverride = RTMemAlloc(sizeof(*pOverride)); if (!pOverride) return; @@ -1001,7 +1010,7 @@ static void vboxNetFltLinuxUnhookDev(PVBOXNETFLTINS pThis, struct net_device *pD # if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) ASMAtomicWritePtr((void * volatile *)&pDev->hard_start_xmit, pOverride->pfnStartXmit); # endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) */ - ASMAtomicWritePtr((void * volatile *)&pDev->OVR_OPS, pOverride->pOrgOps); + ASMAtomicWritePtr((void const * volatile *)&pDev->OVR_OPS, pOverride->pOrgOps); ASMAtomicWriteU32(&pOverride->u32Magic, 0); } else diff --git a/src/VBox/HostDrivers/VBoxNetFlt/linux/files_vboxnetflt b/src/VBox/HostDrivers/VBoxNetFlt/linux/files_vboxnetflt index 8e22c249a..f27ac7b4d 100755..100644 --- a/src/VBox/HostDrivers/VBoxNetFlt/linux/files_vboxnetflt +++ b/src/VBox/HostDrivers/VBoxNetFlt/linux/files_vboxnetflt @@ -1,5 +1,5 @@ #!/bin/sh -# $Id: files_vboxnetflt $ +# $Id: files_vboxnetflt 36190 2011-03-07 16:28:50Z vboxsync $ ## @file # Shared file between Makefile.kmk and export_modules # diff --git a/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFlt-solaris.c b/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFlt-solaris.c index 301331cd3..1a4b1b6b0 100644 --- a/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFlt-solaris.c +++ b/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFlt-solaris.c @@ -1,4 +1,4 @@ -/* $Id: VBoxNetFlt-solaris.c $ */ +/* $Id: VBoxNetFlt-solaris.c 37983 2011-07-15 14:42:57Z vboxsync $ */ /** @file * VBoxNetFlt - Network Filter Driver (Host), Solaris Specific Code. */ @@ -64,6 +64,7 @@ #include <sys/ddi.h> #include <sys/sunddi.h> #include <sys/sunldi.h> +#include <sys/ctf_api.h> // Workaround for very strange define in sys/user.h // #define u (curproc->p_user) /* user is now part of proc structure */ @@ -404,6 +405,64 @@ VBOXNETFLTSTREAMTYPE volatile g_VBoxNetFltSolarisStreamType = kUndefined; static int g_VBoxNetFltSolarisPollInterval = -1; #endif +static int s_off_vnode = -1; +#define VNODE_FOR_FILE_T(filetpointer) (*(struct vnode **)((char *)(filetpointer) + s_off_vnode)) + + +static int +vboxNetFltSolarisCtfGetMemberOffset(ctf_file_t *pCtfFile, const char *pszStruct, const char *pszMember, int *pOffset) +{ + AssertReturn(pCtfFile, VERR_INVALID_PARAMETER); + AssertReturn(pszStruct, VERR_INVALID_PARAMETER); + AssertReturn(pszMember, VERR_INVALID_PARAMETER); + AssertReturn(pOffset, VERR_INVALID_PARAMETER); + + ctf_id_t TypeId = ctf_lookup_by_name(pCtfFile, pszStruct); + if (TypeId != CTF_ERR) + { + ctf_membinfo_t MemberInfo; + bzero(&MemberInfo, sizeof(MemberInfo)); + if (ctf_member_info(pCtfFile, TypeId, pszMember, &MemberInfo) != CTF_ERR) + { + *pOffset = (MemberInfo.ctm_offset >> 3); + LogRel((DEVICE_NAME ":%s::%s at %d\n", pszStruct, pszMember, *pOffset)); + return VINF_SUCCESS; + } + else + LogRel((DEVICE_NAME ":ctf_member_info failed for struct %s member %s\n", pszStruct, pszMember)); + } + else + LogRel((DEVICE_NAME ":ctf_lookup_by_name failed for struct %s\n", pszStruct)); + + return VERR_NOT_FOUND; +} + + +static int +vboxNetFltSolarisProbeCtf(void) +{ + /* + * CTF probing for fluid f_vnode member in file_t. + */ + int rc = VERR_INTERNAL_ERROR; + modctl_t *pModCtl = mod_hold_by_name("genunix"); + if (pModCtl) + { + int err; + ctf_file_t *pCtfFile = ctf_modopen(pModCtl->mod_mp, &err); + if (pCtfFile) + rc = vboxNetFltSolarisCtfGetMemberOffset(pCtfFile, "file_t", "f_vnode", &s_off_vnode); + else + LogRel((DEVICE_NAME ":ctf_modopen failed. err=%d\n", err)); + + mod_release_mod(pModCtl); + } + else + LogRel((DEVICE_NAME ":mod_hold_by_name failed.\n")); + + return rc; +} + /** * Kernel entry points @@ -427,46 +486,52 @@ int _init(void) int rc = RTR0Init(0); if (RT_SUCCESS(rc)) { - /* - * Initialize Solaris specific globals here. - */ - g_VBoxNetFltSolarisStreams = NULL; - g_VBoxNetFltSolarisInstance = NULL; - g_pVBoxNetFltSolarisCred = crdup(kcred); - if (RT_LIKELY(g_pVBoxNetFltSolarisCred)) + rc = vboxNetFltSolarisProbeCtf(); + if (RT_SUCCESS(rc)) { - rc = RTSemFastMutexCreate(&g_VBoxNetFltSolarisMtx); - if (RT_SUCCESS(rc)) + /* + * Initialize Solaris specific globals here. + */ + g_VBoxNetFltSolarisStreams = NULL; + g_VBoxNetFltSolarisInstance = NULL; + g_pVBoxNetFltSolarisCred = crdup(kcred); + if (RT_LIKELY(g_pVBoxNetFltSolarisCred)) { - /* - * Initialize the globals and connect to the support driver. - * - * This will call back vboxNetFltOsOpenSupDrv (and maybe vboxNetFltOsCloseSupDrv) - * for establishing the connect to the support driver. - */ - memset(&g_VBoxNetFltSolarisGlobals, 0, sizeof(g_VBoxNetFltSolarisGlobals)); - rc = vboxNetFltInitGlobalsAndIdc(&g_VBoxNetFltSolarisGlobals); + rc = RTSemFastMutexCreate(&g_VBoxNetFltSolarisMtx); if (RT_SUCCESS(rc)) { - rc = mod_install(&g_VBoxNetFltSolarisModLinkage); - if (!rc) - return rc; + /* + * Initialize the globals and connect to the support driver. + * + * This will call back vboxNetFltOsOpenSupDrv (and maybe vboxNetFltOsCloseSupDrv) + * for establishing the connect to the support driver. + */ + memset(&g_VBoxNetFltSolarisGlobals, 0, sizeof(g_VBoxNetFltSolarisGlobals)); + rc = vboxNetFltInitGlobalsAndIdc(&g_VBoxNetFltSolarisGlobals); + if (RT_SUCCESS(rc)) + { + rc = mod_install(&g_VBoxNetFltSolarisModLinkage); + if (!rc) + return rc; - LogRel((DEVICE_NAME ":mod_install failed. rc=%d\n", rc)); - vboxNetFltTryDeleteIdcAndGlobals(&g_VBoxNetFltSolarisGlobals); - } - else - LogRel((DEVICE_NAME ":failed to initialize globals.\n")); + LogRel((DEVICE_NAME ":mod_install failed. rc=%d\n", rc)); + vboxNetFltTryDeleteIdcAndGlobals(&g_VBoxNetFltSolarisGlobals); + } + else + LogRel((DEVICE_NAME ":failed to initialize globals.\n")); - RTSemFastMutexDestroy(g_VBoxNetFltSolarisMtx); - g_VBoxNetFltSolarisMtx = NIL_RTSEMFASTMUTEX; + RTSemFastMutexDestroy(g_VBoxNetFltSolarisMtx); + g_VBoxNetFltSolarisMtx = NIL_RTSEMFASTMUTEX; + } + } + else + { + LogRel((DEVICE_NAME ":failed to allocate credentials.\n")); + rc = VERR_NO_MEMORY; } } else - { - LogRel((DEVICE_NAME ":failed to allocate credentials.\n")); - rc = VERR_NO_MEMORY; - } + LogRel((DEVICE_NAME ":vboxNetFltSolarisProbeCtf failed. rc=%d\n", rc)); RTR0Term(); } @@ -1561,9 +1626,9 @@ static int vboxNetFltSolarisOpenDev(char *pszDev, vnode_t **ppVNode, vnode_t **p { if ( pUser && pUser->fp - && pUser->fp->f_vnode) + && VNODE_FOR_FILE_T(pUser->fp)) { - *ppVNode = pUser->fp->f_vnode; + *ppVNode = VNODE_FOR_FILE_T(pUser->fp); *ppVNodeHeld = pVNodeHeld; *ppUser = pUser; return VINF_SUCCESS; @@ -1571,7 +1636,7 @@ static int vboxNetFltSolarisOpenDev(char *pszDev, vnode_t **ppVNode, vnode_t **p else { LogRel((DEVICE_NAME ":vboxNetFltSolarisOpenDev failed. pUser=%p fp=%p f_vnode=%p\n", pUser, pUser ? pUser->fp : NULL, - pUser && pUser->fp ? pUser->fp->f_vnode : NULL)); + pUser && pUser->fp ? VNODE_FOR_FILE_T(pUser->fp) : NULL)); } if (pUser) @@ -2186,11 +2251,11 @@ static int vboxNetFltSolarisAttachIp4(PVBOXNETFLTINS pThis, bool fAttach) file_t *pArpFile = getf(ArpMuxFd); if ( pIpFile && pArpFile - && pArpFile->f_vnode - && pIpFile->f_vnode) + && VNODE_FOR_FILE_T(pArpFile) + && VNODE_FOR_FILE_T(pIpFile)) { - vnode_t *pIp4VNode = pIpFile->f_vnode; - vnode_t *pArpVNode = pArpFile->f_vnode; + vnode_t *pIp4VNode = VNODE_FOR_FILE_T(pIpFile); + vnode_t *pArpVNode = VNODE_FOR_FILE_T(pArpFile); /* * Find the position on the host stack for attaching/detaching ourselves. @@ -2430,9 +2495,9 @@ static int vboxNetFltSolarisAttachIp6(PVBOXNETFLTINS pThis, bool fAttach) */ file_t *pIpFile = getf(Ip6MuxFd); if ( pIpFile - && pIpFile->f_vnode) + && VNODE_FOR_FILE_T(pIpFile)) { - vnode_t *pIp6VNode = pIpFile->f_vnode; + vnode_t *pIp6VNode = VNODE_FOR_FILE_T(pIpFile); /* * Find the position on the host stack for attaching/detaching ourselves. diff --git a/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFltBow-solaris.c b/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFltBow-solaris.c index d5a6bc106..7e7afa433 100644 --- a/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFltBow-solaris.c +++ b/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFltBow-solaris.c @@ -1,4 +1,4 @@ -/* $Id: VBoxNetFltBow-solaris.c $ */ +/* $Id: VBoxNetFltBow-solaris.c 37766 2011-07-04 14:15:25Z vboxsync $ */ /** @file * VBoxNetFlt - Network Filter Driver (Host), Solaris Specific Code. */ @@ -53,17 +53,6 @@ #include <sys/dld.h> #include <sys/cred.h> -#if 0 -#include "include/mac_provider.h" /* dependency for other headers */ -#include "include/mac_client.h" /* for mac_* */ -#include "include/mac_client_priv.h" /* for mac_info, mac_capab_get etc. */ -#if 1 -#include "include/dls.h" /* for dls_mgmt_* */ -#include "include/dld_ioc.h" /* required by vnic.h */ -#include "include/vnic.h" /* for vnic_ioc_diag_t */ -#include "include/vnic_impl.h" /* for vnic_dev_create */ -#endif -#endif #define VBOXNETFLT_OS_SPECFIC 1 #include "../VBoxNetFltInternal.h" @@ -72,15 +61,15 @@ * Defined Constants And Macros * *******************************************************************************/ /** The module name. */ -#define DEVICE_NAME "vboxflt" +#define DEVICE_NAME "vboxbow" /** The module descriptions as seen in 'modinfo'. */ #define DEVICE_DESC_DRV "VirtualBox NetBow" /** The dynamically created VNIC name (hardcoded in NetIf-solaris.cpp). * @todo move this define into a common header. */ -#define VBOXFLT_VNIC_NAME "vboxvnic" +#define VBOXBOW_VNIC_NAME "vboxvnic" /** The VirtualBox VNIC template name (hardcoded in NetIf-solaris.cpp). * * @todo move this define into a common header. */ -#define VBOXFLT_VNIC_TEMPLATE_NAME "vboxvnic_template" +#define VBOXBOW_VNIC_TEMPLATE_NAME "vboxvnic_template" /** Debugging switch for using symbols in kmdb */ # define LOCAL static /** VBOXNETFLTVNIC::u32Magic */ @@ -392,17 +381,8 @@ LOCAL int VBoxNetFltSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd) { case DDI_ATTACH: { - int instance = ddi_get_instance(pDip); - int rc = ddi_create_priv_minor_node(pDip, DEVICE_NAME, S_IFCHR, instance, DDI_PSEUDO, 0, "none", "none", 0666); - if (rc == DDI_SUCCESS) - { - g_pVBoxNetFltSolarisDip = pDip; - ddi_report_dev(pDip); - return DDI_SUCCESS; - } - else - LogRel((DEVICE_NAME ":VBoxNetFltSolarisAttach failed to create minor node. rc=%d\n", rc)); - return DDI_FAILURE; + g_pVBoxNetFltSolarisDip = pDip; + return DDI_SUCCESS; } case DDI_RESUME: @@ -434,7 +414,6 @@ LOCAL int VBoxNetFltSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd) { case DDI_DETACH: { - ddi_remove_minor_node(pDip, NULL); return DDI_SUCCESS; } @@ -517,7 +496,6 @@ LOCAL inline mblk_t *vboxNetFltSolarisMBlkFromSG(PVBOXNETFLTINS pThis, PINTNETSG pMsg->b_wptr += pSG->aSegs[i].cb; } } - DB_TYPE(pMsg) = M_DATA; return pMsg; } @@ -990,7 +968,7 @@ LOCAL int vboxNetFltSolarisInitVNICTemplate(PVBOXNETFLTINS pThis, PVBOXNETFLTVNI */ LOCAL PVBOXNETFLTVNIC vboxNetFltSolarisAllocVNIC(void) { - PVBOXNETFLTVNIC pVNIC = RTMemAlloc(sizeof(VBOXNETFLTVNIC)); + PVBOXNETFLTVNIC pVNIC = RTMemAllocZ(sizeof(VBOXNETFLTVNIC)); if (RT_UNLIKELY(!pVNIC)) return NULL; @@ -1015,8 +993,7 @@ LOCAL PVBOXNETFLTVNIC vboxNetFltSolarisAllocVNIC(void) */ LOCAL inline void vboxNetFltSolarisFreeVNIC(PVBOXNETFLTVNIC pVNIC) { - if (pVNIC) - RTMemFree(pVNIC); + RTMemFree(pVNIC); } @@ -1028,6 +1005,8 @@ LOCAL inline void vboxNetFltSolarisFreeVNIC(PVBOXNETFLTVNIC pVNIC) */ LOCAL void vboxNetFltSolarisDestroyVNIC(PVBOXNETFLTVNIC pVNIC) { + AssertPtrReturnVoid(pVNIC); + AssertMsgReturnVoid(pVNIC->u32Magic == VBOXNETFLTVNIC_MAGIC, ("pVNIC=%p u32Magic=%#x\n", pVNIC, pVNIC->u32Magic)); if (pVNIC) { if (pVNIC->hClient) @@ -1085,7 +1064,7 @@ LOCAL int vboxNetFltSolarisCreateVNIC(PVBOXNETFLTINS pThis, PVBOXNETFLTVNIC *ppV if (RT_UNLIKELY(!pVNIC)) return VERR_NO_MEMORY; - RTStrPrintf(pVNIC->szName, sizeof(pVNIC->szName), "%s%RU64", VBOXFLT_VNIC_NAME, pThis->u.s.uInstance); + RTStrPrintf(pVNIC->szName, sizeof(pVNIC->szName), "%s%RU64", VBOXBOW_VNIC_NAME, pThis->u.s.uInstance); /* * Set a random MAC address for now. It will be changed to the VM interface's @@ -1307,7 +1286,7 @@ int vboxNetFltOsInitInstance(PVBOXNETFLTINS pThis, void *pvContext) else { pThis->u.s.fIsVNIC = true; - if (RTStrNCmp(pThis->szName, VBOXFLT_VNIC_TEMPLATE_NAME, sizeof(VBOXFLT_VNIC_TEMPLATE_NAME) - 1) == 0) + if (RTStrNCmp(pThis->szName, VBOXBOW_VNIC_TEMPLATE_NAME, sizeof(VBOXBOW_VNIC_TEMPLATE_NAME) - 1) == 0) { LogFlow((DEVICE_NAME ":vboxNetFltOsInitInstance pThis=%p VNIC template '%s' detected.\n", pThis, pThis->szName)); pThis->u.s.fIsVNICTemplate = true; @@ -1583,7 +1562,7 @@ int vboxNetFltPortOsDisconnectInterface(PVBOXNETFLTINS pThis, void *pvIfData) * Remove the VNIC from the list, destroy and free it. */ list_remove(&pThis->u.s.hVNICs, pVNIC); - LogRel((DEVICE_NAME ":vboxNetFltPortOsDisconnectInterface destroying pVNIC=%p\n", pVNIC)); + LogFlow((DEVICE_NAME ":vboxNetFltPortOsDisconnectInterface destroying pVNIC=%p\n", pVNIC)); vboxNetFltSolarisDestroyVNIC(pVNIC); vboxNetFltSolarisFreeVNIC(pVNIC); } diff --git a/src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_client.h b/src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_client.h deleted file mode 100644 index e5524214e..000000000 --- a/src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_client.h +++ /dev/null @@ -1,199 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2009-2010 Oracle Corporation. All rights reserved. - * Use is subject to license terms. - */ - -/* - * This file captures the MAC client API definitions. It can be - * included from any MAC clients. - */ - -#ifndef _SYS_MAC_CLIENT_H -#define _SYS_MAC_CLIENT_H - -#include <sys/mac.h> -#include <sys/mac_flow.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef _KERNEL - -/* - * MAC client interface. - */ - -typedef struct __mac_client_handle *mac_client_handle_t; -typedef struct __mac_unicast_handle *mac_unicast_handle_t; -typedef struct __mac_promisc_handle *mac_promisc_handle_t; -typedef struct __mac_perim_handle *mac_perim_handle_t; -typedef uintptr_t mac_tx_cookie_t; - -typedef void (*mac_tx_notify_t)(void *, mac_tx_cookie_t); - -typedef enum { - MAC_DIAG_NONE, - MAC_DIAG_MACADDR_NIC, - MAC_DIAG_MACADDR_INUSE, - MAC_DIAG_MACADDR_INVALID, - MAC_DIAG_MACADDRLEN_INVALID, - MAC_DIAG_MACFACTORYSLOTINVALID, - MAC_DIAG_MACFACTORYSLOTUSED, - MAC_DIAG_MACFACTORYSLOTALLUSED, - MAC_DIAG_MACFACTORYNOTSUP, - MAC_DIAG_MACPREFIX_INVALID, - MAC_DIAG_MACPREFIXLEN_INVALID, - MAC_DIAG_MACNO_HWRINGS -} mac_diag_t; - -typedef enum { - MAC_CLIENT_PROMISC_ALL, - MAC_CLIENT_PROMISC_FILTERED, - MAC_CLIENT_PROMISC_MULTI -} mac_client_promisc_type_t; - -/* flags passed to mac_unicast_add() */ -#define MAC_UNICAST_NODUPCHECK 0x0001 -#define MAC_UNICAST_PRIMARY 0x0002 -#define MAC_UNICAST_HW 0x0004 -#define MAC_UNICAST_VNIC_PRIMARY 0x0008 -#define MAC_UNICAST_TAG_DISABLE 0x0010 -#define MAC_UNICAST_STRIP_DISABLE 0x0020 -#define MAC_UNICAST_DISABLE_TX_VID_CHECK 0x0040 - -/* flags passed to mac_client_open */ -#define MAC_OPEN_FLAGS_IS_VNIC 0x0001 -#define MAC_OPEN_FLAGS_EXCLUSIVE 0x0002 -#define MAC_OPEN_FLAGS_IS_AGGR_PORT 0x0004 -#define MAC_OPEN_FLAGS_NO_HWRINGS 0x0008 -#define MAC_OPEN_FLAGS_SHARES_DESIRED 0x0010 -#define MAC_OPEN_FLAGS_USE_DATALINK_NAME 0x0020 -#define MAC_OPEN_FLAGS_REQ_HWRINGS 0x0040 -#define MAC_OPEN_FLAGS_MULTI_PRIMARY 0x0080 - -/* flags passed to mac_client_close */ -#define MAC_CLOSE_FLAGS_IS_VNIC 0x0001 -#define MAC_CLOSE_FLAGS_EXCLUSIVE 0x0002 -#define MAC_CLOSE_FLAGS_IS_AGGR_PORT 0x0004 - -/* flags passed to mac_promisc_add() */ -#define MAC_PROMISC_FLAGS_NO_TX_LOOP 0x0001 -#define MAC_PROMISC_FLAGS_NO_PHYS 0x0002 -#define MAC_PROMISC_FLAGS_VLAN_TAG_STRIP 0x0004 -#define MAC_PROMISC_FLAGS_NO_COPY 0x0008 - -/* flags passed to mac_tx() */ -#define MAC_DROP_ON_NO_DESC 0x01 /* freemsg() if no tx descs */ -#define MAC_TX_NO_ENQUEUE 0x02 /* don't enqueue mblks if not xmit'ed */ -#define MAC_TX_NO_HOLD 0x04 /* don't bump the active Tx count */ - -extern int mac_client_open(mac_handle_t, mac_client_handle_t *, char *, - uint16_t); -extern void mac_client_close(mac_client_handle_t, uint16_t); - -extern int mac_unicast_add(mac_client_handle_t, uint8_t *, uint16_t, - mac_unicast_handle_t *, uint16_t, mac_diag_t *); -extern int mac_unicast_add_set_rx(mac_client_handle_t, uint8_t *, uint16_t, - mac_unicast_handle_t *, uint16_t, mac_diag_t *, mac_rx_t, void *); -extern int mac_unicast_remove(mac_client_handle_t, mac_unicast_handle_t); - -extern int mac_multicast_add(mac_client_handle_t, const uint8_t *); -extern void mac_multicast_remove(mac_client_handle_t, const uint8_t *); - -extern void mac_rx_set(mac_client_handle_t, mac_rx_t, void *); -extern void mac_rx_clear(mac_client_handle_t); -extern mac_tx_cookie_t mac_tx(mac_client_handle_t, mblk_t *, - uintptr_t, uint16_t, mblk_t **); -extern boolean_t mac_tx_is_flow_blocked(mac_client_handle_t, mac_tx_cookie_t); -extern uint64_t mac_client_stat_get(mac_client_handle_t, uint_t); - -extern int mac_promisc_add(mac_client_handle_t, mac_client_promisc_type_t, - mac_rx_t, void *, mac_promisc_handle_t *, uint16_t); -extern void mac_promisc_remove(mac_promisc_handle_t); - -extern mac_notify_handle_t mac_notify_add(mac_handle_t, mac_notify_t, void *); -extern int mac_notify_remove(mac_notify_handle_t, boolean_t); -extern void mac_notify_remove_wait(mac_handle_t); -extern int mac_rename_primary(mac_handle_t, const char *); -extern char *mac_client_name(mac_client_handle_t); - -extern int mac_open(const char *, mac_handle_t *); -extern void mac_close(mac_handle_t); -extern uint64_t mac_stat_get(mac_handle_t, uint_t); - -extern int mac_unicast_primary_set(mac_handle_t, const uint8_t *); -extern void mac_unicast_primary_get(mac_handle_t, uint8_t *); -extern void mac_unicast_primary_info(mac_handle_t, char *, boolean_t *); - -extern boolean_t mac_dst_get(mac_handle_t, uint8_t *); - -extern int mac_addr_random(mac_client_handle_t, uint_t, uint8_t *, - mac_diag_t *); - -extern int mac_addr_factory_reserve(mac_client_handle_t, int *); -extern void mac_addr_factory_release(mac_client_handle_t, uint_t); -extern void mac_addr_factory_value(mac_handle_t, int, uchar_t *, uint_t *, - char *, boolean_t *); -extern uint_t mac_addr_factory_num(mac_handle_t); - -extern mac_tx_notify_handle_t mac_client_tx_notify(mac_client_handle_t, - mac_tx_notify_t, void *); - -extern int mac_set_resources(mac_handle_t, mac_resource_props_t *); -extern void mac_get_resources(mac_handle_t, mac_resource_props_t *); -extern int mac_client_set_resources(mac_client_handle_t, - mac_resource_props_t *); -extern void mac_client_get_resources(mac_client_handle_t, - mac_resource_props_t *); - -/* bridging-related interfaces */ -extern int mac_set_pvid(mac_handle_t, uint16_t); -extern uint16_t mac_get_pvid(mac_handle_t); -extern uint32_t mac_get_llimit(mac_handle_t); -extern uint32_t mac_get_ldecay(mac_handle_t); - -extern int mac_share_capable(mac_handle_t); -extern int mac_share_bind(mac_client_handle_t, uint64_t, uint64_t *); -extern void mac_share_unbind(mac_client_handle_t); - -extern int mac_set_mtu(mac_handle_t, uint_t, uint_t *); - -extern uint_t mac_hwgrp_num(mac_handle_t); -extern void mac_get_hwgrp_info(mac_handle_t, int, uint_t *, uint_t *, - uint_t *, uint_t *, char *); - -extern uint32_t mac_no_notification(mac_handle_t); -extern int mac_set_prop(mac_handle_t, mac_prop_t *, void *, uint_t); -extern int mac_get_prop(mac_handle_t, mac_prop_t *, void *, uint_t, uint_t *); - -extern boolean_t mac_is_vnic(mac_handle_t); - -#endif /* _KERNEL */ - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_MAC_CLIENT_H */ diff --git a/src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_client_priv.h b/src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_client_priv.h deleted file mode 100644 index 19ae1d057..000000000 --- a/src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_client_priv.h +++ /dev/null @@ -1,156 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2009-2010 Oracle Corporation. All rights reserved. - * Use is subject to license terms. - */ - -/* - * This file contains *private* MAC API definitions. This header file - * should only be included by kernel components which are part of the - * GLDv3 stack (dld, dls, aggr, softmac). - */ - -#ifndef _SYS_MAC_CLIENT_PRIV_H -#define _SYS_MAC_CLIENT_PRIV_H - -#include <sys/mac.h> -#include <sys/mac_flow.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef _KERNEL - -#ifdef DEBUG -#define MAC_PERIM_HELD(mph) mac_perim_held(mph) -#else -#define MAC_PERIM_HELD(mph) -#endif - -extern boolean_t mac_rx_bypass_set(mac_client_handle_t, mac_direct_rx_t, - void *); -extern void mac_rx_bypass_enable(mac_client_handle_t); -extern void mac_rx_bypass_disable(mac_client_handle_t); - -extern const mac_info_t *mac_info(mac_handle_t); -extern boolean_t mac_info_get(const char *, mac_info_t *); -extern boolean_t mac_promisc_get(mac_handle_t); - -extern int mac_start(mac_handle_t); -extern void mac_stop(mac_handle_t); - -extern void mac_ioctl(mac_handle_t, queue_t *, mblk_t *); -extern link_state_t mac_link_get(mac_handle_t); -extern void mac_resource_set(mac_client_handle_t, mac_resource_add_t, void *); -extern dev_info_t *mac_devinfo_get(mac_handle_t); -extern void *mac_driver(mac_handle_t); -extern boolean_t mac_capab_get(mac_handle_t, mac_capab_t, void *); -extern boolean_t mac_sap_verify(mac_handle_t, uint32_t, uint32_t *); -extern mblk_t *mac_header(mac_handle_t, const uint8_t *, uint32_t, mblk_t *, - size_t); -extern int mac_header_info(mac_handle_t, mblk_t *, mac_header_info_t *); -extern int mac_vlan_header_info(mac_handle_t, mblk_t *, mac_header_info_t *); -extern mblk_t *mac_header_cook(mac_handle_t, mblk_t *); -extern mblk_t *mac_header_uncook(mac_handle_t, mblk_t *); - -extern void mac_resource_set_common(mac_client_handle_t, - mac_resource_add_t, mac_resource_remove_t, mac_resource_quiesce_t, - mac_resource_restart_t, mac_resource_bind_t, void *); - -extern void mac_perim_enter_by_mh(mac_handle_t, mac_perim_handle_t *); -extern int mac_perim_enter_by_macname(const char *, mac_perim_handle_t *); -extern int mac_perim_enter_by_linkid(datalink_id_t, mac_perim_handle_t *); -extern void mac_perim_exit(mac_perim_handle_t); -extern boolean_t mac_perim_held(mac_handle_t); - -extern uint16_t mac_client_vid(mac_client_handle_t); -extern int mac_vnic_unicast_set(mac_client_handle_t, const uint8_t *); -extern boolean_t mac_client_is_vlan_vnic(mac_client_handle_t); - -extern void mac_client_poll_enable(mac_client_handle_t); -extern void mac_client_poll_disable(mac_client_handle_t); - -extern int mac_resource_ctl_set(mac_client_handle_t, mac_resource_props_t *); -extern void mac_resource_ctl_get(mac_client_handle_t, mac_resource_props_t *); - -/* - * Flow-related APIs for MAC clients. - */ - -extern void mac_link_init_flows(mac_client_handle_t); -extern void mac_link_release_flows(mac_client_handle_t); -extern int mac_link_flow_add(datalink_id_t, char *, flow_desc_t *, - mac_resource_props_t *); -extern int mac_link_flow_remove(char *); -extern int mac_link_flow_modify(char *, mac_resource_props_t *); -extern boolean_t mac_link_has_flows(mac_client_handle_t); - -typedef struct { - char fi_flow_name[MAXFLOWNAMELEN]; - datalink_id_t fi_link_id; - flow_desc_t fi_flow_desc; - mac_resource_props_t fi_resource_props; -} mac_flowinfo_t; - -extern int mac_link_flow_walk(datalink_id_t, - int (*)(mac_flowinfo_t *, void *), void *); -extern int mac_link_flow_info(char *, mac_flowinfo_t *); - -extern void *mac_tx_hold(mac_client_handle_t); -extern void mac_tx_rele(mac_client_handle_t, void *); -extern void mac_rx_client_quiesce(mac_client_handle_t); -extern void mac_rx_client_restart(mac_client_handle_t); -extern void mac_srs_perm_quiesce(mac_client_handle_t, boolean_t); -extern int mac_hwrings_get(mac_client_handle_t, mac_group_handle_t *, - mac_ring_handle_t *, mac_ring_type_t); -extern void mac_hwring_setup(mac_ring_handle_t, mac_resource_handle_t); -extern void mac_hwring_teardown(mac_ring_handle_t); -extern int mac_hwring_disable_intr(mac_ring_handle_t); -extern int mac_hwring_enable_intr(mac_ring_handle_t); -extern int mac_hwring_start(mac_ring_handle_t); -extern void mac_hwring_stop(mac_ring_handle_t); -extern mblk_t *mac_hwring_poll(mac_ring_handle_t, int); -#define MAC_HWRING_POLL(ring, bytes) \ - (((ring)->mr_info.mri_poll) \ - ((ring)->mr_info.mri_driver, (bytes))) - -extern int mac_hwgroup_addmac(mac_group_handle_t, const uint8_t *); -extern int mac_hwgroup_remmac(mac_group_handle_t, const uint8_t *); - -extern void mac_set_upper_mac(mac_client_handle_t, mac_handle_t); - -extern int mac_mark_exclusive(mac_handle_t); -extern void mac_unmark_exclusive(mac_handle_t); - -extern int32_t mac_client_intr_cpu(mac_client_handle_t); -extern void mac_client_set_intr_cpu(void *, mac_client_handle_t, int32_t); -extern void *mac_get_devinfo(mac_handle_t); - -#endif /* _KERNEL */ - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_MAC_CLIENT_PRIV_H */ diff --git a/src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_provider.h b/src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_provider.h deleted file mode 100644 index 6960f9229..000000000 --- a/src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_provider.h +++ /dev/null @@ -1,498 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2009-2010 Oracle Corporation. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_MAC_PROVIDER_H -#define _SYS_MAC_PROVIDER_H - -#include <sys/types.h> -#include <sys/ddi.h> -#include <sys/sunddi.h> -#include <sys/stream.h> -#include <sys/mkdev.h> -#include <sys/mac_flow.h> -#include <sys/mac.h> - -/* - * MAC Provider Interface - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * MAC version identifier. This is used by mac_alloc() mac_register() to - * verify that incompatible drivers don't register. - */ -#define MAC_VERSION 0x2 - -/* - * Opaque handle types - */ -typedef struct __mac_rule_handle *mac_rule_handle_t; - -/* - * Statistics - */ - -#define XCVR_UNDEFINED 0 -#define XCVR_NONE 1 -#define XCVR_10 2 -#define XCVR_100T4 3 -#define XCVR_100X 4 -#define XCVR_100T2 5 -#define XCVR_1000X 6 -#define XCVR_1000T 7 - -#ifdef _KERNEL - -/* - * Definitions for MAC Drivers Capabilities - */ -/* - * MAC layer capabilities. These capabilities are handled by the drivers' - * mc_capab_get() callbacks. Some capabilities require the driver to fill - * in a given data structure, and others are simply boolean capabilities. - * Note that capability values must be powers of 2 so that consumers and - * providers of this interface can keep track of which capabilities they - * care about by keeping a bitfield of these things around somewhere. - */ -typedef enum { - /* - * Capabilities reserved for internal use only - */ - MAC_CAPAB_VNIC = 0x0001, /* data is mac_capab_vnic_t */ - MAC_CAPAB_ANCHOR_VNIC = 0x0002, /* boolean only, no data */ - MAC_CAPAB_AGGR = 0x0004, /* data is mac_capab_aggr_t */ - MAC_CAPAB_NO_NATIVEVLAN = 0x0008, /* boolean only, no data */ - MAC_CAPAB_NO_ZCOPY = 0x0010, /* boolean only, no data */ - MAC_CAPAB_LEGACY = 0x0020, /* data is mac_capab_legacy_t */ - MAC_CAPAB_VRRP = 0x0040, /* data is mac_capab_vrrp_t */ - - /* - * Public Capabilities - */ - MAC_CAPAB_HCKSUM = 0x0100, /* data is a uint32_t */ - MAC_CAPAB_LSO = 0x0200, /* data is mac_capab_lso_t */ - MAC_CAPAB_RINGS = 0x0400, /* data is mac_capab_rings_t */ - MAC_CAPAB_MULTIFACTADDR = 0x0800, /* mac_data_multifactaddr_t */ - MAC_CAPAB_SHARES = 0x1000 /* data is mac_capab_share_t */ - - /* add new capabilities here */ -} mac_capab_t; - - -/* - * LSO capability - */ -typedef struct lso_basic_tcp_ipv4_s { - t_uscalar_t lso_max; /* maximum payload */ -} lso_basic_tcp_ipv4_t; - -/* - * Currently supported flags for LSO. - */ -#define LSO_TX_BASIC_TCP_IPV4 0x01 /* TCP LSO capability */ - -/* - * Future LSO capabilities can be added at the end of the mac_capab_lso_t. - * When such capability is added to the GLDv3 framework, the size of the - * mac_capab_lso_t it allocates and passes to the drivers increases. Older - * drivers wil access only the (upper) sections of that structure, that is the - * sections carrying the capabilities they understand. This ensures the - * interface can be safely extended in a binary compatible way. - */ -typedef struct mac_capab_lso_s { - t_uscalar_t lso_flags; - lso_basic_tcp_ipv4_t lso_basic_tcp_ipv4; - /* Add future lso capabilities here */ -} mac_capab_lso_t; - -/* - * Multiple Factory MAC Addresses Capability - */ -typedef struct mac_capab_multifactaddr_s { - /* - * Number of factory addresses - */ - uint_t mcm_naddr; - - /* - * Callbacks to query all the factory addresses. - */ - void (*mcm_getaddr)(void *, uint_t, uint8_t *); -} mac_capab_multifactaddr_t; - -/* - * Info and callbacks of legacy devices. - */ -typedef struct mac_capab_legacy_s { - /* - * Notifications that the legacy device does not support. - */ - uint32_t ml_unsup_note; - /* - * dev_t of the legacy device; can be held to force attach. - */ - dev_t ml_dev; - boolean_t (*ml_active_set)(void *); - void (*ml_active_clear)(void *); - int (*ml_fastpath_disable)(void *); - void (*ml_fastpath_enable)(void *); -} mac_capab_legacy_t; - -/* - * MAC driver entry point types. - */ -typedef int (*mac_getstat_t)(void *, uint_t, uint64_t *); -typedef int (*mac_start_t)(void *); -typedef void (*mac_stop_t)(void *); -typedef int (*mac_setpromisc_t)(void *, boolean_t); -typedef int (*mac_multicst_t)(void *, boolean_t, const uint8_t *); -typedef int (*mac_unicst_t)(void *, const uint8_t *); -typedef void (*mac_ioctl_t)(void *, queue_t *, mblk_t *); -typedef void (*mac_resources_t)(void *); -typedef mblk_t *(*mac_tx_t)(void *, mblk_t *); -typedef boolean_t (*mac_getcapab_t)(void *, mac_capab_t, void *); -typedef int (*mac_open_t)(void *); -typedef void (*mac_close_t)(void *); -typedef int (*mac_set_prop_t)(void *, const char *, mac_prop_id_t, - uint_t, const void *); -typedef int (*mac_get_prop_t)(void *, const char *, mac_prop_id_t, - uint_t, uint_t, void *, uint_t *); - -/* - * Drivers must set all of these callbacks except for mc_resources, - * mc_ioctl, and mc_getcapab, which are optional. If any of these optional - * callbacks are set, their appropriate flags must be set in mc_callbacks. - * Any future additions to this list must also be accompanied by an - * associated mc_callbacks flag so that the framework can grow without - * affecting the binary compatibility of the interface. - */ -typedef struct mac_callbacks_s { - uint_t mc_callbacks; /* Denotes which callbacks are set */ - mac_getstat_t mc_getstat; /* Get the value of a statistic */ - mac_start_t mc_start; /* Start the device */ - mac_stop_t mc_stop; /* Stop the device */ - mac_setpromisc_t mc_setpromisc; /* Enable or disable promiscuous mode */ - mac_multicst_t mc_multicst; /* Enable or disable a multicast addr */ - mac_unicst_t mc_unicst; /* Set the unicast MAC address */ - mac_tx_t mc_tx; /* Transmit a packet */ - mac_ioctl_t mc_ioctl; /* Process an unknown ioctl */ - mac_getcapab_t mc_getcapab; /* Get capability information */ - mac_open_t mc_open; /* Open the device */ - mac_close_t mc_close; /* Close the device */ - mac_set_prop_t mc_setprop; - mac_get_prop_t mc_getprop; -} mac_callbacks_t; - -typedef struct mac_priv_prop_s { - char mpp_name[MAXLINKPROPNAME]; - uint_t mpp_flags; -} mac_priv_prop_t; - -/* - * Virtualization Capabilities - */ -/* - * The ordering of entries below is important. MAC_HW_CLASSIFIER - * is the cutoff below which are entries which don't depend on - * H/W. MAC_HW_CLASSIFIER and entries after that are cases where - * H/W has been updated through add/modify/delete APIs. - */ -typedef enum { - MAC_NO_CLASSIFIER = 0, - MAC_SW_CLASSIFIER, - MAC_HW_CLASSIFIER -} mac_classify_type_t; - -typedef void (*mac_rx_func_t)(void *, mac_resource_handle_t, mblk_t *, - boolean_t); - -/* - * The virtualization level conveys the extent of the NIC hardware assistance - * for traffic steering employed for virtualization: - * - * MAC_VIRT_NONE: No assist for v12n. - * - * MAC_VIRT_LEVEL1: Multiple Rx rings with MAC address level - * classification between groups of rings. - * Requires the support of the MAC_CAPAB_RINGS - * capability. - * - * MAC_VIRT_HIO: Hybrid I/O capable MAC. Require the support - * of the MAC_CAPAB_SHARES capability. - * - * MAC_VIRT_SERIALIZE: Temporary flag *ONLY* for nxge. Mac layer - * uses this to enable mac Tx serializer on - * outbound traffic and to always enqueue - * incoming traffic on Rx soft rings in mac. - */ -#define MAC_VIRT_NONE 0x0 -#define MAC_VIRT_LEVEL1 0x1 -#define MAC_VIRT_HIO 0x2 -#define MAC_VIRT_SERIALIZE 0x4 - -typedef enum { - MAC_RING_TYPE_RX = 1, /* Receive ring */ - MAC_RING_TYPE_TX /* Transmit ring */ -} mac_ring_type_t; - -#define MAX_RINGS_PER_GROUP 128 - -/* - * Grouping type of a ring group - * - * MAC_GROUP_TYPE_STATIC: The ring group can not be re-grouped. - * MAC_GROUP_TYPE_DYNAMIC: The ring group support dynamic re-grouping - */ -typedef enum { - MAC_GROUP_TYPE_STATIC = 1, /* Static ring group */ - MAC_GROUP_TYPE_DYNAMIC /* Dynamic ring group */ -} mac_group_type_t; - -typedef struct __mac_ring_driver *mac_ring_driver_t; -typedef struct __mac_group_driver *mac_group_driver_t; - -typedef struct mac_ring_info_s mac_ring_info_t; -typedef struct mac_group_info_s mac_group_info_t; - -typedef void (*mac_get_ring_t)(void *, mac_ring_type_t, const int, const int, - mac_ring_info_t *, mac_ring_handle_t); -typedef void (*mac_get_group_t)(void *, mac_ring_type_t, const int, - mac_group_info_t *, mac_group_handle_t); - -typedef void (*mac_group_add_ring_t)(mac_group_driver_t, - mac_ring_driver_t, mac_ring_type_t); -typedef void (*mac_group_rem_ring_t)(mac_group_driver_t, - mac_ring_driver_t, mac_ring_type_t); - -/* - * Multiple Rings Capability - */ -typedef struct mac_capab_rings_s { - mac_ring_type_t mr_type; /* Ring type: Rx vs Tx */ - mac_group_type_t mr_group_type; /* Dynamic vs static grouping */ - uint_t mr_rnum; /* Number of rings */ - uint_t mr_gnum; /* Number of ring groups */ - mac_get_ring_t mr_rget; /* Get ring from driver */ - mac_get_group_t mr_gget; /* Get ring group from driver */ - mac_group_add_ring_t mr_gaddring; /* Add ring into a group */ - mac_group_rem_ring_t mr_gremring; /* Remove ring from a group */ -} mac_capab_rings_t; - -/* - * Common ring functions and driver interfaces - */ -typedef int (*mac_ring_start_t)(mac_ring_driver_t, uint64_t); -typedef void (*mac_ring_stop_t)(mac_ring_driver_t); - -typedef mblk_t *(*mac_ring_send_t)(void *, mblk_t *); -typedef mblk_t *(*mac_ring_poll_t)(void *, int); - -typedef struct mac_ring_info_s { - mac_ring_driver_t mri_driver; - mac_ring_start_t mri_start; - mac_ring_stop_t mri_stop; - mac_intr_t mri_intr; - union { - mac_ring_send_t send; - mac_ring_poll_t poll; - } mrfunion; -} mac_ring_info_s; - -#define mri_tx mrfunion.send -#define mri_poll mrfunion.poll - -typedef int (*mac_group_start_t)(mac_group_driver_t); -typedef void (*mac_group_stop_t)(mac_group_driver_t); -typedef int (*mac_add_mac_addr_t)(void *, const uint8_t *); -typedef int (*mac_rem_mac_addr_t)(void *, const uint8_t *); - -struct mac_group_info_s { - mac_group_driver_t mgi_driver; /* Driver reference */ - mac_group_start_t mgi_start; /* Start the group */ - mac_group_stop_t mgi_stop; /* Stop the group */ - uint_t mgi_count; /* Count of rings */ - mac_intr_t mgi_intr; /* Optional per-group intr */ - - /* Only used for rx groups */ - mac_add_mac_addr_t mgi_addmac; /* Add a MAC address */ - mac_rem_mac_addr_t mgi_remmac; /* Remove a MAC address */ -}; - -/* - * Share management functions. - */ -typedef uint64_t mac_share_handle_t; - -/* - * Allocate and free a share. Returns ENOSPC if all shares have been - * previously allocated. - */ -typedef int (*mac_alloc_share_t)(void *, mac_share_handle_t *); -typedef void (*mac_free_share_t)(mac_share_handle_t); - -/* - * Bind and unbind a share. Binding a share allows a domain - * to have direct access to the groups and rings associated with - * that share. - */ -typedef int (*mac_bind_share_t)(mac_share_handle_t, uint64_t, uint64_t *); -typedef void (*mac_unbind_share_t)(mac_share_handle_t); - -/* - * Return information on about a share. - */ -typedef void (*mac_share_query_t)(mac_share_handle_t, mac_ring_type_t, - mac_ring_handle_t *, uint_t *); - -/* - * Basic idea, bind previously created ring groups to shares - * for them to be exported (or shared) by another domain. - * These interfaces bind/unbind the ring group to a share. - * The groups and their rings will be shared with the guest - * as soon as the share is bound. - */ -typedef int (*mac_share_add_group_t)(mac_share_handle_t, - mac_group_driver_t); -typedef int (*mac_share_rem_group_t)(mac_share_handle_t, - mac_group_driver_t); - -typedef struct mac_capab_share_s { - uint_t ms_snum; /* Number of shares (vr's) */ - void *ms_handle; /* Handle to driver. */ - mac_alloc_share_t ms_salloc; /* Get a share from driver. */ - mac_free_share_t ms_sfree; /* Return a share to driver. */ - mac_share_add_group_t ms_sadd; /* Add a group to the share. */ - mac_share_rem_group_t ms_sremove; /* Remove group from share. */ - mac_share_query_t ms_squery; /* Query share constraints */ - mac_bind_share_t ms_sbind; /* Bind a share */ - mac_unbind_share_t ms_sunbind; /* Unbind a share */ -} mac_capab_share_t; - -typedef struct mac_capab_vrrp_s { - /* IPv6 or IPv4? */ - int mcv_af; -} mac_capab_vrrp_t; - -/* - * MAC registration interface - */ -typedef struct mac_register_s { - uint_t m_version; /* set by mac_alloc() */ - const char *m_type_ident; - void *m_driver; /* Driver private data */ - dev_info_t *m_dip; - uint_t m_instance; - uint8_t *m_src_addr; - uint8_t *m_dst_addr; - mac_callbacks_t *m_callbacks; - uint_t m_min_sdu; - uint_t m_max_sdu; - void *m_pdata; - size_t m_pdata_size; - uint32_t m_margin; - mac_priv_prop_t *m_priv_props; - size_t m_priv_prop_count; - uint32_t m_v12n; /* Virtualization level */ -} mac_register_t; - -/* - * Flags for mc_callbacks. Requiring drivers to set the flags associated - * with optional callbacks initialized in the structure allows the mac - * module to add optional callbacks in the future without requiring drivers - * to recompile. - */ -#define MC_IOCTL 0x001 -#define MC_GETCAPAB 0x002 -#define MC_OPEN 0x004 -#define MC_CLOSE 0x008 -#define MC_SETPROP 0x010 -#define MC_GETPROP 0x020 - -/* - * Driver interface functions. - */ -extern void mac_sdu_get(mac_handle_t, uint_t *, uint_t *); -extern int mac_maxsdu_update(mac_handle_t, uint_t); - -extern mac_register_t *mac_alloc(uint_t); -extern void mac_free(mac_register_t *); -extern int mac_register(mac_register_t *, mac_handle_t *); -extern int mac_disable_nowait(mac_handle_t); -extern int mac_disable(mac_handle_t); -extern int mac_unregister(mac_handle_t); -extern void mac_rx(mac_handle_t, mac_resource_handle_t, - mblk_t *); -extern void mac_rx_ring(mac_handle_t, mac_ring_handle_t, - mblk_t *, uint64_t); -extern void mac_link_update(mac_handle_t, link_state_t); -extern void mac_link_redo(mac_handle_t, link_state_t); -extern void mac_unicst_update(mac_handle_t, - const uint8_t *); -extern void mac_dst_update(mac_handle_t, const uint8_t *); -extern void mac_tx_update(mac_handle_t); -extern void mac_tx_ring_update(mac_handle_t, - mac_ring_handle_t); -extern void mac_capab_update(mac_handle_t); -extern int mac_pdata_update(mac_handle_t, void *, - size_t); -extern void mac_multicast_refresh(mac_handle_t, - mac_multicst_t, void *, boolean_t); -extern void mac_unicst_refresh(mac_handle_t, mac_unicst_t, - void *); -extern void mac_promisc_refresh(mac_handle_t, - mac_setpromisc_t, void *); -extern boolean_t mac_margin_update(mac_handle_t, uint32_t); -extern void mac_margin_get(mac_handle_t, uint32_t *); -extern int mac_margin_remove(mac_handle_t, uint32_t); -extern int mac_margin_add(mac_handle_t, uint32_t *, - boolean_t); -extern void mac_init_ops(struct dev_ops *, const char *); -extern void mac_fini_ops(struct dev_ops *); -extern int mac_devt_to_instance(dev_t); -extern minor_t mac_private_minor(void); - -extern mactype_register_t *mactype_alloc(uint_t); -extern void mactype_free(mactype_register_t *); -extern int mactype_register(mactype_register_t *); -extern int mactype_unregister(const char *); - -extern boolean_t mac_unicst_verify(mac_handle_t, - const uint8_t *, uint_t); - -extern int mac_group_add_ring(mac_group_handle_t, int); -extern void mac_group_rem_ring(mac_group_handle_t, - mac_ring_handle_t); - -#endif /* _KERNEL */ - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_MAC_PROVIDER_H */ diff --git a/src/VBox/HostDrivers/VBoxNetFlt/solaris/vboxbow.conf b/src/VBox/HostDrivers/VBoxNetFlt/solaris/vboxbow.conf new file mode 100644 index 000000000..45239ad5c --- /dev/null +++ b/src/VBox/HostDrivers/VBoxNetFlt/solaris/vboxbow.conf @@ -0,0 +1,21 @@ +# +# Solaris Host VBoxBow (Crossbow) Configuration +# +# Copyright (C) 2008-2010 Oracle Corporation +# +# This file is part of VirtualBox Open Source Edition (OSE), as +# available from http://www.virtualbox.org. This file is free software; +# you can redistribute it and/or modify it under the terms of the GNU +# General Public License (GPL) as published by the Free Software +# Foundation, in version 2 as it comes in the "COPYING" file of the +# VirtualBox OSE distribution. VirtualBox OSE is distributed in the +# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +# + +# This needs to go into /platform/i86pc/kernel/drv, +# while the 64-bit driver object goes into the amd64 +# subdirectory (32-bit drivers goes into the same +# directory). +# +name="vboxbow" parent="pseudo" instance=0; + diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltCommon-win.h b/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltCommon-win.h deleted file mode 100644 index 167318f86..000000000 --- a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltCommon-win.h +++ /dev/null @@ -1,501 +0,0 @@ -/* $Id: VBoxNetFltCommon-win.h $ */ -/** @file - * VBoxNetFltCommon.h - Network Filter Driver (Host), Windows Specific Code. Common header with commonly used defines and decls - */ - -/* - * Copyright (C) 2008 Oracle Corporation - * - * This file is part of VirtualBox Open Source Edition (OSE), as - * available from http://www.virtualbox.org. This file is free software; - * you can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) as published by the Free Software - * Foundation, in version 2 as it comes in the "COPYING" file of the - * VirtualBox OSE distribution. VirtualBox OSE is distributed in the - * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. - */ -/* - * Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample. - * Copyright (c) 1993-1999, Microsoft Corporation - */ - -#ifndef ___VBoxNetFltCommon_win_h___ -#define ___VBoxNetFltCommon_win_h___ - -//#define NTSTRSAFE_LIB - -#ifdef DEBUG -//# define DEBUG_NETFLT_PACKETS -# ifndef DEBUG_misha -# define DEBUG_NETFLT_NOASSERT -# endif -/* # define DEBUG_NETFLT_LOOPBACK */ - -/* receive logic has several branches */ -/* the DEBUG_NETFLT_RECV* macros used to debug the ProtocolReceive callback - * which is typically not used in case the underlying miniport indicates the packets with NdisMIndicateReceivePacket - * the best way to debug the ProtocolReceive (which in turn has several branches) is to enable the DEBUG_NETFLT_RECV - * one by one in the below order, i.e. - * first DEBUG_NETFLT_RECV - * then DEBUG_NETFLT_RECV + DEBUG_NETFLT_RECV_NOPACKET */ -//# define DEBUG_NETFLT_RECV -//# define DEBUG_NETFLT_RECV_NOPACKET -//# define DEBUG_NETFLT_RECV_TRANSFERDATA - -//#define DEBUG_NETFLT_USE_EXALLOC -#endif - -#define LOG_GROUP LOG_GROUP_NET_FLT_DRV - -#include <VBox/intnet.h> -#include <VBox/log.h> -#include <VBox/err.h> -#include <VBox/version.h> -#include <iprt/initterm.h> -#include <iprt/assert.h> -#include <iprt/spinlock.h> -#include <iprt/semaphore.h> -#include <iprt/process.h> -#include <iprt/alloc.h> -#include <iprt/alloca.h> -#include <iprt/time.h> -#include <iprt/net.h> - -RT_C_DECLS_BEGIN -#include <ndis.h> -RT_C_DECLS_END - - - -#define VBOXNETFLT_OS_SPECFIC 1 - -#ifdef VBOX_NETFLT_ONDEMAND_BIND -# define VBOXNETFLT_PROTOCOL_NAME L"VBoxNetFltPt" -#else -# ifndef VBOXNETADP -# define VBOXNETFLT_PROTOCOL_NAME L"VBoxNetFlt" - -/** this is to support ioctl interface */ -# define LINKNAME_STRING L"\\DosDevices\\Global\\VBoxNetFlt" -# define NTDEVICE_STRING L"\\Device\\VBoxNetFlt" -# else -# define LINKNAME_STRING L"\\DosDevices\\Global\\VBoxNetAdp" -# define NTDEVICE_STRING L"\\Device\\VBoxNetAdp" -# endif -//# define VBOXNETFLT_WIN_IOCTL_INIT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_NEITHER, FILE_WRITE_ACCESS) -//# define VBOXNETFLT_WIN_IOCTL_FINI CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_NEITHER, FILE_WRITE_ACCESS) -#endif - -/** version - * NOTE: we are NOT using NDIS 5.1 features now, the code under "#ifdef NDIS51xxx" is not tested and may not work and should be removed soon */ -#ifdef NDIS51_MINIPORT -# define VBOXNETFLT_MAJOR_NDIS_VERSION 5 -# define VBOXNETFLT_MINOR_NDIS_VERSION 1 -#else -# define VBOXNETFLT_MAJOR_NDIS_VERSION 5 -# define VBOXNETFLT_MINOR_NDIS_VERSION 0 -#endif - -#ifdef NDIS51 -# define VBOXNETFLT_PROT_MAJOR_NDIS_VERSION 5 -# define VBOXNETFLT_PROT_MINOR_NDIS_VERSION 0 -#else -# define VBOXNETFLT_PROT_MAJOR_NDIS_VERSION 5 -# define VBOXNETFLT_PROT_MINOR_NDIS_VERSION 0 -#endif - -/** advance declaration */ -typedef struct _ADAPT ADAPT, *PADAPT; - -typedef struct VBOXNETFLTINS *PVBOXNETFLTINS; - -/** configuration */ - -/** received packets queue size. the queue is used when the driver is working in a pass-thru mode */ -#define MAX_RECEIVE_PACKET_ARRAY_SIZE 40 - -/** Ndis Packet pool settings - * these are applied to both receive and send packet pools */ -#define MAX_PACKET_POOL_SIZE 0x0000FFFF -#define MIN_PACKET_POOL_SIZE 0x000000FF - -/** packet queue size used when the driver is working in the "active" mode */ -#define PACKET_INFO_POOL_SIZE 0x0000FFFF - -#ifndef VBOXNETADP -/** memory tag used for memory allocations - * (VBNF stands for VBox NetFlt) */ -# define MEM_TAG 'FNBV' -#else -/** memory tag used for memory allocations - * (VBNA stands for VBox NetAdp) */ -# define MEM_TAG 'ANBV' -#endif - -/** receive and transmit Ndis buffer pool size */ -#define TX_BUFFER_POOL_SIZE 128 -#define RX_BUFFER_POOL_SIZE 128 - -#define ETH_HEADER_SIZE 14 - -#define PACKET_QUEUE_SG_SEGS_ALLOC 32 - -#define VBOX_NETFLT_PACKET_HEADER_MATCH_SIZE 24 - -#if defined(DEBUG_NETFLT_PACKETS) || !defined(VBOX_LOOPBACK_USEFLAGS) -# define VBOXNETFLT_PACKETMATCH_LENGTH (ETH_HEADER_SIZE + 2) -#endif - -#ifdef VBOXNETADP -#define VBOXNETADP_HEADER_SIZE 14 -#define VBOXNETADP_MAX_DATA_SIZE 1500 -#define VBOXNETADP_MAX_PACKET_SIZE VBOXNETADP_HEADER_SIZE + VBOXNETADP_MAX_DATA_SIZE -#define VBOXNETADP_MIN_PACKET_SIZE 60 -#define VBOXNETADP_LINK_SPEED 1000000 //The unit of measurement is 100 bps, 100Mbps -#define VBOXNETADP_MAX_LOOKAHEAD_SIZE VBOXNETADP_MAX_DATA_SIZE -#define VBOXNETADP_VENDOR_ID 0x080027 -#define VBOXNETADP_VENDOR_DRIVER_VERSION 0x00010000 -#define VBOXNETADP_VENDOR_DESC "Sun" -#define VBOXNETADP_MAX_MCAST_LIST 32 -#define VBOXNETADP_ETH_ADDRESS_LENGTH 6 - -//#define VBOXNETADP_REPORT_DISCONNECTED -#endif -/* type defs */ - -/** Flag specifying that the type of enqueued packet - * if set the info contains the PINTNETSG packet - * if clear the packet info contains the PNDIS_PACKET packet - * Typically the packet queue we are maintaining contains PNDIS_PACKETs only, - * however in case the underlying miniport indicates a packet with the NDIS_STATUS_RESOURCES status - * we MUST return the packet back to the miniport immediately - * this is why we are creating the INTNETSG, copying the ndis packet info there and enqueueing it */ -#define PACKET_SG 0x00000001 - -/** the flag specifying that the packet source - * if set the packet comes from the host (upperlying protocol) - * if clear the packet comes from the wire (underlying miniport) */ -#define PACKET_SRC_HOST 0x00000002 - -#ifndef VBOXNETFLT_NO_PACKET_QUEUE -/** flag specifying the packet was originated by our driver - * i.e. we could use it on our needs and should not return it - * we are enqueueing "our" packets on ProtocolReceive call-back when - * Ndis does not give us a receive packet (the driver below us has called NdisM..IndicateReceive) - * this is supported for Ndis Packet only */ -#define PACKET_MINE 0x00000004 - -/** flag passed to vboxNetFltWinQuEnqueuePacket specifying that the packet should be copied - * this is supported for Ndis Packet only */ -#define PACKET_COPY 0x00000008 -#endif - -/** packet queue element containing the packet info */ -typedef struct _PACKET_INFO -{ - /** list entry used for enqueueing the info */ - LIST_ENTRY ListEntry; - /** pointer to the pool containing this packet info */ - struct _PACKET_INFO_POOL * pPool; - /** flags describing the referenced packet. Contains PACKET_xxx flags (i.e. PACKET_SG, PACKET_SRC_HOST) */ - uint32_t fFlags; - /** pointer to the packet this info represents */ - PVOID pPacket; -}PACKET_INFO, *PPACKET_INFO; - -/* paranoid check to make sure the elements in the packet info array are properly aligned */ -C_ASSERT((sizeof(PACKET_INFO) & (sizeof(PVOID) - 1)) == 0); - -/** represents the packet queue */ -typedef LIST_ENTRY PACKET_QUEUE, *PPACKET_QUEUE; - -/* - * we are using non-interlocked versions of LIST_ENTRY-related operations macros and synchronize - * access to the queue and its elements by acquiring/releasing a spinlock using Ndis[Acquire,Release]Spinlock - * - * we are NOT using interlocked versions of insert/remove head/tail list functions because we need to iterate though - * the queue elements as well as remove elements from the midle of the queue - * - * * @todo: it seems that we can switch to using interlocked versions of list-entry functions - * since we have removed all functionality (mentioned above, i.e. queue elements iteration, etc.) that might prevent us from doing this - */ -typedef struct _INTERLOCKED_PACKET_QUEUE -{ - /** queue */ - PACKET_QUEUE Queue; - /** queue lock */ - NDIS_SPIN_LOCK Lock; -}INTERLOCKED_PACKET_QUEUE, *PINTERLOCKED_PACKET_QUEUE; - -typedef struct _SINGLE_LIST -{ - /** queue */ - SINGLE_LIST_ENTRY Head; - /** pointer to the list tail. used to enqueue elements to the tail of the list */ - PSINGLE_LIST_ENTRY pTail; -} SINGLE_LIST, *PSINGLE_LIST; - -typedef struct _INTERLOCKED_SINGLE_LIST -{ - /** queue */ - SINGLE_LIST List; - /** queue lock */ - NDIS_SPIN_LOCK Lock; -} INTERLOCKED_SINGLE_LIST, *PINTERLOCKED_SINGLE_LIST; - -/** packet info pool contains free packet info elements to be used for the packet queue - * we are using the pool mechanism to allocate packet queue elements - * the pool mechanism is pretty simple now, we are allocating a bunch of memory - * for maintaining PACKET_INFO_POOL_SIZE queue elements and just returning null when the pool is exhausted - * This mechanism seems to be enough for now since we are using PACKET_INFO_POOL_SIZE = 0xffff which is - * the maximum size of packets the ndis packet pool supports */ -typedef struct _PACKET_INFO_POOL -{ - /** free packet info queue */ - INTERLOCKED_PACKET_QUEUE Queue; - /** memory bugger used by the pool */ - PVOID pBuffer; -}PACKET_INFO_POOL, *PPACKET_INFO_POOL; - -typedef enum VBOXNETDEVOPSTATE -{ - kVBoxNetDevOpState_InvalidValue = 0, - kVBoxNetDevOpState_Initializing, - kVBoxNetDevOpState_Initialized, - kVBoxNetDevOpState_Deinitializing, - kVBoxNetDevOpState_Deinitialized, - -} VBOXNETDEVOPSTATE; - -typedef enum VBOXADAPTSTATE -{ - /** The usual invalid state. */ - kVBoxAdaptState_Invalid = 0, - /** Initialization. */ - kVBoxAdaptState_Connecting, - /** Connected fuly functional state */ - kVBoxAdaptState_Connected, - /** Disconnecting */ - kVBoxAdaptState_Disconnecting, - /** Disconnected */ - kVBoxAdaptState_Disconnected, -} VBOXADAPTSTATE; - -/** structure used to maintain the state and reference count of the miniport and protocol */ -typedef struct _ADAPT_DEVICE -{ - /** initialize state */ - VBOXNETDEVOPSTATE OpState; - /** ndis power state */ - NDIS_DEVICE_POWER_STATE PowerState; - /** reference count */ - uint32_t cReferences; -/* NDIS_HANDLE hHandle; */ -} ADAPT_DEVICE, *PADAPT_DEVICE; - -/* packet filter processing mode constants */ -#define VBOXNETFLT_PFP_NETFLT 1 -#define VBOXNETFLT_PFP_PASSTHRU 2 - -/** represents filter driver device context*/ -typedef struct _ADAPT -{ -#ifndef VBOXNETADP - /** handle the lower miniport */ - NDIS_HANDLE hBindingHandle; - /** Protocol's Device state */ - ADAPT_DEVICE PTState; -#endif -#ifndef VBOX_NETFLT_ONDEMAND_BIND - /** NDIS Handle to for miniport up-calls */ - NDIS_HANDLE hMiniportHandle; - /** miniport device state */ - ADAPT_DEVICE MPState; - /** ndis packet pool used for receives */ - NDIS_HANDLE hRecvPacketPoolHandle; - /** ndis buffer pool used for receives */ - NDIS_HANDLE hRecvBufferPoolHandle; -#ifndef VBOXNETADP - /** This is used to wrap a request coming down to us. - * This exploits the fact that requests are serialized down to us.*/ - NDIS_REQUEST Request; - /** Ndis Request Bytes needed */ - PULONG BytesNeeded; - /** Ndis Request Bytes Read or Written */ - PULONG BytesReadOrWritten; -#else - volatile ULONG cTxSuccess; - volatile ULONG cRxSuccess; - volatile ULONG cTxError; - volatile ULONG cRxError; -#endif - /** driver bind adapter state. */ - VBOXADAPTSTATE enmState; -#ifndef VBOXNETADP - /** true if we should indicate the receive complete used by the ProtocolReceive mechanism. - * We need to indicate it only with the ProtocolReceive + NdisMEthIndicateReceive path. - * There is no guarantee in the docs that the ProtocolReceive & ProtocolReceiveComplete - * for one transfer are called on one same CPU, however this is how the latest passthru - * sample handles this - * Note: we're using KeGetCurrentProcessorNumber, which is not entirely correct in case - * we're running on 64bit win7+, which can handle > 64 CPUs, however since KeGetCurrentProcessorNumber - * always returns the number < than the number of CPUs in the first group, we're guaranteed to have CPU index < 64 - * @todo: use KeGetCurrentProcessorNumberEx for Win7+ 64 and dynamically extended array */ - bool abIndicateRcvComplete[64]; - - /** TRUE iff a request is pending at the miniport below */ - bool bOutstandingRequests; - /** TRUE iff a request is queued at this IM miniport*/ - bool bQueuedRequest; - /** @todo join all boolean states to one field treated as flags bitmap */ - /** true iff we are processing Set packet filter OID */ - uint8_t fProcessingPacketFilter; - /** true iff the upper protocol filter cache was initialized */ - bool bUpperProtSetFilterInitialized; - /** trus if the adapter is closing */ - bool bClosingAdapter; - /** Pending transfer data packet queue (i.e. packets that were indicated as pending on NdisTransferData call */ - INTERLOCKED_SINGLE_LIST TransferDataList; - /* mac options initialized on OID_GEN_MAC_OPTIONS */ - ULONG fMacOptions; - /** For initializing the miniport edge */ - NDIS_STRING DeviceName; - /** For blocking UnbindAdapter while an IM Init is in progress.*/ - NDIS_EVENT MiniportInitEvent; - /** The last indicated media status */ - NDIS_STATUS LastIndicatedStatus; - /** The latest suppressed media status */ - NDIS_STATUS LatestUnIndicateStatus; - /** when working in the passthru mode the driver puts the received packets to this array - * instead of passing them up immediately - * we are flushing the packets on ProtocolReceiveComplete or when the underlying miniport - * indicates NDIS_STATUS_RESOURCES or when this array is full */ - PNDIS_PACKET aReceivedPackets[MAX_RECEIVE_PACKET_ARRAY_SIZE]; - /** number of packets in the aReceivedPackets array*/ - ULONG cReceivedPacketCount; - /** packet filter flags set by the upper protocols */ - ULONG fUpperProtocolSetFilter; - /** packet filter flags set by the upper protocols */ - ULONG fSetFilterBuffer; - /** packet filter flags set by us */ - ULONG fOurSetFilter; -#endif /* !VBOXNETADP */ -#endif /* !VBOX_NETFLT_ONDEMAND_BIND */ - -#ifndef VBOXNETADP -#if defined(DEBUG_NETFLT_LOOPBACK) || !defined(VBOX_LOOPBACK_USEFLAGS) - /** used for maintaining the pending send packets for handling packet loopback */ - INTERLOCKED_SINGLE_LIST SendPacketQueue; -#endif - /** used for serializing calls to the NdisRequest in the vboxNetFltWinSynchNdisRequest */ - RTSEMFASTMUTEX hSynchRequestMutex; - /** event used to synchronize with the Ndis Request completion in the vboxNetFltWinSynchNdisRequest */ - KEVENT hSynchCompletionEvent; - /** status of the Ndis Request initiated by the vboxNetFltWinSynchNdisRequest */ - NDIS_STATUS volatile fSynchCompletionStatus; - /** pointer to the Ndis Request being executed by the vboxNetFltWinSynchNdisRequest */ - PNDIS_REQUEST volatile pSynchRequest; - /** ndis packet pool used for sends */ - NDIS_HANDLE hSendPacketPoolHandle; - /** ndis buffer pool used for sends */ - NDIS_HANDLE hSendBufferPoolHandle; - /** open/close adapter status. - * Since ndis adapter open and close requests may complete asynchronously, - * we are using event mechanism to wait for open/close completion - * the status field is being set by the completion call-back */ - NDIS_STATUS Status; - /** open/close adaptor completion event */ - NDIS_EVENT hEvent; - /** medium we are attached to */ - NDIS_MEDIUM Medium; -// /** physical medium we are attached to */ -// NDIS_PHYSICAL_MEDIUM PhMedium; - /** True - When the miniport or protocol is transitioning from a D0 to Standby (>D0) State - * False - At all other times, - Flag is cleared after a transition to D0 */ - BOOLEAN bStandingBy; -#endif -} ADAPT, *PADAPT; - -typedef struct _PACKET_QUEUE_WORKER -{ - /** this event is used to initiate a packet queue worker thread kill */ - KEVENT KillEvent; - /** this event is used to notify a worker thread that the packets are added to the queue */ - KEVENT NotifyEvent; - /** pointer to the packet queue worker thread object */ - PKTHREAD pThread; - /** pointer to the SG used by the packet queue for IntNet receive notifications */ - PINTNETSG pSG; - /** Packet queue */ - INTERLOCKED_PACKET_QUEUE PacketQueue; - /** Packet info pool, i.e. the pool for the packet queue elements */ - PACKET_INFO_POOL PacketInfoPool; -} PACKET_QUEUE_WORKER, *PPACKET_QUEUE_WORKER; - -/** Protocol reserved part of a sent packet that is allocated by us. */ -typedef struct _SEND_RSVD -{ - /** original packet receiver from the upperlying protocol - * can be null if the packet was originated by intnet */ - PNDIS_PACKET pOriginalPkt; - /** pointer to the buffer to be freed on send completion - * can be null if no buffer is to be freed */ - PVOID pBufToFree; -#if !defined(VBOX_LOOPBACK_USEFLAGS) || defined(DEBUG_NETFLT_PACKETS) - SINGLE_LIST_ENTRY ListEntry; - /* true if the packet is from IntNet */ - bool bFromIntNet; -#endif -} SEND_RSVD, *PSEND_RSVD; - -/** represents the data stored in the protocol reserved field of ndis packet on NdisTransferData processing*/ -typedef struct _TRANSFERDATA_RSVD -{ - /** next packet in a list */ - SINGLE_LIST_ENTRY ListEntry; - /* packet buffer start */ - PNDIS_BUFFER pOriginalBuffer; -} TRANSFERDATA_RSVD, *PTRANSFERDATA_RSVD; - -/** Miniport reserved part of a received packet that is allocated by - * us. Note that this should fit into the MiniportReserved space - * in an NDIS_PACKET. */ -typedef struct _RECV_RSVD -{ - /** original packet receiver from the underling miniport - * can be null if the packet was originated by intnet */ - PNDIS_PACKET pOriginalPkt; - /** pointer to the buffer to be freed on receive completion - * can be null if no buffer is to be freed */ - PVOID pBufToFree; -} RECV_RSVD, *PRECV_RSVD; - -#ifndef VBOX_NETFLT_ONDEMAND_BIND - -C_ASSERT(sizeof(RECV_RSVD) <= sizeof(((PNDIS_PACKET)0)->MiniportReserved)); -C_ASSERT(sizeof(TRANSFERDATA_RSVD) <= PROTOCOL_RESERVED_SIZE_IN_PACKET); -#endif - -C_ASSERT(sizeof(NDIS_DEVICE_POWER_STATE) == sizeof(uint32_t)); -C_ASSERT(sizeof(UINT) == sizeof(uint32_t)); - -#define NDIS_FLAGS_SKIP_LOOPBACK_W2K 0x400 - -#include "../VBoxNetFltInternal.h" -#include "VBoxNetFlt-win.h" -#ifndef VBOXNETADP -#include "VBoxNetFltPt-win.h" -#endif -#ifndef VBOX_NETFLT_ONDEMAND_BIND -# include "VBoxNetFltMp-win.h" -#endif - -#ifdef DEBUG_NETFLT_NOASSERT -# ifdef Assert -# undef Assert -# endif - -# define Assert(_expr) do {} while (0) -#endif /* #ifdef DEBUG_NETFLT_NOASSERT */ - -#endif diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltMp-win.c b/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltMp-win.c deleted file mode 100644 index ec9f3f754..000000000 --- a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltMp-win.c +++ /dev/null @@ -1,2807 +0,0 @@ -/* $Id: VBoxNetFltMp-win.c $ */ -/** @file - * VBoxNetFlt - Network Filter Driver (Host), Windows Specific Code. Miniport edge of ndis filter driver - */ - -/* - * Copyright (C) 2008 Oracle Corporation - * - * This file is part of VirtualBox Open Source Edition (OSE), as - * available from http://www.virtualbox.org. This file is free software; - * you can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) as published by the Free Software - * Foundation, in version 2 as it comes in the "COPYING" file of the - * VirtualBox OSE distribution. VirtualBox OSE is distributed in the - * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. - */ -/* - * Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample. - * Copyright (c) 1993-1999, Microsoft Corporation - */ - -#include "VBoxNetFltCommon-win.h" - -#ifdef VBOX_NETFLT_ONDEMAND_BIND -# error "unsupported (VBOX_NETFLT_ONDEMAND_BIND)" -#else - -/** driver handle */ -static NDIS_HANDLE g_hDriverHandle = NULL; -/** Ndis wrapper handle */ -static NDIS_HANDLE g_hNdisWrapperHandle; -/** device handle for ioctl interface this is not used currently and should be removed soon */ -static NDIS_HANDLE g_hNdisDeviceHandle = NULL; -/** device object used for ioctl interface this is not used currently and should be removed soon */ -static PDEVICE_OBJECT g_pControlDeviceObject = NULL; -/** ioctl device ref count */ -static LONG g_cControlDeviceRefs = 0; -/** true if control device needs to be dereferenced before destroying */ -static bool g_bControlDeviceReferenced = false; - -enum _DEVICE_STATE -{ - /** ready for create/delete */ - PS_DEVICE_STATE_READY = 0, - /** create operation in progress */ - PS_DEVICE_STATE_CREATING, - /** delete operation in progress */ - PS_DEVICE_STATE_DELETING -} g_eControlDeviceState = PS_DEVICE_STATE_READY; - -/* - * miniport - */ -typedef struct { - PVOID aBuffer[8]; -}OUR_SECURITY_DESCRIPTOR_BUFFER; - -static PUCHAR vboxNetFltWinMpDbgGetOidName(ULONG oid); - -#ifdef VBOXNETFLT_WITH_IOCTL_SECURITY -NTSYSAPI -NTSTATUS -NTAPI -ZwSetSecurityObject(IN HANDLE hHandle, - IN SECURITY_INFORMATION SInfo, - IN PSECURITY_DESCRIPTOR pSDescriptor); -/* - * makes our device object usable/accessible for non-privileged users - */ -static NTSTATUS vboxNetFltWinSetSecurity(PNDIS_STRING pDevName) -{ - NTSTATUS Status; - OBJECT_ATTRIBUTES ObjAttr; - IO_STATUS_BLOCK IoStatus; - HANDLE hFile; - OUR_SECURITY_DESCRIPTOR_BUFFER SecurityDes; - - /*obtain the handle first*/ - NdisZeroMemory(&ObjAttr, sizeof(ObjAttr)); - InitializeObjectAttributes(&ObjAttr, pDevName, - OBJ_KERNEL_HANDLE /* ULONG Attributes */, - NULL /*HANDLE RootDirectory*/, - NULL /*PSECURITY_DESCRIPTOR SecurityDescriptor */ - ); - - NdisZeroMemory(&IoStatus, sizeof(IoStatus)); - Status = ZwOpenFile(&hFile /* PHANDLE FileHandle*/, - WRITE_DAC /*ACCESS_MASK DesiredAccess - we want to change the ACL */, - &ObjAttr /*POBJECT_ATTRIBUTES */, - &IoStatus /*PIO_STATUS_BLOCK */, - 0 /*ULONG ShareAccess*/, - 0 /*ULONG OpenOptions*/ - ); - Assert(Status == STATUS_SUCCESS); - if(Status == STATUS_SUCCESS) - { - /* create and set security descriptor */ - NdisZeroMemory(&SecurityDes, sizeof(SecurityDes)); - Status = RtlCreateSecurityDescriptor(&SecurityDes, SECURITY_DESCRIPTOR_REVISION); - Assert(Status == STATUS_SUCCESS); - if(Status == STATUS_SUCCESS) - { - Status = ZwSetSecurityObject(hFile, DACL_SECURITY_INFORMATION, &SecurityDes); - Assert(Status == STATUS_SUCCESS); - if(Status != STATUS_SUCCESS) - { - LogRel(("ZwSetSecurityObject error: Status (0x%x)\n", Status)); - DBGPRINT(("ZwSetSecurityObject error: Status (0x%x)\n", Status)); - } - } - else - { - LogRel(("RtlCreateSecurityDescriptor error: Status (0x%x)\n", Status)); - DBGPRINT(("RtlCreateSecurityDescriptor error: Status (0x%x)\n", Status)); - } - - { - NTSTATUS Tmp = ZwClose(hFile); - Assert(Tmp == STATUS_SUCCESS); - if(Tmp != STATUS_SUCCESS) - { - LogRel(("ZwClose error: Status (0x%x), ignoring\n", Status)); - DBGPRINT(("ZwClose error: Status (0x%x), ignoring\n", Status)); - } - } - } - else - { - LogRel(("ZwOpenFile error: Status (0x%x)\n", Status)); - DBGPRINT(("ZwOpenFile error: Status (0x%x)\n", Status)); - } - - return Status; -} -#endif -/** - * Register an ioctl interface - a device object to be used for this - * purpose is created by NDIS when we call NdisMRegisterDevice. - * - * This routine is called whenever a new miniport instance is - * initialized. However, we only create one global device object, - * when the first miniport instance is initialized. This routine - * handles potential race conditions with vboxNetFltWinPtDeregisterDevice via - * the g_eControlDeviceState and g_cControlDeviceRefs variables. - * - * NOTE: do not call this from DriverEntry; it will prevent the driver - * from being unloaded (e.g. on uninstall). - * - * @return NDIS_STATUS_SUCCESS if we successfully register a device object. */ -static NDIS_STATUS -vboxNetFltWinPtRegisterDevice( - VOID - ) -{ - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - UNICODE_STRING DeviceName; - UNICODE_STRING DeviceLinkUnicodeString; - PDRIVER_DISPATCH DispatchTable[IRP_MJ_MAXIMUM_FUNCTION+1]; - - LogFlow(("==>vboxNetFltWinPtRegisterDevice\n")); - - NdisAcquireSpinLock(&g_GlobalLock); - - ++g_cControlDeviceRefs; - - if (1 == g_cControlDeviceRefs) - { - Assert(g_eControlDeviceState != PS_DEVICE_STATE_CREATING); - - /* Another thread could be running vboxNetFltWinPtDeregisterDevice on - * behalf of another miniport instance. If so, wait for - * it to exit. */ - while (g_eControlDeviceState != PS_DEVICE_STATE_READY) - { - NdisReleaseSpinLock(&g_GlobalLock); - NdisMSleep(1); - NdisAcquireSpinLock(&g_GlobalLock); - } - - g_eControlDeviceState = PS_DEVICE_STATE_CREATING; - - NdisReleaseSpinLock(&g_GlobalLock); - - - NdisZeroMemory(DispatchTable, (IRP_MJ_MAXIMUM_FUNCTION+1) * sizeof(PDRIVER_DISPATCH)); - - DispatchTable[IRP_MJ_CREATE] = vboxNetFltWinPtDispatch; - DispatchTable[IRP_MJ_CLEANUP] = vboxNetFltWinPtDispatch; - DispatchTable[IRP_MJ_CLOSE] = vboxNetFltWinPtDispatch; - DispatchTable[IRP_MJ_DEVICE_CONTROL] = vboxNetFltWinPtDispatch; - - - NdisInitUnicodeString(&DeviceName, NTDEVICE_STRING); - NdisInitUnicodeString(&DeviceLinkUnicodeString, LINKNAME_STRING); - - /* Create a device object and register our dispatch handlers */ - - Status = NdisMRegisterDevice( - g_hNdisWrapperHandle, - &DeviceName, - &DeviceLinkUnicodeString, - &DispatchTable[0], - &g_pControlDeviceObject, - &g_hNdisDeviceHandle - ); - - Assert(Status == NDIS_STATUS_SUCCESS); - if(Status == NDIS_STATUS_SUCCESS) - { -#ifdef VBOXNETFLT_WITH_IOCTL_SECURITY - /* NdisMRegisterDevice does not offers us the ability to set security attributes */ - /* need to do this "manually" for the device to be accessible by the non-privileged users */ - Status = vboxNetFltWinSetSecurity(&DeviceLinkUnicodeString); - Assert(Status == STATUS_SUCCESS); - if(Status != STATUS_SUCCESS) - { - LogRel(("Failed to set security attributes for netflt control device, status (0x%x), ignoring\n", Status)); - /* ignore the failure */ - Status = NDIS_STATUS_SUCCESS; - } -#endif - - Status = ObReferenceObjectByPointer(g_pControlDeviceObject, FILE_READ_DATA, NULL, KernelMode); - Assert(Status == NDIS_STATUS_SUCCESS); - if(Status == NDIS_STATUS_SUCCESS) - { - g_bControlDeviceReferenced = true; - } - else - { - LogRel(("Failed to reference netflt control device, status (0x%x), ignoring\n", Status)); - /* ignore the failure */ - Status = NDIS_STATUS_SUCCESS; - g_bControlDeviceReferenced = false; - } - } - - NdisAcquireSpinLock(&g_GlobalLock); - - g_eControlDeviceState = PS_DEVICE_STATE_READY; - } - - NdisReleaseSpinLock(&g_GlobalLock); - - LogFlow(("<==vboxNetFltWinPtRegisterDevice: %x\n", Status)); - - return (Status); -} - -/** - * Deregister the ioctl interface. This is called whenever a miniport - * instance is halted. When the last miniport instance is halted, we - * request NDIS to delete the device object - * - * @return NDIS_STATUS_SUCCESS if everything worked ok - * */ -static NDIS_STATUS -vboxNetFltWinPtDeregisterDevice( - VOID - ) -{ - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - - LogFlow(("==>NetFltDeregisterDevice\n")); - - NdisAcquireSpinLock(&g_GlobalLock); - - Assert(g_cControlDeviceRefs > 0); - - --g_cControlDeviceRefs; - - if (0 == g_cControlDeviceRefs) - { - /* All miniport instances have been halted. Deregister - * the control device. */ - - Assert(g_eControlDeviceState == PS_DEVICE_STATE_READY); - - /* Block vboxNetFltWinPtRegisterDevice() while we release the control - * device lock and deregister the device. */ - - g_eControlDeviceState = PS_DEVICE_STATE_DELETING; - - NdisReleaseSpinLock(&g_GlobalLock); - - if (g_hNdisDeviceHandle != NULL) - { - if(g_bControlDeviceReferenced) - { - g_bControlDeviceReferenced = false; - ObDereferenceObject(g_pControlDeviceObject); - } - - Status = NdisMDeregisterDevice(g_hNdisDeviceHandle); - g_hNdisDeviceHandle = NULL; - } - - NdisAcquireSpinLock(&g_GlobalLock); - g_eControlDeviceState = PS_DEVICE_STATE_READY; - } - - NdisReleaseSpinLock(&g_GlobalLock); - - LogFlow(("<== NetFltDeregisterDevice: %x\n", Status)); - return Status; - -} -#ifndef VBOXNETADP -/** - * This is the initialize handler which gets called as a result of - * the BindAdapter handler calling NdisIMInitializeDeviceInstanceEx. - * The context parameter which we pass there is the adapter structure - * which we retrieve here. - * - * @param OpenErrorStatus Not used by us. - * @param SelectedMediumIndex Place-holder for what media we are using - * @param MediumArray Array of ndis media passed down to us to pick from - * @param MediumArraySize Size of the array - * @param MiniportAdapterHandle The handle NDIS uses to refer to us - * @param WrapperConfigurationContext For use by NdisOpenConfiguration - * @return NDIS_STATUS_SUCCESS unless something goes wrong - * */ -static NDIS_STATUS vboxNetFltWinMpInitialize( - OUT PNDIS_STATUS OpenErrorStatus, - OUT PUINT SelectedMediumIndex, - IN PNDIS_MEDIUM MediumArray, - IN UINT MediumArraySize, - IN NDIS_HANDLE MiniportAdapterHandle, - IN NDIS_HANDLE WrapperConfigurationContext - ) -{ - UINT i; - PADAPT pAdapt; - NDIS_STATUS Status = NDIS_STATUS_FAILURE; - NDIS_MEDIUM Medium; - - UNREFERENCED_PARAMETER(WrapperConfigurationContext); - - do - { - /* - * Start off by retrieving our adapter context and storing - * the Miniport handle in it. - */ - pAdapt = (PADAPT)NdisIMGetDeviceContext(MiniportAdapterHandle); - pAdapt->hMiniportHandle = MiniportAdapterHandle; - - Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Initializing); - /* the MP state should be already set to kVBoxNetDevOpState_Initializing, just a paranoia - * in case NDIS for some reason calls us in some irregular way */ - vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Initializing); - - LogFlow(("==> Miniport Initialize: Adapt %p\n", pAdapt)); - - /* - * Usually we export the medium type of the adapter below as our - * virtual miniport's medium type. However if the adapter below us - * is a WAN device, then we claim to be of medium type 802.3. - */ - Medium = pAdapt->Medium; - - if (Medium == NdisMediumWan) - { - Medium = NdisMedium802_3; - } - - for (i = 0; i < MediumArraySize; i++) - { - if (MediumArray[i] == Medium) - { - *SelectedMediumIndex = i; - break; - } - } - - if (i == MediumArraySize) - { - Status = NDIS_STATUS_UNSUPPORTED_MEDIA; - break; - } - - - /* - * Set the attributes now. NDIS_ATTRIBUTE_DESERIALIZE enables us - * to make up-calls to NDIS without having to call NdisIMSwitchToMiniport - * or NdisIMQueueCallBack. This also forces us to protect our data using - * spinlocks where appropriate. Also in this case NDIS does not queue - * packets on our behalf. Since this is a very simple pass-thru - * miniport, we do not have a need to protect anything. However in - * a general case there will be a need to use per-adapter spin-locks - * for the packet queues at the very least. - */ - NdisMSetAttributesEx(MiniportAdapterHandle, - pAdapt, - 0, /* CheckForHangTimeInSeconds */ - NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT | - NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT| - NDIS_ATTRIBUTE_INTERMEDIATE_DRIVER | - NDIS_ATTRIBUTE_DESERIALIZE | - NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND, - (NDIS_INTERFACE_TYPE)0); - - /* - * Initialize LastIndicatedStatus to be NDIS_STATUS_MEDIA_CONNECT - */ - pAdapt->LastIndicatedStatus = NDIS_STATUS_MEDIA_CONNECT; - - /* - * Initialize the power states for both the lower binding (PTDeviceState) - * and our miniport edge to Powered On. - */ - Assert(vboxNetFltWinGetPowerState(&pAdapt->MPState) == NdisDeviceStateD3); - vboxNetFltWinSetPowerState(&pAdapt->MPState, NdisDeviceStateD0); - Assert(pAdapt->MPState.OpState == kVBoxNetDevOpState_Initializing); - vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Initialized); - - Status = NDIS_STATUS_SUCCESS; - } - while (FALSE); - - /* - * If we had received an UnbindAdapter notification on the underlying - * adapter, we would have blocked that thread waiting for the IM Init - * process to complete. Wake up any such thread. - */ - if(Status != NDIS_STATUS_SUCCESS) - { - Assert(vboxNetFltWinGetPowerState(&pAdapt->MPState) == NdisDeviceStateD3); - Assert(pAdapt->MPState.OpState == kVBoxNetDevOpState_Initializing); - vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized); - } - NdisSetEvent(&pAdapt->MiniportInitEvent); - - LogFlow(("<== Miniport Initialize: Adapt %p, Status %x\n", pAdapt, Status)); - - *OpenErrorStatus = Status; - - return Status; -} - -/** - * process the packet send in a "passthru" mode - */ -static NDIS_STATUS -vboxNetFltWinSendPassThru( - IN PADAPT pAdapt, - IN PNDIS_PACKET pPacket -#ifdef VBOXNETFLT_NO_PACKET_QUEUE - , bool bNetFltActive -#endif - ) -{ - PNDIS_PACKET pMyPacket; - NDIS_STATUS fStatus; - - fStatus = vboxNetFltWinPrepareSendPacket(pAdapt, pPacket, &pMyPacket/*, false*/); - - Assert(fStatus == NDIS_STATUS_SUCCESS); - if (fStatus == NDIS_STATUS_SUCCESS) - { -#if !defined(VBOX_LOOPBACK_USEFLAGS) /* || defined(DEBUG_NETFLT_PACKETS) */ -# ifdef VBOXNETFLT_NO_PACKET_QUEUE - if (bNetFltActive) - vboxNetFltWinLbPutSendPacket(pAdapt, pMyPacket, false /* bFromIntNet */); -# else - /* no need for the loop enqueue & check in a passthru mode , ndis will do everything for us */ -# endif -#endif - NdisSend(&fStatus, - pAdapt->hBindingHandle, - pMyPacket); - if (fStatus != NDIS_STATUS_PENDING) - { -#ifndef WIN9X - NdisIMCopySendCompletePerPacketInfo (pPacket, pMyPacket); -#endif -#if defined(VBOXNETFLT_NO_PACKET_QUEUE) && !defined(VBOX_LOOPBACK_USEFLAGS) - if (bNetFltActive) - vboxNetFltWinLbRemoveSendPacket(pAdapt, pMyPacket); -#endif - NdisFreePacket(pMyPacket); - } - } - return fStatus; -} - -#else /* defined VBOXNETADP */ -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpDoDeinitialization(PADAPT pAdapt) -{ - PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt); - RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; - uint64_t NanoTS = RTTimeSystemNanoTS(); - int cPPUsage; - - Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Initialized); - /* - * Set the flag that the miniport below is unbinding, so the request handlers will - * fail any request coming later - */ - RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp); - - ASMAtomicUoWriteBool(&pNetFlt->fDisconnectedFromHost, true); - ASMAtomicUoWriteBool(&pNetFlt->fRediscoveryPending, false); - ASMAtomicUoWriteU64(&pNetFlt->NanoTSLastRediscovery, NanoTS); - - vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitializing); - - RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); - - vboxNetFltWinWaitDereference(&pAdapt->MPState); - - /* check packet pool is empty */ - cPPUsage = NdisPacketPoolUsage(pAdapt->hRecvPacketPoolHandle); - Assert(cPPUsage == 0); - /* for debugging only, ignore the err in release */ - NOREF(cPPUsage); - - vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized); - -// pAdapt->hMiniportHandle = NULL; - - return NDIS_STATUS_SUCCESS; -} - -static NDIS_STATUS vboxNetFltWinMpReadApplyConfig(PADAPT pAdapt, NDIS_HANDLE hMiniportAdapter, NDIS_HANDLE hWrapperConfigurationContext) -{ - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - NDIS_HANDLE hConfiguration; - PNDIS_CONFIGURATION_PARAMETER pParameterValue; - NDIS_STRING strMAC = NDIS_STRING_CONST("MAC"); - PVBOXNETFLTINS pThis = PADAPT_2_PVBOXNETFLTINS(pAdapt); - RTMAC mac; - - // - // Open the registry for this adapter to read advanced - // configuration parameters stored by the INF file. - // - NdisOpenConfiguration( - &Status, - &hConfiguration, - hWrapperConfigurationContext); - Assert(Status == NDIS_STATUS_SUCCESS); - if(Status == NDIS_STATUS_SUCCESS) - { - do - { - int rc; - NDIS_CONFIGURATION_PARAMETER param; - WCHAR MacBuf[13]; - - - NdisReadConfiguration(&Status, - &pParameterValue, - hConfiguration, - &strMAC, - NdisParameterString); -// Assert(Status == NDIS_STATUS_SUCCESS); - if(Status == NDIS_STATUS_SUCCESS) - { - - rc = vboxNetFltWinMACFromNdisString(&mac, &pParameterValue->ParameterData.StringData); - AssertRC(rc); - if(RT_SUCCESS(rc)) - { - break; - } - } - - vboxNetFltWinGenerateMACAddress(&mac); - param.ParameterType = NdisParameterString; - param.ParameterData.StringData.Buffer = MacBuf; - param.ParameterData.StringData.MaximumLength = sizeof(MacBuf); - - rc = vboxNetFltWinMAC2NdisString(&mac, ¶m.ParameterData.StringData); - Assert(RT_SUCCESS(rc)); - if(RT_SUCCESS(rc)) - { - NdisWriteConfiguration(&Status, - hConfiguration, - &strMAC, - ¶m); - Assert(Status == NDIS_STATUS_SUCCESS); - if(Status != NDIS_STATUS_SUCCESS) - { - /* ignore the failure */ - Status = NDIS_STATUS_SUCCESS; - } - } - }while(0); - - NdisCloseConfiguration(hConfiguration); - } - else - { - vboxNetFltWinGenerateMACAddress(&mac); - } - - pThis->u.s.MacAddr = mac; - - return NDIS_STATUS_SUCCESS; -} - -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpDoInitialization(PADAPT pAdapt, NDIS_HANDLE hMiniportAdapter, NDIS_HANDLE hWrapperConfigurationContext) -{ - NDIS_STATUS Status; - pAdapt->hMiniportHandle = hMiniportAdapter; - - LogFlow(("==> vboxNetFltWinMpDoInitialization: Adapt %p\n", pAdapt)); - - Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitialized); - vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Initializing); - - vboxNetFltWinMpReadApplyConfig(pAdapt, hMiniportAdapter, hWrapperConfigurationContext); - - NdisMSetAttributesEx(hMiniportAdapter, - pAdapt, - 0, /* CheckForHangTimeInSeconds */ - NDIS_ATTRIBUTE_DESERIALIZE | - NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND, - NdisInterfaceInternal/*(NDIS_INTERFACE_TYPE)0*/); - - /* - * Initialize the power states for both the lower binding (PTDeviceState) - * and our miniport edge to Powered On. - */ - Assert(vboxNetFltWinGetPowerState(&pAdapt->MPState) == NdisDeviceStateD3); - vboxNetFltWinSetPowerState(&pAdapt->MPState, NdisDeviceStateD0); - Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Initializing); - vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Initialized); - - Status = NDIS_STATUS_SUCCESS; - - -// *OpenErrorStatus = Status; - - LogFlow(("<== vboxNetFltWinMpDoInitialization: Adapt %p, Status %x\n", pAdapt, Status)); - - return Status; -} - -/** - * This is the initialize handler which gets called as a result of - * the BindAdapter handler calling NdisIMInitializeDeviceInstanceEx. - * The context parameter which we pass there is the adapter structure - * which we retrieve here. - * - * @param OpenErrorStatus Not used by us. - * @param SelectedMediumIndex Place-holder for what media we are using - * @param MediumArray Array of ndis media passed down to us to pick from - * @param MediumArraySize Size of the array - * @param MiniportAdapterHandle The handle NDIS uses to refer to us - * @param WrapperConfigurationContext For use by NdisOpenConfiguration - * @return NDIS_STATUS_SUCCESS unless something goes wrong - * */ -static NDIS_STATUS vboxNetFltWinMpInitialize( - OUT PNDIS_STATUS OpenErrorStatus, - OUT PUINT SelectedMediumIndex, - IN PNDIS_MEDIUM MediumArray, - IN UINT MediumArraySize, - IN NDIS_HANDLE MiniportAdapterHandle, - IN NDIS_HANDLE WrapperConfigurationContext - ) -{ - UINT i; - PADAPT pAdapt; - NDIS_STATUS Status = NDIS_STATUS_FAILURE; - NDIS_MEDIUM Medium; - - UNREFERENCED_PARAMETER(WrapperConfigurationContext); - - Medium = NdisMedium802_3; - - if (Medium == NdisMediumWan) - { - Medium = NdisMedium802_3; - } - - for (i = 0; i < MediumArraySize; i++) - { - if (MediumArray[i] == Medium) - { - *SelectedMediumIndex = i; - break; - } - } - - if (i != MediumArraySize) - { - PDEVICE_OBJECT pPdo, pFdo; -#define KEY_PREFIX L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\" - UCHAR Buf[512]; - PUCHAR pSuffix; - ULONG cbBuf; - NDIS_STRING RtlStr; - - wcscpy((WCHAR*)Buf, KEY_PREFIX); - pSuffix = Buf + (sizeof(KEY_PREFIX)-2); - - NdisMGetDeviceProperty(MiniportAdapterHandle, - &pPdo, - &pFdo, - NULL, //Next Device Object - NULL, - NULL); - - Status = IoGetDeviceProperty (pPdo, - DevicePropertyDriverKeyName, - sizeof(Buf) - (sizeof(KEY_PREFIX)-2), - pSuffix, - &cbBuf); - if(Status == STATUS_SUCCESS) - { - OBJECT_ATTRIBUTES ObjAttr; - HANDLE hDrvKey; - RtlStr.Buffer=(WCHAR*)Buf; - RtlStr.Length=(USHORT)cbBuf - 2 + sizeof(KEY_PREFIX) - 2; - RtlStr.MaximumLength=sizeof(Buf); - - InitializeObjectAttributes(&ObjAttr, &RtlStr, OBJ_CASE_INSENSITIVE, NULL, NULL); - - Status = ZwOpenKey(&hDrvKey, KEY_READ, &ObjAttr); - if(Status == STATUS_SUCCESS) - { - static UNICODE_STRING NetCfgInstanceIdValue = NDIS_STRING_CONST("NetCfgInstanceId"); -// UCHAR valBuf[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + RTUUID_STR_LENGTH*2 + 10]; -// ULONG cLength = sizeof(valBuf); -#define NAME_PREFIX L"\\DEVICE\\" - PKEY_VALUE_PARTIAL_INFORMATION pInfo = (PKEY_VALUE_PARTIAL_INFORMATION)Buf; - Status = ZwQueryValueKey(hDrvKey, - &NetCfgInstanceIdValue, - KeyValuePartialInformation, - pInfo, - sizeof(Buf), - &cbBuf); - if(Status == STATUS_SUCCESS) - { - if(pInfo->Type == REG_SZ && pInfo->DataLength > 2) - { - WCHAR *pName; - Status = vboxNetFltWinMemAlloc(&pName, pInfo->DataLength + sizeof(NAME_PREFIX)); - if(Status == STATUS_SUCCESS) - { - wcscpy(pName, NAME_PREFIX); - wcscpy(pName+(sizeof(NAME_PREFIX)-2)/2, (WCHAR*)pInfo->Data); - RtlStr.Buffer=pName; - RtlStr.Length = (USHORT)pInfo->DataLength - 2 + sizeof(NAME_PREFIX) - 2; - RtlStr.MaximumLength = (USHORT)pInfo->DataLength + sizeof(NAME_PREFIX); - - Status = vboxNetFltWinPtInitBind(&pAdapt, MiniportAdapterHandle, &RtlStr, WrapperConfigurationContext); - - if(Status == STATUS_SUCCESS) - { - Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Initialized); - vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Initialized); -#if 0 - NdisMIndicateStatus(pAdapt->hMiniportHandle, - NDIS_STATUS_MEDIA_CONNECT, - (PVOID)NULL, - 0); -#endif - } - else - { - Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitialized); - vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized); - } - - vboxNetFltWinMemFree(pName); - - } - } - else - { - Status = NDIS_STATUS_FAILURE; - } - } - } - } - } - else - { - Status = NDIS_STATUS_UNSUPPORTED_MEDIA; - } - - if(Status != NDIS_STATUS_SUCCESS) - { - vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized); - } - - /* TODO: */ - *OpenErrorStatus = Status; - - return Status; -} -#endif - - -/** - * Send Packet Array handler. Either this or our SendPacket handler is called - * based on which one is enabled in our Miniport Characteristics. - * - * @param MiniportAdapterContext Pointer to our adapter - * @param PacketArray Set of packets to send - * @param NumberOfPackets Self-explanatory - * @return none */ -static VOID -vboxNetFltWinMpSendPackets( - IN NDIS_HANDLE fMiniportAdapterContext, - IN PPNDIS_PACKET pPacketArray, - IN UINT cNumberOfPackets - ) -{ - PADAPT pAdapt = (PADAPT)fMiniportAdapterContext; - NDIS_STATUS fStatus = NDIS_STATUS_SUCCESS; - UINT i; - PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt); - bool bNetFltActive; - - Assert(cNumberOfPackets); - - if(vboxNetFltWinIncReferenceAdaptNetFlt(pNetFlt, pAdapt, cNumberOfPackets, &bNetFltActive)) - { - uint32_t cAdaptRefs = cNumberOfPackets; - uint32_t cNetFltRefs; - uint32_t cPassThruRefs; - if(bNetFltActive) - { - cNetFltRefs = cNumberOfPackets; - cPassThruRefs = 0; - } - else - { - cPassThruRefs = cNumberOfPackets; - cNetFltRefs = 0; - } - - for (i = 0; i < cNumberOfPackets; i++) - { - PNDIS_PACKET pPacket; - - pPacket = pPacketArray[i]; - - if(!cNetFltRefs -#ifdef VBOXNETFLT_NO_PACKET_QUEUE - || !vboxNetFltWinPostIntnet(pNetFlt, pPacket, PACKET_SRC_HOST) -#else - || (fStatus = vboxNetFltWinQuEnqueuePacket(pNetFlt, pPacket, PACKET_SRC_HOST)) != NDIS_STATUS_SUCCESS -#endif - ) - { -#ifndef VBOXNETADP - fStatus = vboxNetFltWinSendPassThru(pAdapt, pPacket -#ifdef VBOXNETFLT_NO_PACKET_QUEUE - , !!cNetFltRefs -#endif - ); -#else - if(!cNetFltRefs) - { -# ifdef VBOXNETADP_REPORT_DISCONNECTED - fStatus = NDIS_STATUS_MEDIA_DISCONNECT; - STATISTIC_INCREASE(pAdapt->cTxError); -# else - fStatus = NDIS_STATUS_SUCCESS; -# endif - } -#endif - - if (fStatus != NDIS_STATUS_PENDING) - { - NdisMSendComplete(pAdapt->hMiniportHandle, - pPacket, - fStatus); - } - else - { - cAdaptRefs--; - } - } - else - { -#ifdef VBOXNETFLT_NO_PACKET_QUEUE - NdisMSendComplete(pAdapt->hMiniportHandle, - pPacket, - NDIS_STATUS_SUCCESS); -#else - cAdaptRefs--; - cNetFltRefs--; -#endif - } - } - - if(cNetFltRefs) - { - vboxNetFltWinDecReferenceNetFlt(pNetFlt, cNetFltRefs); - } - else if(cPassThruRefs) - { - vboxNetFltWinDecReferenceModePassThru(pNetFlt, cPassThruRefs); - } - if(cAdaptRefs) - { - vboxNetFltWinDecReferenceAdapt(pAdapt, cAdaptRefs); - } - } - else - { - NDIS_HANDLE h = pAdapt->hMiniportHandle; - Assert(0); - if(h) - { - for (i = 0; i < cNumberOfPackets; i++) - { - PNDIS_PACKET pPacket; - pPacket = pPacketArray[i]; - NdisMSendComplete(h, - pPacket, - NDIS_STATUS_FAILURE); - } - } - } -} -#ifndef VBOXNETADP -/** - * Entry point called by NDIS to query for the value of the specified OID. - * Typical processing is to forward the query down to the underlying miniport. - * - * The following OIDs are filtered here: - * OID_PNP_QUERY_POWER - return success right here - * OID_GEN_SUPPORTED_GUIDS - do not forward, otherwise we will show up - * multiple instances of private GUIDs supported by the underlying miniport. - * OID_PNP_CAPABILITIES - we do send this down to the lower miniport, but - * the values returned are postprocessed before we complete this request; - * see vboxNetFltWinPtRequestComplete. - * - * NOTE on OID_TCP_TASK_OFFLOAD - if this IM driver modifies the contents - * of data it passes through such that a lower miniport may not be able - * to perform TCP task offload, then it should not forward this OID down, - * but fail it here with the status NDIS_STATUS_NOT_SUPPORTED. This is to - * avoid performing incorrect transformations on data. - * - * If our miniport edge (upper edge) is at a low-power state, fail the request. - * If our protocol edge (lower edge) has been notified of a low-power state, - * we pend this request until the miniport below has been set to D0. Since - * requests to miniports are serialized always, at most a single request will - * be pended. - * - * @param MiniportAdapterContext Pointer to the adapter structure - * @param Oid Oid for this query - * @param InformationBuffer Buffer for information - * @param InformationBufferLength Size of this buffer - * @param BytesWritten Specifies how much info is written - * @param BytesNeeded In case the buffer is smaller than what we need, tell them how much is needed - * @return Return code from the NdisRequest below. - * */ -static NDIS_STATUS -vboxNetFltWinMpQueryInformation( - IN NDIS_HANDLE MiniportAdapterContext, - IN NDIS_OID Oid, - IN PVOID InformationBuffer, - IN ULONG InformationBufferLength, - OUT PULONG BytesWritten, - OUT PULONG BytesNeeded - ) -{ - PADAPT pAdapt = (PADAPT)MiniportAdapterContext; - NDIS_STATUS Status = NDIS_STATUS_FAILURE; - PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt); - RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; - - do - { - if (Oid == OID_PNP_QUERY_POWER) - { - /* - * Do not forward this. - */ - Status = NDIS_STATUS_SUCCESS; - break; - } - - if (Oid == OID_GEN_SUPPORTED_GUIDS) - { - /* - * Do not forward this, otherwise we will end up with multiple - * instances of private GUIDs that the underlying miniport - * supports. - */ - Status = NDIS_STATUS_NOT_SUPPORTED; - break; - } - - if (Oid == OID_TCP_TASK_OFFLOAD) - { - /* we want to receive packets with checksums calculated - * since we are passing them to IntNet - */ - Status = NDIS_STATUS_NOT_SUPPORTED; - break; - } - - /* - * If the miniport below is unbinding, just fail any request - */ - if (vboxNetFltWinGetOpState(&pAdapt->PTState) > kVBoxNetDevOpState_Initialized) /* protocol unbind in progress */ - { - Status = NDIS_STATUS_FAILURE; - break; - } - - /* - * All other queries are failed, if the miniport is not at D0, - */ - if (vboxNetFltWinGetPowerState(&pAdapt->MPState) > NdisDeviceStateD0) - { - Status = NDIS_STATUS_FAILURE; - break; - } - - pAdapt->Request.RequestType = NdisRequestQueryInformation; - pAdapt->Request.DATA.QUERY_INFORMATION.Oid = Oid; - pAdapt->Request.DATA.QUERY_INFORMATION.InformationBuffer = InformationBuffer; - pAdapt->Request.DATA.QUERY_INFORMATION.InformationBufferLength = InformationBufferLength; - pAdapt->BytesNeeded = BytesNeeded; - pAdapt->BytesReadOrWritten = BytesWritten; - - /* - * If the miniport below is binding, fail the request - */ - RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp); - - if (vboxNetFltWinGetOpState(&pAdapt->PTState) > kVBoxNetDevOpState_Initialized) - { - RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); - Status = NDIS_STATUS_FAILURE; - break; - } - /* - * If the Protocol device state is OFF, mark this request as being - * pended. We queue this until the device state is back to D0. - */ - if ((vboxNetFltWinGetPowerState(&pAdapt->PTState) > NdisDeviceStateD0) - && (pAdapt->bStandingBy == FALSE)) - { - pAdapt->bQueuedRequest = TRUE; - RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); - Status = NDIS_STATUS_PENDING; - break; - } - /* - * This is in the process of powering down the system, always fail the request - */ - if (pAdapt->bStandingBy == TRUE) - { - RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); - Status = NDIS_STATUS_FAILURE; - break; - } - pAdapt->bOutstandingRequests = TRUE; - - RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); - if(Oid == OID_GEN_CURRENT_PACKET_FILTER && VBOXNETFLT_PROMISCUOUS_SUPPORTED(pAdapt)) - { - bool fNetFltActive; - const bool fAdaptActive = vboxNetFltWinReferenceAdaptNetFlt(pNetFlt, pAdapt, &fNetFltActive); - - Assert(InformationBuffer); - Assert(!pAdapt->fProcessingPacketFilter); - - if(fNetFltActive) - { - /* netflt is active, simply return the cached value */ - *((PULONG)InformationBuffer) = pAdapt->fUpperProtocolSetFilter; - - Status = NDIS_STATUS_SUCCESS; - vboxNetFltWinDereferenceNetFlt(pNetFlt); - vboxNetFltWinDereferenceAdapt(pAdapt); - - RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp); - pAdapt->bOutstandingRequests = FALSE; - RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); - break; - } - else if(fAdaptActive) - { - pAdapt->fProcessingPacketFilter = VBOXNETFLT_PFP_PASSTHRU; - /* we're cleaning it in RequestComplete */ - } - } - - /* - * default case, most requests will be passed to the miniport below - */ - NdisRequest(&Status, - pAdapt->hBindingHandle, - &pAdapt->Request); - - - if (Status != NDIS_STATUS_PENDING) - { - vboxNetFltWinPtRequestComplete(pAdapt, &pAdapt->Request, Status); - Status = NDIS_STATUS_PENDING; - } - - } while (FALSE); - - return(Status); - -} -/** - * Postprocess a request for OID_PNP_CAPABILITIES that was forwarded - * down to the underlying miniport, and has been completed by it. - * - * @param pAdapt - Pointer to the adapter structure - * @param pStatus - Place to return final status - * @return None. */ -DECLHIDDEN(VOID) -vboxNetFltWinMpQueryPNPCapabilities( - IN OUT PADAPT pAdapt, - OUT PNDIS_STATUS pStatus - ) -{ - PNDIS_PNP_CAPABILITIES pPNPCapabilities; - PNDIS_PM_WAKE_UP_CAPABILITIES pPMstruct; - - if (pAdapt->Request.DATA.QUERY_INFORMATION.InformationBufferLength >= sizeof(NDIS_PNP_CAPABILITIES)) - { - pPNPCapabilities = (PNDIS_PNP_CAPABILITIES)(pAdapt->Request.DATA.QUERY_INFORMATION.InformationBuffer); - - /* - * The following fields must be overwritten by an IM driver. - */ - pPMstruct= & pPNPCapabilities->WakeUpCapabilities; - pPMstruct->MinMagicPacketWakeUp = NdisDeviceStateUnspecified; - pPMstruct->MinPatternWakeUp = NdisDeviceStateUnspecified; - pPMstruct->MinLinkChangeWakeUp = NdisDeviceStateUnspecified; - *pAdapt->BytesReadOrWritten = sizeof(NDIS_PNP_CAPABILITIES); - *pAdapt->BytesNeeded = 0; - - - *pStatus = NDIS_STATUS_SUCCESS; - } - else - { - *pAdapt->BytesNeeded= sizeof(NDIS_PNP_CAPABILITIES); - *pStatus = NDIS_STATUS_RESOURCES; - } -} - -#endif /* ifndef VBOXNETADP*/ - -/** - * This routine does all the processing for a request with a SetPower Oid - * The miniport shoud accept the Set Power and transition to the new state - * - * The Set Power should not be passed to the miniport below - * - * If the IM miniport is going into a low power state, then there is no guarantee if it will ever - * be asked go back to D0, before getting halted. No requests should be pended or queued. - * - * @param pNdisStatus - Status of the operation - * @param pAdapt - The Adapter structure - * @param InformationBuffer - The New DeviceState - * @param InformationBufferLength - * @param BytesRead - No of bytes read - * @param BytesNeeded - No of bytes needed - * @return Status - NDIS_STATUS_SUCCESS if all the wait events succeed. */ -static VOID -vboxNetFltWinMpProcessSetPowerOid( - IN OUT PNDIS_STATUS pNdisStatus, - IN PADAPT pAdapt, - IN PVOID InformationBuffer, - IN ULONG InformationBufferLength, - OUT PULONG BytesRead, - OUT PULONG BytesNeeded - ) -{ - - - NDIS_DEVICE_POWER_STATE NewDeviceState; - - LogFlow(("==>vboxNetFltWinMpProcessSetPowerOid: Adapt %p\n", pAdapt)); - - Assert (InformationBuffer != NULL); - - *pNdisStatus = NDIS_STATUS_FAILURE; - - do - { - /* - * Check for invalid length - */ - if (InformationBufferLength < sizeof(NDIS_DEVICE_POWER_STATE)) - { - *pNdisStatus = NDIS_STATUS_INVALID_LENGTH; - break; - } - - NewDeviceState = (*(PNDIS_DEVICE_POWER_STATE)InformationBuffer); - - /* - * Check for invalid device state - */ - if ((vboxNetFltWinGetPowerState(&pAdapt->MPState) > NdisDeviceStateD0) && (NewDeviceState != NdisDeviceStateD0)) - { - /* - * If the miniport is in a non-D0 state, the miniport can only receive a Set Power to D0 - */ - Assert (!(vboxNetFltWinGetPowerState(&pAdapt->MPState) > NdisDeviceStateD0) && (NewDeviceState != NdisDeviceStateD0)); - - *pNdisStatus = NDIS_STATUS_FAILURE; - break; - } - -#ifndef VBOXNETADP - /* - * Is the miniport transitioning from an On (D0) state to an Low Power State (>D0) - * If so, then set the bStandingBy Flag - (Block all incoming requests) - */ - if (vboxNetFltWinGetPowerState(&pAdapt->MPState) == NdisDeviceStateD0 && NewDeviceState > NdisDeviceStateD0) - { - pAdapt->bStandingBy = TRUE; - } - - /* - * If the miniport is transitioning from a low power state to ON (D0), then clear the bStandingBy flag - * All incoming requests will be pended until the physical miniport turns ON. - */ - if (vboxNetFltWinGetPowerState(&pAdapt->MPState) > NdisDeviceStateD0 && NewDeviceState == NdisDeviceStateD0) - { - pAdapt->bStandingBy = FALSE; - } -#endif - /* - * Now update the state in the pAdapt structure; - */ - vboxNetFltWinSetPowerState(&pAdapt->MPState, NewDeviceState); -#ifndef VBOXNETADP - if(NewDeviceState != NdisDeviceStateD0) - { - vboxNetFltWinPtFlushReceiveQueue(pAdapt, - true ); /* just return */ - } -#endif - *pNdisStatus = NDIS_STATUS_SUCCESS; - - - } while (FALSE); - - if (*pNdisStatus == NDIS_STATUS_SUCCESS) - { -#ifndef VBOXNETADP - /* - * The miniport resume from low power state - */ - if (pAdapt->bStandingBy == FALSE) - { - /* - * If we need to indicate the media connect state - */ - if (pAdapt->LastIndicatedStatus != pAdapt->LatestUnIndicateStatus) - { - NdisMIndicateStatus(pAdapt->hMiniportHandle, - pAdapt->LatestUnIndicateStatus, - (PVOID)NULL, - 0); - NdisMIndicateStatusComplete(pAdapt->hMiniportHandle); - pAdapt->LastIndicatedStatus = pAdapt->LatestUnIndicateStatus; - } - } - else - { - /* - * Initialize LatestUnIndicatedStatus - */ - pAdapt->LatestUnIndicateStatus = pAdapt->LastIndicatedStatus; - } -#endif - *BytesRead = sizeof(NDIS_DEVICE_POWER_STATE); - *BytesNeeded = 0; - } - else - { - *BytesRead = 0; - *BytesNeeded = sizeof (NDIS_DEVICE_POWER_STATE); - } - - LogFlow(("<==vboxNetFltWinMpProcessSetPowerOid: Adapt %p\n", pAdapt)); -} -#ifndef VBOXNETADP -/** - * Miniport SetInfo handler. - * - * In the case of OID_PNP_SET_POWER, record the power state and return the OID. - * Do not pass below - * If the device is suspended, do not block the SET_POWER_OID - * as it is used to reactivate the NetFlt miniport - * - * PM- If the MP is not ON (DeviceState > D0) return immediately (except for 'query power' and 'set power') - * If MP is ON, but the PT is not at D0, then queue the queue the request for later processing - * - * Requests to miniports are always serialized - * - * @param MiniportAdapterContext Pointer to the adapter structure - * @param Oid Oid for this query - * @param InformationBuffer Buffer for information - * @param InformationBufferLength Size of this buffer - * @param BytesRead Specifies how much info is read - * @param BytesNeeded In case the buffer is smaller than what we need, tell them how much is needed - * @return Return code from the NdisRequest below. */ -static NDIS_STATUS -vboxNetFltWinMpSetInformation( - IN NDIS_HANDLE MiniportAdapterContext, - IN NDIS_OID Oid, - IN PVOID InformationBuffer, - IN ULONG InformationBufferLength, - OUT PULONG BytesRead, - OUT PULONG BytesNeeded - ) -{ - PADAPT pAdapt = (PADAPT)MiniportAdapterContext; - NDIS_STATUS Status; - PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt); - RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; - - Status = NDIS_STATUS_FAILURE; - - do - { - /* - * The Set Power should not be sent to the miniport below the NetFlt, but is handled internally - */ - if (Oid == OID_PNP_SET_POWER) - { - vboxNetFltWinMpProcessSetPowerOid(&Status, - pAdapt, - InformationBuffer, - InformationBufferLength, - BytesRead, - BytesNeeded); - break; - - } - - /* - * If the miniport below is unbinding, fail the request - */ - if (vboxNetFltWinGetOpState(&pAdapt->PTState) > kVBoxNetDevOpState_Initialized) - { - Status = NDIS_STATUS_FAILURE; - break; - } - - /* - * All other Set Information requests are failed, if the miniport is - * not at D0 or is transitioning to a device state greater than D0. - */ - if (vboxNetFltWinGetPowerState(&pAdapt->MPState) > NdisDeviceStateD0) - { - Status = NDIS_STATUS_FAILURE; - break; - } - - /* Set up the Request and return the result */ - pAdapt->Request.RequestType = NdisRequestSetInformation; - pAdapt->Request.DATA.SET_INFORMATION.Oid = Oid; - pAdapt->Request.DATA.SET_INFORMATION.InformationBuffer = InformationBuffer; - pAdapt->Request.DATA.SET_INFORMATION.InformationBufferLength = InformationBufferLength; - pAdapt->BytesNeeded = BytesNeeded; - pAdapt->BytesReadOrWritten = BytesRead; - - /* - * If the miniport below is unbinding, fail the request - */ - RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp); - if (vboxNetFltWinGetOpState(&pAdapt->PTState) > kVBoxNetDevOpState_Initialized) - { - RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); - Status = NDIS_STATUS_FAILURE; - break; - } - - /* - * If the device below is at a low power state, we cannot send it the - * request now, and must pend it. - */ - if ((vboxNetFltWinGetPowerState(&pAdapt->PTState) > NdisDeviceStateD0) - && (pAdapt->bStandingBy == FALSE)) - { - pAdapt->bQueuedRequest = TRUE; - RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); - Status = NDIS_STATUS_PENDING; - break; - } - /* - * This is in the process of powering down the system, always fail the request - */ - if (pAdapt->bStandingBy == TRUE) - { - RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); - Status = NDIS_STATUS_FAILURE; - break; - } - pAdapt->bOutstandingRequests = TRUE; - - RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); - - if(Oid == OID_GEN_CURRENT_PACKET_FILTER && VBOXNETFLT_PROMISCUOUS_SUPPORTED(pAdapt)) - { - /* need to disable cleaning promiscuous here ?? */ - bool fNetFltActive; - const bool fAdaptActive = vboxNetFltWinReferenceAdaptNetFlt(pNetFlt, pAdapt, &fNetFltActive); - - Assert(InformationBuffer); - Assert(!pAdapt->fProcessingPacketFilter); - - if(fNetFltActive) - { - Assert(fAdaptActive); - - /* netflt is active, update the cached value */ - /* TODO: in case we are are not in promiscuous now, we are issuing a request. - * what should we do in case of a failure? - * i.e. should we update the fUpperProtocolSetFilter in completion routine in this case? etc. */ - pAdapt->fUpperProtocolSetFilter = *((PULONG)InformationBuffer); - pAdapt->bUpperProtSetFilterInitialized = true; - - if(!(pAdapt->fOurSetFilter & NDIS_PACKET_TYPE_PROMISCUOUS)) - { - pAdapt->fSetFilterBuffer = NDIS_PACKET_TYPE_PROMISCUOUS; - pAdapt->Request.DATA.SET_INFORMATION.InformationBuffer = &pAdapt->fSetFilterBuffer; - pAdapt->Request.DATA.SET_INFORMATION.InformationBufferLength = sizeof(pAdapt->fSetFilterBuffer); - pAdapt->fProcessingPacketFilter = VBOXNETFLT_PFP_NETFLT; - /* we'll do dereferencing in request complete */ - } - else - { - Status = NDIS_STATUS_SUCCESS; - vboxNetFltWinDereferenceNetFlt(pNetFlt); - vboxNetFltWinDereferenceAdapt(pAdapt); - - RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp); - pAdapt->bOutstandingRequests = FALSE; - RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); - break; - } - } - else if(fAdaptActive) - { - pAdapt->fProcessingPacketFilter = VBOXNETFLT_PFP_PASSTHRU; - /* dereference on completion */ - } - } - - /* - * Forward the request to the device below. - */ - NdisRequest(&Status, - pAdapt->hBindingHandle, - &pAdapt->Request); - - if (Status != NDIS_STATUS_PENDING) - { - vboxNetFltWinPtRequestComplete(pAdapt, &pAdapt->Request, Status); - } - - } while (FALSE); - - return(Status); -} -#else -static NDIS_OID g_vboxNetFltWinMpSupportedOids[] = -{ - OID_GEN_SUPPORTED_LIST, - OID_GEN_HARDWARE_STATUS, - OID_GEN_MEDIA_SUPPORTED, - OID_GEN_MEDIA_IN_USE, - OID_GEN_MAXIMUM_LOOKAHEAD, - OID_GEN_MAXIMUM_FRAME_SIZE, - OID_GEN_LINK_SPEED, - OID_GEN_TRANSMIT_BUFFER_SPACE, - OID_GEN_RECEIVE_BUFFER_SPACE, - OID_GEN_TRANSMIT_BLOCK_SIZE, - OID_GEN_RECEIVE_BLOCK_SIZE, - OID_GEN_VENDOR_ID, - OID_GEN_VENDOR_DESCRIPTION, - OID_GEN_VENDOR_DRIVER_VERSION, - OID_GEN_CURRENT_PACKET_FILTER, - OID_GEN_CURRENT_LOOKAHEAD, - OID_GEN_DRIVER_VERSION, - OID_GEN_MAXIMUM_TOTAL_SIZE, - OID_GEN_PROTOCOL_OPTIONS, - OID_GEN_MAC_OPTIONS, - OID_GEN_MEDIA_CONNECT_STATUS, - OID_GEN_MAXIMUM_SEND_PACKETS, - OID_GEN_XMIT_OK, - OID_GEN_RCV_OK, - OID_GEN_XMIT_ERROR, - OID_GEN_RCV_ERROR, - OID_GEN_RCV_NO_BUFFER, - OID_GEN_RCV_CRC_ERROR, - OID_GEN_TRANSMIT_QUEUE_LENGTH, - OID_802_3_PERMANENT_ADDRESS, - OID_802_3_CURRENT_ADDRESS, - OID_802_3_MULTICAST_LIST, - OID_802_3_MAC_OPTIONS, - OID_802_3_MAXIMUM_LIST_SIZE, - OID_802_3_RCV_ERROR_ALIGNMENT, - OID_802_3_XMIT_ONE_COLLISION, - OID_802_3_XMIT_MORE_COLLISIONS, - OID_802_3_XMIT_DEFERRED, - OID_802_3_XMIT_MAX_COLLISIONS, - OID_802_3_RCV_OVERRUN, - OID_802_3_XMIT_UNDERRUN, - OID_802_3_XMIT_HEARTBEAT_FAILURE, - OID_802_3_XMIT_TIMES_CRS_LOST, - OID_802_3_XMIT_LATE_COLLISIONS -#ifndef INTERFACE_WITH_NDISPROT - , - OID_PNP_CAPABILITIES, - OID_PNP_SET_POWER, - OID_PNP_QUERY_POWER -# if 0 - , - OID_PNP_ADD_WAKE_UP_PATTERN, - OID_PNP_REMOVE_WAKE_UP_PATTERN, - OID_PNP_ENABLE_WAKE_UP -# endif -#endif -}; - -static NDIS_STATUS -vboxNetFltWinMpQueryInformation( - IN NDIS_HANDLE MiniportAdapterContext, - IN NDIS_OID Oid, - IN PVOID InformationBuffer, - IN ULONG InformationBufferLength, - OUT PULONG BytesWritten, - OUT PULONG BytesNeeded) -/*++ - -Routine Description: - - Entry point called by NDIS to query for the value of the specified OID. - MiniportQueryInformation runs at IRQL = DISPATCH_LEVEL. - -Arguments: - - MiniportAdapterContext Pointer to the adapter structure - Oid Oid for this query - InformationBuffer Buffer for information - InformationBufferLength Size of this buffer - BytesWritten Specifies how much info is written - BytesNeeded In case the buffer is smaller than - what we need, tell them how much is needed - - -Return Value: - - Return code from the NdisRequest below. - -Notes: Read "Minimizing Miniport Driver Initialization Time" in the DDK - for more info on how to handle certain OIDs that affect the init of - a miniport. - ---*/ -{ - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - PADAPT pAdapt = (PADAPT)MiniportAdapterContext; - NDIS_HARDWARE_STATUS HardwareStatus = NdisHardwareStatusReady; - NDIS_MEDIUM Medium = NdisMedium802_3; - UCHAR VendorDesc[] = VBOXNETADP_VENDOR_DESC; - ULONG ulInfo = 0; - USHORT usInfo = 0; - ULONG64 ulInfo64 = 0; - PVOID pInfo = (PVOID) &ulInfo; - ULONG ulInfoLen = sizeof(ulInfo); - NDIS_PNP_CAPABILITIES PMCaps; - - LogFlow(("==> vboxNetFltWinMpQueryInformation %s\n", vboxNetFltWinMpDbgGetOidName(Oid))); - - // Initialize the result - *BytesWritten = 0; - *BytesNeeded = 0; - - switch(Oid) - { - case OID_GEN_SUPPORTED_LIST: - // - // The OID_GEN_SUPPORTED_LIST OID specifies an array of OIDs - // for objects that the underlying driver or its NIC supports. - // Objects include general, media-specific, and implementation- - // specific objects. NDIS forwards a subset of the returned - // list to protocols that make this query. That is, NDIS filters - // any supported statistics OIDs out of the list because - // protocols never make statistics queries. - // - pInfo = (PVOID) g_vboxNetFltWinMpSupportedOids; - ulInfoLen = sizeof(g_vboxNetFltWinMpSupportedOids); - break; - - case OID_GEN_HARDWARE_STATUS: - // - // Specify the current hardware status of the underlying NIC as - // one of the following NDIS_HARDWARE_STATUS-type values. - // - pInfo = (PVOID) &HardwareStatus; - ulInfoLen = sizeof(NDIS_HARDWARE_STATUS); - break; - - case OID_GEN_MEDIA_SUPPORTED: - // - // Specify the media types that the NIC can support but not - // necessarily the media types that the NIC currently uses. - // fallthrough: - case OID_GEN_MEDIA_IN_USE: - // - // Specify a complete list of the media types that the NIC - // currently uses. - // - pInfo = (PVOID) &Medium; - ulInfoLen = sizeof(NDIS_MEDIUM); - break; - - case OID_GEN_CURRENT_LOOKAHEAD: - case OID_GEN_MAXIMUM_LOOKAHEAD: - // - // If the miniport driver indicates received data by calling - // NdisXxxIndicateReceive, it should respond to OID_GEN_MAXIMUM_LOOKAHEAD - // with the maximum number of bytes the NIC can provide as - // lookahead data. If that value is different from the size of the - // lookahead buffer supported by bound protocols, NDIS will call - // MiniportSetInformation to set the size of the lookahead buffer - // provided by the miniport driver to the minimum of the miniport - // driver and protocol(s) values. If the driver always indicates - // up full packets with NdisMIndicateReceivePacket, it should - // set this value to the maximum total packet size, which - // excludes the header. - // Upper-layer drivers examine lookahead data to determine whether - // a packet that is associated with the lookahead data is intended - // for one or more of their clients. If the underlying driver - // supports multipacket receive indications, bound protocols are - // given full net packets on every indication. Consequently, - // this value is identical to that returned for - // OID_GEN_RECEIVE_BLOCK_SIZE. - // - ulInfo = VBOXNETADP_MAX_LOOKAHEAD_SIZE; - break; - - case OID_GEN_MAXIMUM_FRAME_SIZE: - // - // Specify the maximum network packet size, in bytes, that the - // NIC supports excluding the header. A NIC driver that emulates - // another medium type for binding to a transport must ensure that - // the maximum frame size for a protocol-supplied net packet does - // not exceed the size limitations for the true network medium. - // - ulInfo = VBOXNETADP_MAX_PACKET_SIZE - VBOXNETADP_HEADER_SIZE; - break; - - case OID_GEN_MAXIMUM_TOTAL_SIZE: - // - // Specify the maximum total packet length, in bytes, the NIC - // supports including the header. A protocol driver might use - // this returned length as a gauge to determine the maximum - // size packet that a NIC driver could forward to the - // protocol driver. The miniport driver must never indicate - // up to the bound protocol driver packets received over the - // network that are longer than the packet size specified by - // OID_GEN_MAXIMUM_TOTAL_SIZE. - // - case OID_GEN_TRANSMIT_BLOCK_SIZE: - // - // The OID_GEN_TRANSMIT_BLOCK_SIZE OID specifies the minimum - // number of bytes that a single net packet occupies in the - // transmit buffer space of the NIC. For example, a NIC that - // has a transmit space divided into 256-byte pieces would have - // a transmit block size of 256 bytes. To calculate the total - // transmit buffer space on such a NIC, its driver multiplies - // the number of transmit buffers on the NIC by its transmit - // block size. In our case, the transmit block size is - // identical to its maximum packet size. - - case OID_GEN_RECEIVE_BLOCK_SIZE: - // - // The OID_GEN_RECEIVE_BLOCK_SIZE OID specifies the amount of - // storage, in bytes, that a single packet occupies in the receive - // buffer space of the NIC. - // - ulInfo = (ULONG) VBOXNETADP_MAX_PACKET_SIZE; - break; - - case OID_GEN_MAC_OPTIONS: - // - // Specify a bitmask that defines optional properties of the NIC. - // This miniport indicates receive with NdisMIndicateReceivePacket - // function. It has no MiniportTransferData function. Such a driver - // should set this NDIS_MAC_OPTION_TRANSFERS_NOT_PEND flag. - // - // NDIS_MAC_OPTION_NO_LOOPBACK tells NDIS that NIC has no internal - // loopback support so NDIS will manage loopbacks on behalf of - // this driver. - // - // NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA tells the protocol that - // our receive buffer is not on a device-specific card. If - // NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA is not set, multi-buffer - // indications are copied to a single flat buffer. - // - ulInfo = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | - NDIS_MAC_OPTION_TRANSFERS_NOT_PEND | - NDIS_MAC_OPTION_NO_LOOPBACK; - break; - - case OID_GEN_LINK_SPEED: - // - // Specify the maximum speed of the NIC in kbps. - // The unit of measurement is 100 bps - // - ulInfo = VBOXNETADP_LINK_SPEED; - break; - - case OID_GEN_TRANSMIT_BUFFER_SPACE: - // - // Specify the amount of memory, in bytes, on the NIC that - // is available for buffering transmit data. A protocol can - // use this OID as a guide for sizing the amount of transmit - // data per send. - // - ulInfo = VBOXNETADP_MAX_PACKET_SIZE * PACKET_INFO_POOL_SIZE; - break; - - case OID_GEN_RECEIVE_BUFFER_SPACE: - // - // Specify the amount of memory on the NIC that is available - // for buffering receive data. A protocol driver can use this - // OID as a guide for advertising its receive window after it - // establishes sessions with remote nodes. - // - - ulInfo = VBOXNETADP_MAX_PACKET_SIZE * PACKET_INFO_POOL_SIZE; - break; - - case OID_GEN_VENDOR_ID: - // - // Specify a three-byte IEEE-registered vendor code, followed - // by a single byte that the vendor assigns to identify a - // particular NIC. The IEEE code uniquely identifies the vendor - // and is the same as the three bytes appearing at the beginning - // of the NIC hardware address. Vendors without an IEEE-registered - // code should use the value 0xFFFFFF. - // - ulInfo = VBOXNETADP_VENDOR_ID; - break; - - case OID_GEN_VENDOR_DESCRIPTION: - // - // Specify a zero-terminated string describing the NIC vendor. - // - pInfo = VendorDesc; - ulInfoLen = sizeof(VendorDesc); - break; - - case OID_GEN_VENDOR_DRIVER_VERSION: - // - // Specify the vendor-assigned version number of the NIC driver. - // The low-order half of the return value specifies the minor - // version; the high-order half specifies the major version. - // - ulInfo = VBOXNETADP_VENDOR_DRIVER_VERSION; - break; - - case OID_GEN_DRIVER_VERSION: - // - // Specify the NDIS version in use by the NIC driver. The high - // byte is the major version number; the low byte is the minor - // version number. - // - usInfo = (USHORT) (VBOXNETFLT_MAJOR_NDIS_VERSION<<8) + VBOXNETFLT_MINOR_NDIS_VERSION; - pInfo = (PVOID) &usInfo; - ulInfoLen = sizeof(USHORT); - break; - - case OID_GEN_MAXIMUM_SEND_PACKETS: - // - // If a miniport driver registers a MiniportSendPackets function, - // MiniportQueryInformation will be called with the - // OID_GEN_MAXIMUM_SEND_PACKETS request. The miniport driver must - // respond with the maximum number of packets it is prepared to - // handle on a single send request. The miniport driver should - // pick a maximum that minimizes the number of packets that it - // has to queue internally because it has no resources - // (its device is full). A miniport driver for a bus-master DMA - // NIC should attempt to pick a value that keeps its NIC filled - // under anticipated loads. - // - ulInfo = PACKET_INFO_POOL_SIZE; - break; - - case OID_GEN_MEDIA_CONNECT_STATUS: - // - // Return the connection status of the NIC on the network as one - // of the following system-defined values: NdisMediaStateConnected - // or NdisMediaStateDisconnected. - // -#ifdef VBOXNETADP_REPORT_DISCONNECTED - { - PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt); - bool bNetFltActive; - bool bActive = vboxNetFltWinReferenceAdaptNetFltFromAdapt(pNetFlt, pAdapt, bNetFltActive); - if(bActive && bNetFltActive) - { - ulInfo = NdisMediaStateConnected; - } - else - { - ulInfo = NdisMediaStateDisconnected; - } - - if(bActive) - { - vboxNetFltWinDereferenceAdapt(pAdapt); - } - if(bNetFltActive) - { - vboxNetFltWinDereferenceNetFlt(pNetFlt); - } - else - { - vboxNetFltWinDereferenceModePassThru(pNetFlt); - } - } -#else - ulInfo = NdisMediaStateConnected; -#endif - break; - - case OID_GEN_CURRENT_PACKET_FILTER: - // - // Specify the types of net packets such as directed, broadcast - // multicast, for which a protocol receives indications from a - // NIC driver. After NIC is initialized, a protocol driver - // can send a set OID_GEN_CURRENT_PACKET_FILTER to a non-zero value, - // thereby enabling the miniport driver to indicate receive packets - // to that protocol. - // - ulInfo = ( - NDIS_PACKET_TYPE_BROADCAST - | NDIS_PACKET_TYPE_DIRECTED - | NDIS_PACKET_TYPE_ALL_FUNCTIONAL - | NDIS_PACKET_TYPE_ALL_LOCAL - | NDIS_PACKET_TYPE_GROUP - | NDIS_PACKET_TYPE_MULTICAST - ); - break; - - case OID_PNP_CAPABILITIES: - // - // Return the wake-up capabilities of its NIC. If you return - // NDIS_STATUS_NOT_SUPPORTED, NDIS considers the miniport driver - // to be not Power management aware and doesn't send any power - // or wake-up related queries such as - // OID_PNP_SET_POWER, OID_PNP_QUERY_POWER, - // OID_PNP_ADD_WAKE_UP_PATTERN, OID_PNP_REMOVE_WAKE_UP_PATTERN, - // OID_PNP_ENABLE_WAKE_UP. Here, we are expecting the driver below - // us to do the right thing. - // - RtlZeroMemory (&PMCaps, sizeof(NDIS_PNP_CAPABILITIES)); - ulInfoLen = sizeof (NDIS_PNP_CAPABILITIES); - pInfo = (PVOID) &PMCaps; - PMCaps.WakeUpCapabilities.MinMagicPacketWakeUp = NdisDeviceStateUnspecified; - PMCaps.WakeUpCapabilities.MinPatternWakeUp = NdisDeviceStateUnspecified; - break; - - case OID_PNP_QUERY_POWER: - Status = NDIS_STATUS_SUCCESS; - break; - - // - // Following 4 OIDs are for querying Ethernet Operational - // Characteristics. - // - case OID_802_3_PERMANENT_ADDRESS: - // - // Return the MAC address of the NIC burnt in the hardware. - // - { - PVBOXNETFLTINS pNetFlt = (PADAPT_2_PVBOXNETFLTINS(pAdapt)); - pInfo = &pNetFlt->u.s.MacAddr; - ulInfoLen = VBOXNETADP_ETH_ADDRESS_LENGTH; - } - break; - - case OID_802_3_CURRENT_ADDRESS: - // - // Return the MAC address the NIC is currently programmed to - // use. Note that this address could be different from the - // permanent address as the user can override using - // registry. Read NdisReadNetworkAddress doc for more info. - // - { - PVBOXNETFLTINS pNetFlt = (PADAPT_2_PVBOXNETFLTINS(pAdapt)); - pInfo = &pNetFlt->u.s.MacAddr; - ulInfoLen = VBOXNETADP_ETH_ADDRESS_LENGTH; - } - break; - - case OID_802_3_MAXIMUM_LIST_SIZE: - // - // The maximum number of multicast addresses the NIC driver - // can manage. This list is global for all protocols bound - // to (or above) the NIC. Consequently, a protocol can receive - // NDIS_STATUS_MULTICAST_FULL from the NIC driver when - // attempting to set the multicast address list, even if - // the number of elements in the given list is less than - // the number originally returned for this query. - // - ulInfo = VBOXNETADP_MAX_MCAST_LIST; - break; - - case OID_802_3_MAC_OPTIONS: - // - // A protocol can use this OID to determine features supported - // by the underlying driver such as NDIS_802_3_MAC_OPTION_PRIORITY. - // Return zero indicating that it supports no options. - // - ulInfo = 0; - break; - - // - // Following list consists of both general and Ethernet - // specific statistical OIDs. - // - - case OID_GEN_XMIT_OK: - ulInfo64 = pAdapt->cTxSuccess; - pInfo = &ulInfo64; - if (InformationBufferLength >= sizeof(ULONG64) || - InformationBufferLength == 0) - { - ulInfoLen = sizeof(ULONG64); - } - else - { - ulInfoLen = sizeof(ULONG); - } - // We should always report that 8 bytes are required to keep ndistest happy - *BytesNeeded = sizeof(ULONG64); - break; - - case OID_GEN_RCV_OK: - ulInfo64 = pAdapt->cRxSuccess; - pInfo = &ulInfo64; - if (InformationBufferLength >= sizeof(ULONG64) || - InformationBufferLength == 0) - { - ulInfoLen = sizeof(ULONG64); - } - else - { - ulInfoLen = sizeof(ULONG); - } - // We should always report that 8 bytes are required to keep ndistest happy - *BytesNeeded = sizeof(ULONG64); - break; - - case OID_GEN_XMIT_ERROR: - - ulInfo = pAdapt->cTxError; - break; - - case OID_GEN_RCV_ERROR: - ulInfo = pAdapt->cRxError; - break; - - case OID_GEN_RCV_NO_BUFFER: - ulInfo = 0; - break; - - case OID_GEN_RCV_CRC_ERROR: - ulInfo = 0; - break; - - case OID_GEN_TRANSMIT_QUEUE_LENGTH: - ulInfo = PACKET_INFO_POOL_SIZE; - break; - - case OID_802_3_RCV_ERROR_ALIGNMENT: - ulInfo = 0; - break; - - case OID_802_3_XMIT_ONE_COLLISION: - ulInfo = 0; - break; - - case OID_802_3_XMIT_MORE_COLLISIONS: - ulInfo = 0; - break; - - case OID_802_3_XMIT_DEFERRED: - ulInfo = 0; - break; - - case OID_802_3_XMIT_MAX_COLLISIONS: - ulInfo = 0; - break; - - case OID_802_3_RCV_OVERRUN: - ulInfo = 0; - break; - - case OID_802_3_XMIT_UNDERRUN: - ulInfo = 0; - break; - - case OID_802_3_XMIT_HEARTBEAT_FAILURE: - ulInfo = 0; - break; - - case OID_802_3_XMIT_TIMES_CRS_LOST: - ulInfo = 0; - break; - - case OID_802_3_XMIT_LATE_COLLISIONS: - ulInfo = 0; - break; - - default: - Status = NDIS_STATUS_NOT_SUPPORTED; - break; - } - - if(Status == NDIS_STATUS_SUCCESS) - { - if(ulInfoLen <= InformationBufferLength) - { - // Copy result into InformationBuffer - *BytesWritten = ulInfoLen; - if(ulInfoLen) - { - NdisMoveMemory(InformationBuffer, pInfo, ulInfoLen); - } - } - else - { - // too short - *BytesNeeded = ulInfoLen; - Status = NDIS_STATUS_BUFFER_TOO_SHORT; - } - } - - - LogFlow(("<== vboxNetFltWinMpQueryInformation Status = 0x%08x\n", - Status)); - - return(Status); -} - -NDIS_STATUS -vboxNetFltWinMpSetMulticastList( - IN PADAPT pAdapt, - IN PVOID InformationBuffer, - IN ULONG InformationBufferLength, - OUT PULONG pBytesRead, - OUT PULONG pBytesNeeded - ) -/*++ -Routine Description: - This routine will set up the adapter for a specified multicast - address list. - -Arguments: - IN PMP_ADAPTER Adapter - Pointer to adapter block - InformationBuffer - Buffer for information - InformationBufferLength Size of this buffer - pBytesRead Specifies how much info is read - BytesNeeded In case the buffer is smaller than - -Return Value: - - NDIS_STATUS - ---*/ -{ - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; -#if 0 - ULONG index; -#endif - - LogFlow(("==> vboxNetFltWinMpSetMulticastList\n")); - - // - // Initialize. - // - *pBytesNeeded = 0; - *pBytesRead = InformationBufferLength; - - do - { - if (InformationBufferLength % VBOXNETADP_ETH_ADDRESS_LENGTH) - { - Status = NDIS_STATUS_INVALID_LENGTH; - break; - } - - if (InformationBufferLength > (VBOXNETADP_MAX_MCAST_LIST * VBOXNETADP_ETH_ADDRESS_LENGTH)) - { - Status = NDIS_STATUS_MULTICAST_FULL; - *pBytesNeeded = VBOXNETADP_MAX_MCAST_LIST * VBOXNETADP_ETH_ADDRESS_LENGTH; - break; - } -#if 0 - // - // Protect the list update with a lock if it can be updated by - // another thread simultaneously. - // - - NdisZeroMemory(pAdapt->aMCList, - sizeof(pAdapt->aMCList)); - - NdisMoveMemory(pAdapt->aMCList, - InformationBuffer, - InformationBufferLength); - - pAdapt->cMCList = InformationBufferLength / ETH_LENGTH_OF_ADDRESS; -#endif - - } - while (FALSE); - - // - // Program the hardware to add support for these multicast addresses - // - - LogFlow(("<== vboxNetFltWinMpSetMulticastList\n")); - - return(Status); - -} - - -static NDIS_STATUS -vboxNetFltWinMpSetInformation( - IN NDIS_HANDLE MiniportAdapterContext, - IN NDIS_OID Oid, - IN PVOID InformationBuffer, - IN ULONG InformationBufferLength, - OUT PULONG BytesRead, - OUT PULONG BytesNeeded) -/*++ - -Routine Description: - - This is the handler for an OID set operation. - MiniportSetInformation runs at IRQL = DISPATCH_LEVEL. - -Arguments: - - MiniportAdapterContext Pointer to the adapter structure - Oid Oid for this query - InformationBuffer Buffer for information - InformationBufferLength Size of this buffer - BytesRead Specifies how much info is read - BytesNeeded In case the buffer is smaller than what - we need, tell them how much is needed - -Return Value: - - Return code from the NdisRequest below. - ---*/ -{ - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - PADAPT pAdapt = (PADAPT) MiniportAdapterContext; - PNDIS_PM_PACKET_PATTERN pPmPattern = NULL; - - LogFlow(("==> vboxNetFltWinMpSetInformation %s\n", vboxNetFltWinMpDbgGetOidName(Oid))); - - *BytesRead = 0; - *BytesNeeded = 0; - - switch(Oid) - { - case OID_802_3_MULTICAST_LIST: - // - // Set the multicast address list on the NIC for packet reception. - // The NIC driver can set a limit on the number of multicast - // addresses bound protocol drivers can enable simultaneously. - // NDIS returns NDIS_STATUS_MULTICAST_FULL if a protocol driver - // exceeds this limit or if it specifies an invalid multicast - // address. - // - Status = vboxNetFltWinMpSetMulticastList( - pAdapt, - InformationBuffer, - InformationBufferLength, - BytesRead, - BytesNeeded); - break; - - case OID_GEN_CURRENT_PACKET_FILTER: - // - // Program the hardware to indicate the packets - // of certain filter types. - // - if(InformationBufferLength != sizeof(ULONG)) - { - *BytesNeeded = sizeof(ULONG); - Status = NDIS_STATUS_INVALID_LENGTH; - break; - } - - *BytesRead = InformationBufferLength; - - break; - - case OID_GEN_CURRENT_LOOKAHEAD: - // - // A protocol driver can set a suggested value for the number - // of bytes to be used in its binding; however, the underlying - // NIC driver is never required to limit its indications to - // the value set. - // - if(InformationBufferLength != sizeof(ULONG)){ - *BytesNeeded = sizeof(ULONG); - Status = NDIS_STATUS_INVALID_LENGTH; - break; - } - - break; - - case OID_PNP_SET_POWER: - // - // This OID notifies a miniport driver that its NIC will be - // transitioning to the device power state specified in the - // InformationBuffer. The miniport driver must always return - // NDIS_STATUS_SUCCESS to an OID_PNP_SET_POWER request. An - // OID_PNP_SET_POWER request may or may not be preceded by an - // OID_PNP_QUERY_POWER request. - // - if (InformationBufferLength != sizeof(NDIS_DEVICE_POWER_STATE )) - { - Status = NDIS_STATUS_INVALID_LENGTH; - break; - } - - vboxNetFltWinMpProcessSetPowerOid(&Status, pAdapt, InformationBuffer, InformationBufferLength, BytesRead, BytesNeeded); - break; -/* - case OID_PNP_ADD_WAKE_UP_PATTERN: - // - // This OID is sent by a protocol driver to a miniport driver to - // specify a wake-up pattern. The wake-up pattern, along with its mask, - // is described by an NDIS_PM_PACKET_PATTERN structure. - // - pPmPattern = (PNDIS_PM_PACKET_PATTERN) InformationBuffer; - if (InformationBufferLength < sizeof(NDIS_PM_PACKET_PATTERN)) - { - Status = NDIS_STATUS_BUFFER_TOO_SHORT; - - *BytesNeeded = sizeof(NDIS_PM_PACKET_PATTERN); - break; - } - if (InformationBufferLength < pPmPattern->PatternOffset + pPmPattern->PatternSize) - { - Status = NDIS_STATUS_BUFFER_TOO_SHORT; - - *BytesNeeded = pPmPattern->PatternOffset + pPmPattern->PatternSize; - break; - } - *BytesRead = pPmPattern->PatternOffset + pPmPattern->PatternSize; - Status = NDIS_STATUS_SUCCESS; - bForwardRequest = TRUE; - break; - - case OID_PNP_REMOVE_WAKE_UP_PATTERN: - // - // This OID requests the miniport driver to delete a wake-up pattern - // that it previously received in an OID_PNP_ADD_WAKE_UP_PATTERN request. - // The wake-up pattern, along with its mask, is described by an - // NDIS_PM_PACKET_PATTERN structure. - // - pPmPattern = (PNDIS_PM_PACKET_PATTERN) InformationBuffer; - if (InformationBufferLength < sizeof(NDIS_PM_PACKET_PATTERN)) - { - Status = NDIS_STATUS_BUFFER_TOO_SHORT; - - *BytesNeeded = sizeof(NDIS_PM_PACKET_PATTERN); - break; - } - if (InformationBufferLength < pPmPattern->PatternOffset + pPmPattern->PatternSize) - { - Status = NDIS_STATUS_BUFFER_TOO_SHORT; - - *BytesNeeded = pPmPattern->PatternOffset + pPmPattern->PatternSize; - break; - } - *BytesRead = pPmPattern->PatternOffset + pPmPattern->PatternSize; - Status = NDIS_STATUS_SUCCESS; - bForwardRequest = TRUE; - - break; - - case OID_PNP_ENABLE_WAKE_UP: - // - // This OID specifies which wake-up capabilities a miniport - // driver should enable in its NIC. Before the miniport - // transitions to a low-power state (that is, before NDIS - // sends the miniport driver an OID_PNP_SET_POWER request), - // NDIS sends the miniport an OID_PNP_ENABLE_WAKE_UP request to - // enable the appropriate wake-up capabilities. - // - DEBUGP(MP_INFO, ("--> OID_PNP_ENABLE_WAKE_UP\n")); - if(InformationBufferLength != sizeof(ULONG)) - { - *BytesNeeded = sizeof(ULONG); - Status = NDIS_STATUS_INVALID_LENGTH; - break; - } - *BytesRead = sizeof(ULONG); - Status = NDIS_STATUS_SUCCESS; - bForwardRequest = TRUE; - break; -*/ - default: - Status = NDIS_STATUS_INVALID_OID; - break; - - } - - - LogFlow(("<== vboxNetFltWinMpSetInformation Status = 0x%08x\n", Status)); - - return(Status); -} - -static PUCHAR vboxNetFltWinMpDbgGetOidName(ULONG oid) -{ - PCHAR oidName; - - switch (oid){ - - #undef MAKECASE - #define MAKECASE(oidx) case oidx: oidName = #oidx; break; - - MAKECASE(OID_GEN_SUPPORTED_LIST) - MAKECASE(OID_GEN_HARDWARE_STATUS) - MAKECASE(OID_GEN_MEDIA_SUPPORTED) - MAKECASE(OID_GEN_MEDIA_IN_USE) - MAKECASE(OID_GEN_MAXIMUM_LOOKAHEAD) - MAKECASE(OID_GEN_MAXIMUM_FRAME_SIZE) - MAKECASE(OID_GEN_LINK_SPEED) - MAKECASE(OID_GEN_TRANSMIT_BUFFER_SPACE) - MAKECASE(OID_GEN_RECEIVE_BUFFER_SPACE) - MAKECASE(OID_GEN_TRANSMIT_BLOCK_SIZE) - MAKECASE(OID_GEN_RECEIVE_BLOCK_SIZE) - MAKECASE(OID_GEN_VENDOR_ID) - MAKECASE(OID_GEN_VENDOR_DESCRIPTION) - MAKECASE(OID_GEN_CURRENT_PACKET_FILTER) - MAKECASE(OID_GEN_CURRENT_LOOKAHEAD) - MAKECASE(OID_GEN_DRIVER_VERSION) - MAKECASE(OID_GEN_MAXIMUM_TOTAL_SIZE) - MAKECASE(OID_GEN_PROTOCOL_OPTIONS) - MAKECASE(OID_GEN_MAC_OPTIONS) - MAKECASE(OID_GEN_MEDIA_CONNECT_STATUS) - MAKECASE(OID_GEN_MAXIMUM_SEND_PACKETS) - MAKECASE(OID_GEN_VENDOR_DRIVER_VERSION) - MAKECASE(OID_GEN_SUPPORTED_GUIDS) - MAKECASE(OID_GEN_NETWORK_LAYER_ADDRESSES) - MAKECASE(OID_GEN_TRANSPORT_HEADER_OFFSET) - MAKECASE(OID_GEN_MEDIA_CAPABILITIES) - MAKECASE(OID_GEN_PHYSICAL_MEDIUM) - MAKECASE(OID_GEN_XMIT_OK) - MAKECASE(OID_GEN_RCV_OK) - MAKECASE(OID_GEN_XMIT_ERROR) - MAKECASE(OID_GEN_RCV_ERROR) - MAKECASE(OID_GEN_RCV_NO_BUFFER) - MAKECASE(OID_GEN_DIRECTED_BYTES_XMIT) - MAKECASE(OID_GEN_DIRECTED_FRAMES_XMIT) - MAKECASE(OID_GEN_MULTICAST_BYTES_XMIT) - MAKECASE(OID_GEN_MULTICAST_FRAMES_XMIT) - MAKECASE(OID_GEN_BROADCAST_BYTES_XMIT) - MAKECASE(OID_GEN_BROADCAST_FRAMES_XMIT) - MAKECASE(OID_GEN_DIRECTED_BYTES_RCV) - MAKECASE(OID_GEN_DIRECTED_FRAMES_RCV) - MAKECASE(OID_GEN_MULTICAST_BYTES_RCV) - MAKECASE(OID_GEN_MULTICAST_FRAMES_RCV) - MAKECASE(OID_GEN_BROADCAST_BYTES_RCV) - MAKECASE(OID_GEN_BROADCAST_FRAMES_RCV) - MAKECASE(OID_GEN_RCV_CRC_ERROR) - MAKECASE(OID_GEN_TRANSMIT_QUEUE_LENGTH) - MAKECASE(OID_GEN_GET_TIME_CAPS) - MAKECASE(OID_GEN_GET_NETCARD_TIME) - MAKECASE(OID_GEN_NETCARD_LOAD) - MAKECASE(OID_GEN_DEVICE_PROFILE) - MAKECASE(OID_GEN_INIT_TIME_MS) - MAKECASE(OID_GEN_RESET_COUNTS) - MAKECASE(OID_GEN_MEDIA_SENSE_COUNTS) - MAKECASE(OID_PNP_CAPABILITIES) - MAKECASE(OID_PNP_SET_POWER) - MAKECASE(OID_PNP_QUERY_POWER) - MAKECASE(OID_PNP_ADD_WAKE_UP_PATTERN) - MAKECASE(OID_PNP_REMOVE_WAKE_UP_PATTERN) - MAKECASE(OID_PNP_ENABLE_WAKE_UP) - MAKECASE(OID_802_3_PERMANENT_ADDRESS) - MAKECASE(OID_802_3_CURRENT_ADDRESS) - MAKECASE(OID_802_3_MULTICAST_LIST) - MAKECASE(OID_802_3_MAXIMUM_LIST_SIZE) - MAKECASE(OID_802_3_MAC_OPTIONS) - MAKECASE(OID_802_3_RCV_ERROR_ALIGNMENT) - MAKECASE(OID_802_3_XMIT_ONE_COLLISION) - MAKECASE(OID_802_3_XMIT_MORE_COLLISIONS) - MAKECASE(OID_802_3_XMIT_DEFERRED) - MAKECASE(OID_802_3_XMIT_MAX_COLLISIONS) - MAKECASE(OID_802_3_RCV_OVERRUN) - MAKECASE(OID_802_3_XMIT_UNDERRUN) - MAKECASE(OID_802_3_XMIT_HEARTBEAT_FAILURE) - MAKECASE(OID_802_3_XMIT_TIMES_CRS_LOST) - MAKECASE(OID_802_3_XMIT_LATE_COLLISIONS) - - default: - oidName = "<** UNKNOWN OID **>"; - break; - } - - return oidName; -} -#endif - -/** - * NDIS Miniport entry point called whenever protocols are done with - * a packet that we had indicated up and they had queued up for returning - * later. - * - * @param MiniportAdapterContext - pointer to ADAPT structure - * @param Packet - packet being returned. - * @return None. */ -DECLHIDDEN(VOID) -vboxNetFltWinMpReturnPacket( - IN NDIS_HANDLE MiniportAdapterContext, - IN PNDIS_PACKET Packet - ) -{ - PADAPT pAdapt = (PADAPT)MiniportAdapterContext; - - { - /* - * This is a packet allocated from this IM's receive packet pool. - * Reclaim our packet, and return the original to the driver below. - */ - - PNDIS_PACKET MyPacket; - PRECV_RSVD RecvRsvd; - - RecvRsvd = (PRECV_RSVD)(Packet->MiniportReserved); - MyPacket = RecvRsvd->pOriginalPkt; - - if(MyPacket) - { - /* the packet was sent from underlying miniport */ - NdisFreePacket(Packet); - NdisReturnPackets(&MyPacket, 1); - } - else - { - PVOID pBufToFree = RecvRsvd->pBufToFree; - - /* the packet was sent from NetFlt */ - vboxNetFltWinFreeSGNdisPacket(Packet, !pBufToFree); - if(pBufToFree) - { - vboxNetFltWinMemFree(pBufToFree); - } - } - - vboxNetFltWinDereferenceAdapt(pAdapt); - } -} - -/** Miniport's transfer data handler. - * - * @param Packet Destination packet - * @param BytesTransferred Place-holder for how much data was copied - * @param MiniportAdapterContext Pointer to the adapter structure - * @param MiniportReceiveContext Context - * @param ByteOffset Offset into the packet for copying data - * @param BytesToTransfer How much to copy. - * @return Status of transfer */ -static NDIS_STATUS -vboxNetFltWinMpTransferData( - OUT PNDIS_PACKET Packet, - OUT PUINT BytesTransferred, - IN NDIS_HANDLE MiniportAdapterContext, - IN NDIS_HANDLE MiniportReceiveContext, - IN UINT ByteOffset, - IN UINT BytesToTransfer - ) -{ -#ifndef VBOXNETADP - - PADAPT pAdapt = (PADAPT)MiniportAdapterContext; - NDIS_STATUS Status; - - /* - * Return, if the device is OFF - */ - if (vboxNetFltWinGetPowerState(&pAdapt->PTState) != NdisDeviceStateD0 - || vboxNetFltWinGetPowerState(&pAdapt->MPState) != NdisDeviceStateD0) - { - return NDIS_STATUS_FAILURE; - } - - NdisTransferData(&Status, - pAdapt->hBindingHandle, - MiniportReceiveContext, - ByteOffset, - BytesToTransfer, - Packet, - BytesTransferred); - - return(Status); -#else - /* should never be here */ - Assert(0); - return NDIS_STATUS_FAILURE; -#endif -} - -/** - * Halt handler. All the hard-work for clean-up is done here. - * - * @param MiniportAdapterContext Pointer to the Adapter - * @return None. */ -static VOID -vboxNetFltWinMpHalt( - IN NDIS_HANDLE MiniportAdapterContext - ) -{ - PADAPT pAdapt = (PADAPT)MiniportAdapterContext; -#ifndef VBOXNETADP - NDIS_STATUS Status; -#endif - - LogFlow(("==>MiniportHalt: Adapt %p\n", pAdapt)); - -#ifndef VBOXNETADP -// Assert(vboxNetFltWinGetOpState(&pAdapt->PTState) == kVBoxNetDevOpState_Deinitializing); -// if(vboxNetFltWinGetOpState(&pAdapt->PTState) == kVBoxNetDevOpState_Deinitializing) - if(vboxNetFltWinGetAdaptState(pAdapt) == kVBoxAdaptState_Disconnecting) - { - Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitializing); - vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitializing); - /* we're called from protocolUnbinAdapter, do our job */ - /* - * If we have a valid bind, close the miniport below the protocol - */ - vboxNetFltWinPtCloseAdapter(pAdapt, &Status); - - Assert(vboxNetFltWinGetOpState(&pAdapt->PTState) == kVBoxNetDevOpState_Deinitializing); - vboxNetFltWinSetOpState(&pAdapt->PTState, kVBoxNetDevOpState_Deinitialized); - vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized); - } - else -#endif - { - /* we're NOT called from protocolUnbinAdapter, perform a full disconnect */ - NDIS_STATUS Status; - - Assert(/*vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Initializing - ||*/ vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Initialized); -#ifndef VBOXNETADP - AssertBreakpoint(); -#endif - Status = vboxNetFltWinDetachFromInterface(pAdapt, false); - Assert(Status == NDIS_STATUS_SUCCESS); -/* you can not access the pAdapt after closure - Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitialized); - vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized); -#ifndef VBOXNETADP - Assert(vboxNetFltWinGetOpState(&pAdapt->PTState) == kVBoxNetDevOpState_Deinitialized); - vboxNetFltWinSetOpState(&pAdapt->PTState, kVBoxNetDevOpState_Deinitialized); -#endif -*/ - } - - LogFlow(("<== MiniportHalt: pAdapt %p\n", pAdapt)); -} - -/** - * register the miniport edge - */ -DECLHIDDEN(NDIS_STATUS) -vboxNetFltWinMpRegister( - IN PDRIVER_OBJECT DriverObject, - IN PUNICODE_STRING RegistryPath - ) -{ - NDIS_MINIPORT_CHARACTERISTICS MChars; - NDIS_STATUS Status; - - NdisMInitializeWrapper(&g_hNdisWrapperHandle, DriverObject, RegistryPath, NULL); - - /* - * Register the miniport with NDIS. Note that it is the miniport - * which was started as a driver and not the protocol. Also the miniport - * must be registered prior to the protocol since the protocol's BindAdapter - * handler can be initiated anytime and when it is, it must be ready to - * start driver instances. - */ - - NdisZeroMemory(&MChars, sizeof(NDIS_MINIPORT_CHARACTERISTICS)); - - MChars.MajorNdisVersion = VBOXNETFLT_MAJOR_NDIS_VERSION; - MChars.MinorNdisVersion = VBOXNETFLT_MINOR_NDIS_VERSION; - - MChars.InitializeHandler = vboxNetFltWinMpInitialize; - MChars.QueryInformationHandler = vboxNetFltWinMpQueryInformation; - MChars.SetInformationHandler = vboxNetFltWinMpSetInformation; - MChars.ResetHandler = NULL; - MChars.TransferDataHandler = vboxNetFltWinMpTransferData; - MChars.HaltHandler = vboxNetFltWinMpHalt; - - /* - * We will disable the check for hang timeout so we do not - * need a check for hang handler! - */ - MChars.CheckForHangHandler = NULL; - MChars.ReturnPacketHandler = vboxNetFltWinMpReturnPacket; - - /* - * Either the Send or the SendPackets handler should be specified. - * If SendPackets handler is specified, SendHandler is ignored - */ - MChars.SendHandler = NULL; /* vboxNetFltWinMpSend; */ - MChars.SendPacketsHandler = vboxNetFltWinMpSendPackets; - -#ifndef VBOXNETADP - Status = NdisIMRegisterLayeredMiniport(g_hNdisWrapperHandle, - &MChars, - sizeof(MChars), - &g_hDriverHandle); -#else - Status = NdisMRegisterMiniport( - g_hNdisWrapperHandle, - &MChars, - sizeof(MChars)); -#endif - if(Status == NDIS_STATUS_SUCCESS) - { -# ifndef WIN9X - NdisMRegisterUnloadHandler(g_hNdisWrapperHandle, vboxNetFltWinUnload); -# endif - } - - return Status; -} - -/** - * deregister the miniport edge - */ -DECLHIDDEN(NDIS_STATUS) -vboxNetFltWinMpDeregister() -{ -#ifndef VBOXNETADP - NdisIMDeregisterLayeredMiniport(g_hDriverHandle); -#else - /* don't need to do anything here */ -#endif - NdisTerminateWrapper(g_hNdisWrapperHandle, NULL); - return NDIS_STATUS_SUCCESS; -} - -#ifndef VBOXNETADP -/** - * return the miniport edge handle - */ -DECLHIDDEN(NDIS_HANDLE) vboxNetFltWinMpGetHandle() -{ - return g_hDriverHandle; -} - -/** - * initialize the instance of a device used for ioctl handling - */ -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpInitializeDevideInstance(PADAPT pAdapt) -{ - NDIS_STATUS Status; - /* - * Now ask NDIS to initialize our miniport (upper) edge. - * Set the flag below to synchronize with a possible call - * to our protocol Unbind handler that may come in before - * our miniport initialization happens. - */ - Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitialized); - vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Initializing); - /* this is doe in vboxNetFltWinPtInitPADAPT*/ - /* NdisInitializeEvent(&pAdapt->MiniportInitEvent); */ - - Status = NdisIMInitializeDeviceInstanceEx(g_hDriverHandle, - &pAdapt->DeviceName, - pAdapt); - /* ensure we're taking into account the pAdapt->Status if our miniport halt handler was called */ - if(Status == NDIS_STATUS_SUCCESS) - { - if(pAdapt->Status == NDIS_STATUS_SUCCESS) - { -// Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Initialized); -// vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Initialized); - return NDIS_STATUS_SUCCESS; - } - AssertBreakpoint(); - vboxNetFltWinMpDeInitializeDevideInstance(pAdapt, &Status); - Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitialized); - vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized); - return pAdapt->Status; - } - else - { - Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitialized); - vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized); - } - return Status; -} - -/** - * deinitialize the instance of a device used for ioctl handling - */ -DECLHIDDEN(bool) vboxNetFltWinMpDeInitializeDevideInstance(PADAPT pAdapt, PNDIS_STATUS pStatus) -{ -# ifndef WIN9X - NDIS_STATUS LocalStatus; - /* - * Check if we had called NdisIMInitializeDeviceInstanceEx and - * we are awaiting a call to MiniportInitialize. - */ - if (vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Initializing) - { - /* - * Try to cancel the pending IMInit process. - */ - LocalStatus = NdisIMCancelInitializeDeviceInstance( - g_hDriverHandle, - &pAdapt->DeviceName); - - if (LocalStatus == NDIS_STATUS_SUCCESS) - { - /* - * Successfully cancelled IM Initialization; our - * Miniport Initialize routine will not be called - * for this device. - */ - Assert(pAdapt->hMiniportHandle == NULL); - } - else - { - /* - * Our Miniport Initialize routine will be called - * (may be running on another thread at this time). - * Wait for it to finish. - */ - NdisWaitEvent(&pAdapt->MiniportInitEvent, 0); - } - - vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized); - } -#endif - - /* - * Call NDIS to remove our device-instance. We do most of the work - * inside the HaltHandler. - * - * The Handle will be NULL if our miniport Halt Handler has been called or - * if the IM device was never initialized - */ - - if (vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Initialized) - { - vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitializing); - - *pStatus = NdisIMDeInitializeDeviceInstance(pAdapt->hMiniportHandle); - - vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized); - - if (*pStatus != NDIS_STATUS_SUCCESS) - { - *pStatus = NDIS_STATUS_FAILURE; - } - - return true; - } - - vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized); - - return false; -} -#endif - -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpReferenceControlDevice() -{ - return vboxNetFltWinPtRegisterDevice(); -} - -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpDereferenceControlDevice() -{ - return vboxNetFltWinPtDeregisterDevice(); -} - -#endif /* #ifndef VBOX_NETFLT_ONDEMAND_BIND*/ diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltMp-win.h b/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltMp-win.h deleted file mode 100644 index 9b121a56e..000000000 --- a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltMp-win.h +++ /dev/null @@ -1,46 +0,0 @@ -/* $Id: VBoxNetFltMp-win.h $ */ -/** @file - * VBoxNetFlt - Network Filter Driver (Host), Windows Specific Code. Miniport edge of ndis filter driver - */ - -/* - * Copyright (C) 2008 Oracle Corporation - * - * This file is part of VirtualBox Open Source Edition (OSE), as - * available from http://www.virtualbox.org. This file is free software; - * you can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) as published by the Free Software - * Foundation, in version 2 as it comes in the "COPYING" file of the - * VirtualBox OSE distribution. VirtualBox OSE is distributed in the - * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. - */ -/* - * Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample. - * Copyright (c) 1993-1999, Microsoft Corporation - */ - -#ifndef ___VBoxNetFltMp_win_h___ -#define ___VBoxNetFltMp_win_h___ - - #ifdef VBOX_NETFLT_ONDEMAND_BIND - # error "unsupported (VBOX_NETFLT_ONDEMAND_BIND)" - #else - -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpRegister(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath); -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpDeregister(); -DECLHIDDEN(NDIS_HANDLE) vboxNetFltWinMpGetHandle(); -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpInitializeDevideInstance(PADAPT pAdapt); -DECLHIDDEN(VOID) vboxNetFltWinMpReturnPacket(IN NDIS_HANDLE MiniportAdapterContext, IN PNDIS_PACKET Packet); -DECLHIDDEN(bool) vboxNetFltWinMpDeInitializeDevideInstance(PADAPT pAdapt, PNDIS_STATUS pStatus); -DECLHIDDEN(VOID) vboxNetFltWinMpQueryPNPCapabilities(IN OUT PADAPT pAdapt, OUT PNDIS_STATUS pStatus); -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpReferenceControlDevice(); -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpDereferenceControlDevice(); - - #ifdef VBOXNETADP -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpDoInitialization(PADAPT pAdapt, NDIS_HANDLE hMiniportAdapter, NDIS_HANDLE hWrapperConfigurationContext); -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpDoDeinitialization(PADAPT pAdapt); - #endif - - #endif - -#endif diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltPt-win.c b/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltPt-win.c deleted file mode 100644 index 983ca638d..000000000 --- a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltPt-win.c +++ /dev/null @@ -1,2512 +0,0 @@ -/* $Id: VBoxNetFltPt-win.c $ */ -/** @file - * VBoxNetFlt - Network Filter Driver (Host), Windows Specific Code. Protocol edge of ndis filter driver - */ - -/* - * Copyright (C) 2008 Oracle Corporation - * - * This file is part of VirtualBox Open Source Edition (OSE), as - * available from http://www.virtualbox.org. This file is free software; - * you can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) as published by the Free Software - * Foundation, in version 2 as it comes in the "COPYING" file of the - * VirtualBox OSE distribution. VirtualBox OSE is distributed in the - * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. - */ -/* - * Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample. - * Copyright (c) 1993-1999, Microsoft Corporation - */ - -#include "VBoxNetFltCommon-win.h" - -#ifdef VBOXNETADP -# error "No protocol edge" -#endif - -/** protocol handle */ -static NDIS_HANDLE g_hProtHandle = NULL; -/** medium array used while opening underlying adaptor - * we are actually binding to NdisMedium802_3 and NdisMediumWan - * as specified in VBoxNetFlt.inf: - * HKR, Ndi\Interfaces, FilterMediaTypes, , "ethernet, wan" */ -static NDIS_MEDIUM g_aMediumArray[] = - { - /* Ethernet */ - NdisMedium802_3, - /* Wan */ - NdisMediumWan - }; - -/** - * performs binding to the given adapter - */ -#ifdef VBOX_NETFLT_ONDEMAND_BIND -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtDoBinding(IN PADAPT pAdapt) -#else -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtDoBinding(IN PADAPT pAdapt, IN PNDIS_STRING pOurDeviceName, IN PNDIS_STRING pBindToDeviceName) -#endif -{ - UINT MediumIndex; - NDIS_STATUS Status, Sts; - - Assert(pAdapt->PTState.PowerState == NdisDeviceStateD3); - Assert(pAdapt->PTState.OpState == kVBoxNetDevOpState_Deinitialized); - Assert(KeGetCurrentIrql() == PASSIVE_LEVEL); - - vboxNetFltWinSetOpState(&pAdapt->PTState, kVBoxNetDevOpState_Initializing); - - do - { -// NDIS_STATUS TmpStatus; - /* copy the bind to dev name to our buffer */ -#ifdef VBOX_NETFLT_ONDEMAND_BIND - NDIS_STRING BindToDeviceName; - PNDIS_STRING pBindToDeviceName; - PVBOXNETFLTINS pThis = PADAPT_2_PVBOXNETFLTINS(pAdapt); - PWSTR pUnicode; - ULONG cbUnicode; - ANSI_STRING AnsiStr; - - /* most Rtlxx functions we are using here require this */ - Assert(KeGetCurrentIrql() == PASSIVE_LEVEL); - - RtlInitAnsiString(&AnsiStr, pThis->szName); - cbUnicode = RtlAnsiStringToUnicodeSize(&AnsiStr); - - pUnicode = alloca(cbUnicode); - BindToDeviceName.Buffer = pUnicode; - BindToDeviceName.MaximumLength = (USHORT)cbUnicode; - - Status = RtlAnsiStringToUnicodeString(&BindToDeviceName, &AnsiStr, FALSE); - if(!NT_SUCCESS(Status)) - { - Assert(0); - break; - } - - pBindToDeviceName = &BindToDeviceName; -#else - Status = vboxNetFltWinCopyString(&pAdapt->DeviceName, pOurDeviceName); - if(Status != NDIS_STATUS_SUCCESS) - { - Assert(0); - break; - } -#endif - - vboxNetFltWinSetPowerState(&pAdapt->PTState, NdisDeviceStateD0); - pAdapt->Status = NDIS_STATUS_SUCCESS; - - NdisResetEvent(&pAdapt->hEvent); - - /* - * Now open the adapter below and complete the initialization - */ - NdisOpenAdapter(&Status, - &Sts, - &pAdapt->hBindingHandle, - &MediumIndex, - g_aMediumArray, - sizeof(g_aMediumArray)/sizeof(NDIS_MEDIUM), - g_hProtHandle, - pAdapt, - pBindToDeviceName, - 0, - NULL); - - if (Status == NDIS_STATUS_PENDING) - { - NdisWaitEvent(&pAdapt->hEvent, 0); - Status = pAdapt->Status; - } - - Assert(Status == NDIS_STATUS_SUCCESS); - if(Status != NDIS_STATUS_SUCCESS) - { - vboxNetFltWinSetOpState(&pAdapt->PTState, kVBoxNetDevOpState_Deinitialized); - pAdapt->hBindingHandle = NULL; - LogRel(("NdisOpenAdapter failed, Status (0c%x)", Status)); - break; - } - - Assert(pAdapt->hBindingHandle); - - pAdapt->Medium = g_aMediumArray[MediumIndex]; - vboxNetFltWinSetOpState(&pAdapt->PTState, kVBoxNetDevOpState_Initialized); - -#ifndef VBOX_NETFLT_ONDEMAND_BIND - Status = vboxNetFltWinMpInitializeDevideInstance(pAdapt); - if (Status != NDIS_STATUS_SUCCESS) - { - Log(("BindAdapter: Adapt %p, IMInitializeDeviceInstance error %x\n", - pAdapt, Status)); - - vboxNetFltWinSetOpState(&pAdapt->PTState, kVBoxNetDevOpState_Deinitializing); - vboxNetFltWinPtCloseAdapter(pAdapt, &Sts); - vboxNetFltWinSetOpState(&pAdapt->PTState, kVBoxNetDevOpState_Deinitialized); - break; - } -#endif - } while(0); - - return Status; -} - -/** - * Called by NDIS to bind to a miniport below. - * @param Status - Return status of bind here. - * @param BindContext - Can be passed to NdisCompleteBindAdapter if this call is pended. - * @param DeviceName - Device name to bind to. This is passed to NdisOpenAdapter. - * @param SystemSpecific1 - Can be passed to NdisOpenProtocolConfiguration to read per-binding information - * @param SystemSpecific2 - Unused - * @return NDIS_STATUS_PENDING if this call is pended. In this case call NdisCompleteBindAdapter to complete. - * Anything else Completes this call synchronously */ -static VOID -vboxNetFltWinPtBindAdapter( - OUT PNDIS_STATUS pStatus, - IN NDIS_HANDLE BindContext, - IN PNDIS_STRING pDeviceName, - IN PVOID SystemSpecific1, - IN PVOID SystemSpecific2 - ) -{ -#ifdef VBOX_NETFLT_ONDEMAND_BIND - /* we initiate the binding ourselves by calling NdisOpenAdapter */ - LogFlow(("==> Protocol BindAdapter\n")); - Assert(0); - *pStatus = NDIS_STATUS_OPEN_FAILED; - LogFlow(("<== Protocol BindAdapter\n")); - return; -#else - NDIS_HANDLE ConfigHandle = NULL; - PNDIS_CONFIGURATION_PARAMETER Param; - NDIS_STRING DeviceStr = NDIS_STRING_CONST("UpperBindings"); - PADAPT pAdapt = NULL; - - UNREFERENCED_PARAMETER(BindContext); - UNREFERENCED_PARAMETER(SystemSpecific2); - - LogFlow(("==> Protocol BindAdapter\n")); - - do - { - /* Access the configuration section for our binding-specific - * parameters. */ - - NdisOpenProtocolConfiguration(pStatus, - &ConfigHandle, - (PNDIS_STRING)SystemSpecific1); - - if (*pStatus != NDIS_STATUS_SUCCESS) - { - break; - } - - /* Read the "UpperBindings" reserved key that contains a list - * of device names representing our miniport instances corresponding - * to this lower binding. Since this is a 1:1 IM driver, this key - * contains exactly one name. - * - * If we want to implement a N:1 mux driver (N adapter instances - * over a single lower binding), then UpperBindings will be a - * MULTI_SZ containing a list of device names - we would loop through - * this list, calling NdisIMInitializeDeviceInstanceEx once for - * each name in it. */ - - NdisReadConfiguration(pStatus, - &Param, - ConfigHandle, - &DeviceStr, - NdisParameterString); - if (*pStatus != NDIS_STATUS_SUCCESS) - { - break; - } - - *pStatus = vboxNetFltWinPtInitBind(&pAdapt, &Param->ParameterData.StringData, pDeviceName); - if (*pStatus != NDIS_STATUS_SUCCESS) - { - break; - } - } while(FALSE); - - /* - * Close the configuration handle now - see comments above with - * the call to NdisIMInitializeDeviceInstanceEx. - */ - if (ConfigHandle != NULL) - { - NdisCloseConfiguration(ConfigHandle); - } - - LogFlow(("<== Protocol BindAdapter: pAdapt %p, Status %x\n", pAdapt, *pStatus)); -#endif -} - -/** - * Completion routine for NdisOpenAdapter issued from within the vboxNetFltWinPtBindAdapter. Simply - * unblock the caller. - * - * @param ProtocolBindingContext Pointer to the adapter - * @param Status Status of the NdisOpenAdapter call - * @param OpenErrorStatus Secondary status(ignored by us). - * @return None - * */ -static VOID -vboxNetFltWinPtOpenAdapterComplete( - IN NDIS_HANDLE ProtocolBindingContext, - IN NDIS_STATUS Status, - IN NDIS_STATUS OpenErrorStatus - ) -{ - PADAPT pAdapt =(PADAPT)ProtocolBindingContext; - - UNREFERENCED_PARAMETER(OpenErrorStatus); - - LogFlow(("==> vboxNetFltWinPtOpenAdapterComplete: Adapt %p, Status %x\n", pAdapt, Status)); - if(pAdapt->Status == NDIS_STATUS_SUCCESS) - { - pAdapt->Status = Status; - } - NdisSetEvent(&pAdapt->hEvent); -} - -DECLHIDDEN(NDIS_STATUS) -vboxNetFltWinPtDoUnbinding(PADAPT pAdapt, bool bOnUnbind) -{ - NDIS_STATUS Status; -#ifndef VBOX_NETFLT_ONDEMAND_BIND - PNDIS_PACKET PacketArray[MAX_RECEIVE_PACKET_ARRAY_SIZE]; - ULONG NumberOfPackets = 0, i; - BOOLEAN CompleteRequest = FALSE; - BOOLEAN ReturnPackets = FALSE; - PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt); - RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; - uint64_t NanoTS = RTTimeSystemNanoTS(); -#endif - int cPPUsage; - - LogFlow(("==> vboxNetFltWinPtDoUnbinding: Adapt %p\n", pAdapt)); - - Assert(KeGetCurrentIrql() == PASSIVE_LEVEL); - -#ifndef VBOX_NETFLT_ONDEMAND_BIND - Assert(vboxNetFltWinGetOpState(&pAdapt->PTState) == kVBoxNetDevOpState_Initialized); - /* - * Set the flag that the miniport below is unbinding, so the request handlers will - * fail any request coming later - */ - RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp); - - ASMAtomicUoWriteBool(&pNetFlt->fDisconnectedFromHost, true); - ASMAtomicUoWriteBool(&pNetFlt->fRediscoveryPending, false); - ASMAtomicUoWriteU64(&pNetFlt->NanoTSLastRediscovery, NanoTS); - -// pAdapt->PTState.DeviceState = NdisDeviceStateD3; -// pAdapt->MPState.DeviceState = NdisDeviceStateD3; - vboxNetFltWinSetOpState(&pAdapt->PTState, kVBoxNetDevOpState_Deinitializing); - if(!bOnUnbind) - { - vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitializing); - } - - if (pAdapt->bQueuedRequest == TRUE) - { - pAdapt->bQueuedRequest = FALSE; - CompleteRequest = TRUE; - } - if (pAdapt->cReceivedPacketCount > 0) - { - - NdisMoveMemory(PacketArray, - pAdapt->aReceivedPackets, - pAdapt->cReceivedPacketCount * sizeof(PNDIS_PACKET)); - - NumberOfPackets = pAdapt->cReceivedPacketCount; - - pAdapt->cReceivedPacketCount = 0; - ReturnPackets = TRUE; - } - - - RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); - - if (CompleteRequest == TRUE) - { - vboxNetFltWinPtRequestComplete(pAdapt, - &pAdapt->Request, - NDIS_STATUS_FAILURE ); - - } - if (ReturnPackets == TRUE) - { - for (i = 0; i < NumberOfPackets; i++) - { - vboxNetFltWinMpReturnPacket(pAdapt, PacketArray[i]); - } - } - - vboxNetFltWinWaitDereference(&pAdapt->MPState); - - vboxNetFltWinWaitDereference(&pAdapt->PTState); - - /* check packet pool is empty */ - cPPUsage = NdisPacketPoolUsage(pAdapt->hSendPacketPoolHandle); - Assert(cPPUsage == 0); - cPPUsage = NdisPacketPoolUsage(pAdapt->hRecvPacketPoolHandle); - Assert(cPPUsage == 0); - /* for debugging only, ignore the err in release */ - NOREF(cPPUsage); - - while (ASMAtomicUoReadBool((volatile bool *)&pAdapt->bOutstandingRequests)) - { - /* - * sleep till outstanding requests complete - */ - vboxNetFltWinSleep(2); - } - - if(!bOnUnbind || !vboxNetFltWinMpDeInitializeDevideInstance(pAdapt, &Status)) -#endif /* #ifndef VBOX_NETFLT_ONDEMAND_BIND */ - { - /* - * We need to do some work here. - * Close the binding below us - * and release the memory allocated. - */ - vboxNetFltWinPtCloseAdapter(pAdapt, &Status); - vboxNetFltWinSetOpState(&pAdapt->PTState, kVBoxNetDevOpState_Deinitialized); - - if(!bOnUnbind) - { - Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitializing); - vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized); - } - else - { - Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitialized); - } - } - else - { - Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitialized); - } - - LogFlow(("<== vboxNetFltWinPtDoUnbinding: Adapt %p\n", pAdapt)); - - return Status; -} - -/** - * Called by NDIS when we are required to unbind to the adapter below. - * This functions shares functionality with the miniport's HaltHandler. - * The code should ensure that NdisCloseAdapter and NdisFreeMemory is called - * only once between the two functions - * - * @param Status Placeholder for return status - * @param ProtocolBindingContext Pointer to the adapter structure - * @param UnbindContext Context for NdisUnbindComplete() if this pends - * @return NONE */ -static VOID -vboxNetFltWinPtUnbindAdapter( - OUT PNDIS_STATUS pStatus, - IN NDIS_HANDLE ProtocolBindingContext, - IN NDIS_HANDLE UnbindContext - ) -{ - PADAPT pAdapt =(PADAPT)ProtocolBindingContext; - PVBOXNETFLTINS pNetFltIf = PADAPT_2_PVBOXNETFLTINS(pAdapt); - - LogFlow(("==> vboxNetFltWinPtUnbindAdapter: Adapt %p\n", pAdapt)); - - *pStatus = vboxNetFltWinDetachFromInterface(pAdapt, true); - Assert(*pStatus == NDIS_STATUS_SUCCESS); - - LogFlow(("<== vboxNetFltWinPtUnbindAdapter: Adapt %p\n", pAdapt)); -} - -/** - * protocol unload handler - */ -static VOID -vboxNetFltWinPtUnloadProtocol( - VOID -) -{ - vboxNetFltWinPtDeregister(); - LogFlow(("vboxNetFltWinPtUnloadProtocol: done!\n")); -} - - -/** - * Completion for the CloseAdapter call. - * - * @param ProtocolBindingContext Pointer to the adapter structure - * @param Status Completion status - * @return None */ -static VOID -vboxNetFltWinPtCloseAdapterComplete( - IN NDIS_HANDLE ProtocolBindingContext, - IN NDIS_STATUS Status - ) -{ - PADAPT pAdapt =(PADAPT)ProtocolBindingContext; - - LogFlow(("CloseAdapterComplete: Adapt %p, Status %x\n", pAdapt, Status)); - if(pAdapt->Status == NDIS_STATUS_SUCCESS) - { - pAdapt->Status = Status; - } - NdisSetEvent(&pAdapt->hEvent); -} - - -/** - * Completion for the reset. - * - * @param ProtocolBindingContext Pointer to the adapter structure - * @param Status Completion status - * @return None */ -static VOID -vboxNetFltWinPtResetComplete( - IN NDIS_HANDLE ProtocolBindingContext, - IN NDIS_STATUS Status - ) -{ - - UNREFERENCED_PARAMETER(ProtocolBindingContext); - UNREFERENCED_PARAMETER(Status); - /* - * We never issue a reset, so we should not be here. - */ - Assert(0); -} - -/** - * Completion handler for the previously posted request. All OIDS - * are completed by and sent to the same miniport that they were requested for. - * If Oid == OID_PNP_QUERY_POWER then the data structure needs to returned with all entries = - * NdisDeviceStateUnspecified - * @param ProtocolBindingContext Pointer to the adapter structure - * @param NdisRequest The posted request - * @param Status Completion status - * @return None - * - */ -DECLHIDDEN(VOID) -vboxNetFltWinPtRequestComplete( - IN NDIS_HANDLE ProtocolBindingContext, - IN PNDIS_REQUEST NdisRequest, - IN NDIS_STATUS Status - ) -{ - PADAPT pAdapt = (PADAPT)ProtocolBindingContext; - PNDIS_REQUEST pSynchRequest = pAdapt->pSynchRequest; -#ifndef VBOX_NETFLT_ONDEMAND_BIND - NDIS_OID Oid = pAdapt->Request.DATA.SET_INFORMATION.Oid ; -#endif - - if(pSynchRequest == NdisRequest) - { - /* asynchronous completion of our sync request */ - - /*1.set the status */ - pAdapt->fSynchCompletionStatus = Status; - - /* 2. set event */ - KeSetEvent(&pAdapt->hSynchCompletionEvent, 0, FALSE); - - /* 3. return; */ - return; - } -#ifdef VBOX_NETFLT_ONDEMAND_BIND - Assert(0); - return; -#else - - /* - * Since our request is not outstanding anymore - */ - Assert(pAdapt->bOutstandingRequests == TRUE); - - pAdapt->bOutstandingRequests = FALSE; - - /* - * Complete the Set or Query, and fill in the buffer for OID_PNP_CAPABILITIES, if need be. - */ - switch (NdisRequest->RequestType) - { - case NdisRequestQueryInformation: - - /* - * We never pass OID_PNP_QUERY_POWER down. - */ - Assert(Oid != OID_PNP_QUERY_POWER); - - if ((Oid == OID_PNP_CAPABILITIES) && (Status == NDIS_STATUS_SUCCESS)) - { - vboxNetFltWinMpQueryPNPCapabilities(pAdapt, &Status); - } - *pAdapt->BytesReadOrWritten = NdisRequest->DATA.QUERY_INFORMATION.BytesWritten; - *pAdapt->BytesNeeded = NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded; - - if ((Oid == OID_GEN_MAC_OPTIONS) && (Status == NDIS_STATUS_SUCCESS)) - { - /* save mac options for adaptor below us to use it with the NdisCopyLookaheadData when our ProtocolReceive is called */ - pAdapt->fMacOptions = *(PULONG)NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer; -#ifndef VBOX_LOOPBACK_USEFLAGS - /* - * Remove the no-loopback bit from mac-options. In essence we are - * telling NDIS that we can handle loopback. We don't, but the - * interface below us does. If we do not do this, then loopback - * processing happens both below us and above us. This is wasteful - * at best and if Netmon is running, it will see multiple copies - * of loopback packets when sniffing above us. - * - * Only the lowest miniport is a stack of layered miniports should - * ever report this bit set to NDIS. - */ - *(PULONG)NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer &= ~NDIS_MAC_OPTION_NO_LOOPBACK; -#else - /* we have to catch loopbacks from the underlying driver, so no duplications will occur, - * just indicate NDIS to handle loopbacks for the packets coming from the protocol */ - *(PULONG)NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer |= NDIS_MAC_OPTION_NO_LOOPBACK; -#endif - } - if(Oid == OID_GEN_CURRENT_PACKET_FILTER && VBOXNETFLT_PROMISCUOUS_SUPPORTED(pAdapt)) - { - /* we're here _ONLY_ in the passthru mode */ - Assert(pAdapt->fProcessingPacketFilter == VBOXNETFLT_PFP_PASSTHRU); - if(pAdapt->fProcessingPacketFilter == VBOXNETFLT_PFP_PASSTHRU) - { - PVBOXNETFLTINS pNetFltIf = PADAPT_2_PVBOXNETFLTINS(pAdapt); - Assert(pNetFltIf->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE); - vboxNetFltWinDereferenceModePassThru(pNetFltIf); - vboxNetFltWinDereferenceAdapt(pAdapt); - } - - if(Status == NDIS_STATUS_SUCCESS) - { - /* the filter request is issued below only in case netflt is not active, - * simply update the cache here */ - /* cache the filter used by upper protocols */ - pAdapt->fUpperProtocolSetFilter = *(PULONG)NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer; - pAdapt->bUpperProtSetFilterInitialized = true; - } - } - - - NdisMQueryInformationComplete(pAdapt->hMiniportHandle, - Status); - break; - - case NdisRequestSetInformation: - - Assert( Oid != OID_PNP_SET_POWER); - - if(Oid == OID_GEN_CURRENT_PACKET_FILTER && VBOXNETFLT_PROMISCUOUS_SUPPORTED(pAdapt)) - { - PVBOXNETFLTINS pNetFltIf = PADAPT_2_PVBOXNETFLTINS(pAdapt); - Assert(Status == NDIS_STATUS_SUCCESS); - if(pAdapt->fProcessingPacketFilter == VBOXNETFLT_PFP_NETFLT) - { - Assert(pNetFltIf->enmTrunkState == INTNETTRUNKIFSTATE_ACTIVE); - if(Status == NDIS_STATUS_SUCCESS) - { - pAdapt->fOurSetFilter = *((PULONG)pAdapt->Request.DATA.SET_INFORMATION.InformationBuffer); - Assert(pAdapt->fOurSetFilter == NDIS_PACKET_TYPE_PROMISCUOUS); - } - vboxNetFltWinDereferenceNetFlt(pNetFltIf); - vboxNetFltWinDereferenceAdapt(pAdapt); - pAdapt->fProcessingPacketFilter = 0; - } - else if(pAdapt->fProcessingPacketFilter == VBOXNETFLT_PFP_PASSTHRU) - { - Assert(pNetFltIf->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE); - - if(Status == NDIS_STATUS_SUCCESS) - { - /* the request was issued when the netflt was not active, simply update the cache here */ - pAdapt->fUpperProtocolSetFilter = *((PULONG)pAdapt->Request.DATA.SET_INFORMATION.InformationBuffer); - pAdapt->bUpperProtSetFilterInitialized = true; - } - vboxNetFltWinDereferenceModePassThru(pNetFltIf); - vboxNetFltWinDereferenceAdapt(pAdapt); - pAdapt->fProcessingPacketFilter = 0; - } - } - - - *pAdapt->BytesReadOrWritten = NdisRequest->DATA.SET_INFORMATION.BytesRead; - *pAdapt->BytesNeeded = NdisRequest->DATA.SET_INFORMATION.BytesNeeded; - NdisMSetInformationComplete(pAdapt->hMiniportHandle, - Status); - break; - - default: - Assert(0); - break; - } -#endif -} - -/** - * Status handler for the lower-edge(protocol). - * - * @param ProtocolBindingContext Pointer to the adapter structure - * @param GeneralStatus Status code - * @param StatusBuffer Status buffer - * @param StatusBufferSize Size of the status buffer - * @return None - */ -static VOID -vboxNetFltWinPtStatus( - IN NDIS_HANDLE ProtocolBindingContext, - IN NDIS_STATUS GeneralStatus, - IN PVOID StatusBuffer, - IN UINT StatusBufferSize - ) -{ -#ifndef VBOX_NETFLT_ONDEMAND_BIND - PADAPT pAdapt = (PADAPT)ProtocolBindingContext; - - /* - * Pass up this indication only if the upper edge miniport is initialized - * and powered on. Also ignore indications that might be sent by the lower - * miniport when it isn't at D0. - */ - if (vboxNetFltWinReferenceAdapt(pAdapt)) - { - Assert(pAdapt->hMiniportHandle); - - if ((GeneralStatus == NDIS_STATUS_MEDIA_CONNECT) || - (GeneralStatus == NDIS_STATUS_MEDIA_DISCONNECT)) - { - - pAdapt->LastIndicatedStatus = GeneralStatus; - } - NdisMIndicateStatus(pAdapt->hMiniportHandle, - GeneralStatus, - StatusBuffer, - StatusBufferSize); - - vboxNetFltWinDereferenceAdapt(pAdapt); - } - /* - * Save the last indicated media status - */ - else - { - if ((pAdapt->hMiniportHandle != NULL) && - ((GeneralStatus == NDIS_STATUS_MEDIA_CONNECT) || - (GeneralStatus == NDIS_STATUS_MEDIA_DISCONNECT))) - { - pAdapt->LatestUnIndicateStatus = GeneralStatus; - } - } -#endif -} - -/** - * status complete handler - */ -static VOID -vboxNetFltWinPtStatusComplete( - IN NDIS_HANDLE ProtocolBindingContext - ) -{ -#ifndef VBOX_NETFLT_ONDEMAND_BIND - PADAPT pAdapt = (PADAPT)ProtocolBindingContext; - - /* - * Pass up this indication only if the upper edge miniport is initialized - * and powered on. Also ignore indications that might be sent by the lower - * miniport when it isn't at D0. - */ - if (vboxNetFltWinReferenceAdapt(pAdapt)) - { - NdisMIndicateStatusComplete(pAdapt->hMiniportHandle); - - vboxNetFltWinDereferenceAdapt(pAdapt); - } -#endif -} - -/** - * Called by NDIS when the miniport below had completed a send. We should - * complete the corresponding upper-edge send this represents. - * - * @param ProtocolBindingContext - Points to ADAPT structure - * @param Packet - Low level packet being completed - * @param Status - status of send - * @return None - */ -static VOID -vboxNetFltWinPtSendComplete( - IN NDIS_HANDLE ProtocolBindingContext, - IN PNDIS_PACKET Packet, - IN NDIS_STATUS Status - ) -{ - PADAPT pAdapt = (PADAPT)ProtocolBindingContext; - PNDIS_PACKET Pkt; - - { - PSEND_RSVD SendRsvd; - -#if defined(DEBUG_NETFLT_PACKETS) || !defined(VBOX_LOOPBACK_USEFLAGS) - /* @todo: for optimization we could check only for netflt-mode packets - * do it for all for now */ - vboxNetFltWinLbRemoveSendPacket(pAdapt, Packet); -#endif -// Assert(KeGetCurrentIrql() == DISPATCH_LEVEL); - - SendRsvd = (PSEND_RSVD)(Packet->ProtocolReserved); - Pkt = SendRsvd->pOriginalPkt; - -#ifndef VBOX_NETFLT_ONDEMAND_BIND - if(Pkt) - { -#ifndef WIN9X - NdisIMCopySendCompletePerPacketInfo (Pkt, Packet); -#endif - NdisFreePacket(Packet); - - /* the ptk was posted from the upperlying protocol */ - NdisMSendComplete(pAdapt->hMiniportHandle, - Pkt, - Status); - } - else -#else - /* TODO: should change the PSEND_RSVD structure as we no nolnger need to handle original packets - * because all packets are originated by us */ - Assert(!Pkt); -#endif - { - /* if the ptk is zero - the ptk was originated by netFlt send/receive - * need to free packet buffers */ - PVOID pBufToFree = SendRsvd->pBufToFree; - - vboxNetFltWinFreeSGNdisPacket(Packet, !pBufToFree); - if(pBufToFree) - { - vboxNetFltWinMemFree(pBufToFree); - } - } - } - - vboxNetFltWinDereferenceAdapt(pAdapt); -} - -#ifndef VBOX_NETFLT_ONDEMAND_BIND - -/** - * removes searches for the packet in the list and removes it if found - * @return true if the packet was found and removed, false - otherwise - */ -static bool vboxNetFltWinRemovePacketFromList(PINTERLOCKED_SINGLE_LIST pList, PNDIS_PACKET pPacket) -{ - PTRANSFERDATA_RSVD pTDR = (PTRANSFERDATA_RSVD)pPacket->ProtocolReserved; - return vboxNetFltWinInterlockedSearchListEntry(pList, &pTDR->ListEntry, - true /* remove*/); -} - -/** - * puts the packet to the tail of the list - */ -static void vboxNetFltWinPutPacketToList(PINTERLOCKED_SINGLE_LIST pList, PNDIS_PACKET pPacket, PNDIS_BUFFER pOrigBuffer) -{ - PTRANSFERDATA_RSVD pTDR = (PTRANSFERDATA_RSVD)pPacket->ProtocolReserved; - pTDR->pOriginalBuffer = pOrigBuffer; - vboxNetFltWinInterlockedPutTail(pList, &pTDR->ListEntry); -} - -/** - * This is to queue the received packets and indicates them up if the given Packet - * status is NDIS_STATUS_RESOURCES, or the array is full. - * - * @param pAdapt - Pointer to the adpater structure. - * @param Packet - Pointer to the indicated packet. - * @param Indicate - Do the indication now. - * @return NONE - */ -DECLHIDDEN(VOID) vboxNetFltWinPtQueueReceivedPacket( - IN PADAPT pAdapt, - IN PNDIS_PACKET Packet, - IN BOOLEAN DoIndicate - ) -{ - PNDIS_PACKET PacketArray[MAX_RECEIVE_PACKET_ARRAY_SIZE]; - ULONG NumberOfPackets = 0, i; - bool bReturn = false; - PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt); - RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; - - do{ - RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp); - - Assert(pAdapt->cReceivedPacketCount < MAX_RECEIVE_PACKET_ARRAY_SIZE); - - /* - * pAdapt->ReceivePacketCount must be less than MAX_RECEIVE_PACKET_ARRAY_SIZE because - * the thread which held the pVElan->Lock before should already indicate the packet(s) - * up if pAdapt->ReceivePacketCount == MAX_RECEIVE_PACKET_ARRAY_SIZE. - */ - pAdapt->aReceivedPackets[pAdapt->cReceivedPacketCount] = Packet; - pAdapt->cReceivedPacketCount++; - - /* check the device state */ - if(vboxNetFltWinGetPowerState(&pAdapt->PTState) != NdisDeviceStateD0 - || vboxNetFltWinGetPowerState(&pAdapt->MPState) != NdisDeviceStateD0 - || vboxNetFltWinGetOpState(&pAdapt->PTState) > kVBoxNetDevOpState_Initialized - || vboxNetFltWinGetOpState(&pAdapt->MPState) > kVBoxNetDevOpState_Initialized) - { - /* we need to return all packets */ - bReturn = true; - } - - /* - * If our receive packet array is full, or the miniport below indicated the packets - * with resources, do the indicating now. - */ - - if ((pAdapt->cReceivedPacketCount == MAX_RECEIVE_PACKET_ARRAY_SIZE) || DoIndicate || bReturn) - { - NdisMoveMemory(PacketArray, - pAdapt->aReceivedPackets, - pAdapt->cReceivedPacketCount * sizeof(PNDIS_PACKET)); - - NumberOfPackets = pAdapt->cReceivedPacketCount; - /* - * So other thread can queue the received packets - */ - pAdapt->cReceivedPacketCount = 0; - - if(!bReturn) - { - DoIndicate = TRUE; - } - } - RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); - } while(0); - - if(!bReturn) - { - if(DoIndicate) - { - NdisMIndicateReceivePacket(pAdapt->hMiniportHandle, PacketArray, NumberOfPackets); - } - } - else - { - if (DoIndicate) - { - NumberOfPackets -= 1; - } - for (i = 0; i < NumberOfPackets; i++) - { - vboxNetFltWinMpReturnPacket(pAdapt, PacketArray[i]); - } - } -} - -#endif - -static bool vboxNetFltWinPtTransferDataCompleteActive(IN PADAPT pAdapt, - IN PNDIS_PACKET pPacket, - IN NDIS_STATUS Status) -{ - PVBOXNETFLTINS pNetFltIf = PADAPT_2_PVBOXNETFLTINS(pAdapt); - PNDIS_BUFFER pBuffer; - PTRANSFERDATA_RSVD pTDR; - - if(!vboxNetFltWinRemovePacketFromList(&pAdapt->TransferDataList, pPacket)) - return false; - - pTDR = (PTRANSFERDATA_RSVD)pPacket->ProtocolReserved; - Assert(pTDR); - Assert(pTDR->pOriginalBuffer); - - do - { - NdisUnchainBufferAtFront(pPacket, &pBuffer); - - Assert(pBuffer); - - NdisFreeBuffer(pBuffer); - - pBuffer = pTDR->pOriginalBuffer; - - NdisChainBufferAtBack(pPacket, pBuffer); - - /* data transfer was initiated when the netFlt was active - * the netFlt is still retained by us - * 1. check if loopback - * 2. enqueue packet - * 3. release netFlt */ - - if(Status == NDIS_STATUS_SUCCESS) - { - -#ifdef VBOX_LOOPBACK_USEFLAGS - if(vboxNetFltWinIsLoopedBackPacket(pPacket)) - { - /* should not be here */ - Assert(0); - } -#else - PNDIS_PACKET pLb = vboxNetFltWinLbSearchLoopBack(pAdapt, pPacket, false); - if(pLb) - { -#ifndef DEBUG_NETFLT_RECV_TRANSFERDATA - /* should not be here */ - Assert(0); -#endif - if(!vboxNetFltWinLbIsFromIntNet(pLb)) - { - /* the packet is not from int net, need to pass it up to the host */ - vboxNetFltWinPtQueueReceivedPacket(pAdapt, pPacket, TRUE); - /* dereference NetFlt, pAdapt will be dereferenced on Packet return */ - vboxNetFltWinDereferenceNetFlt(pNetFltIf); - break; - } - } -#endif - else - { - PRECV_RSVD pRecvRsvd; - /* 2. enqueue */ - /* use the same packet info to put the packet in the processing packet queue */ -#ifdef VBOX_NETFLT_ONDEMAND_BIND -# error "port me or remove VBOX_NETFLT_ONDEMAND_BIND" - PNDIS_BUFFER pBuffer; - PVOID pVA; - UINT cbLength; - uint32_t fFlags; - - NdisQueryPacket(pPacket, NULL, NULL, &pBuffer, NULL); - NdisQueryBufferSafe(pBuffer, &pVA, &cbLength, NormalPagePriority); - - fFlags = MACS_EQUAL(((PRTNETETHERHDR)pVA)->SrcMac, pNetFltIf->u.s.MacAddr) ? - PACKET_MINE | PACKET_SRC_HOST : PACKET_MINE; - SET_FLAGS_TO_INFO(pInfo, fFlags); - - pRecvRsvd = (PRECV_RSVD)(pPacket->MiniportReserved); - pRecvRsvd->pOriginalPkt = NULL; - pRecvRsvd->pBufToFree = NULL; - - NdisSetPacketFlags(pPacket, 0); - - Status = vboxNetFltWinQuEnqueuePacket(pNetFltIf, pPacket, fFlags); -#else - VBOXNETFLT_LBVERIFY(pNetFltIf, pPacket); - - pRecvRsvd = (PRECV_RSVD)(pPacket->MiniportReserved); - pRecvRsvd->pOriginalPkt = NULL; - pRecvRsvd->pBufToFree = NULL; - - NdisSetPacketFlags(pPacket, 0); -# ifdef VBOXNETFLT_NO_PACKET_QUEUE - if (vboxNetFltWinPostIntnet(pNetFltIf, pPacket, 0)) - { - /* drop it */ - vboxNetFltWinFreeSGNdisPacket(pPacket, true); - vboxNetFltWinDereferenceAdapt(pAdapt); - } - else - { - NdisMIndicateReceivePacket(pAdapt->hMiniportHandle, &pPacket, 1); - } - vboxNetFltWinDereferenceNetFlt(pNetFltIf); - break; -# else - Status = vboxNetFltWinQuEnqueuePacket(pNetFltIf, pPacket, PACKET_MINE); - if (Status == NDIS_STATUS_SUCCESS) - { - break; - } - Assert(0); -# endif -#endif - } - } - else - { - Assert(0); - } - /* we are here because of error either in data transfer or in enqueueing the packet */ - vboxNetFltWinFreeSGNdisPacket(pPacket, true); - vboxNetFltWinDereferenceNetFlt(pNetFltIf); - vboxNetFltWinDereferenceAdapt(pAdapt); - } while(0); - - return true; -} - -/** - * Entry point called by NDIS to indicate completion of a call by us - * to NdisTransferData. - * - * See notes under SendComplete. - */ -static VOID -vboxNetFltWinPtTransferDataComplete( - IN NDIS_HANDLE ProtocolBindingContext, - IN PNDIS_PACKET pPacket, - IN NDIS_STATUS Status, - IN UINT BytesTransferred - ) -{ - PADAPT pAdapt =(PADAPT)ProtocolBindingContext; - if(!vboxNetFltWinPtTransferDataCompleteActive(pAdapt, pPacket, Status)) - { -#ifndef VBOX_NETFLT_ONDEMAND_BIND - if(pAdapt->hMiniportHandle) - { - NdisMTransferDataComplete(pAdapt->hMiniportHandle, - pPacket, - Status, - BytesTransferred); - } - - vboxNetFltWinDereferenceAdapt(pAdapt); -#else - /* we are here because we've failed to allocate packet info */ - Assert(0); -#endif - } -} -#ifndef VBOX_NETFLT_ONDEMAND_BIND -/** - * This routine process the queued the packet, if anything is fine, indicate the packet - * up, otherwise, return the packet to the underlying miniports. - * - * @param pAdapt - Pointer to the adpater structure. - * @param bReturn - if true the packets should be returned without indication to the upper protocol - * @return None. */ -DECLHIDDEN(VOID) -vboxNetFltWinPtFlushReceiveQueue( - IN PADAPT pAdapt, - IN bool bReturn - ) -{ - - PNDIS_PACKET PacketArray[MAX_RECEIVE_PACKET_ARRAY_SIZE]; - ULONG NumberOfPackets = 0, i; - PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt); - RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; - - do - { - RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp); - - if (pAdapt->cReceivedPacketCount > 0) - { - NdisMoveMemory(PacketArray, - pAdapt->aReceivedPackets, - pAdapt->cReceivedPacketCount * sizeof(PNDIS_PACKET)); - - NumberOfPackets = pAdapt->cReceivedPacketCount; - /* - * So other thread can queue the received packets - */ - pAdapt->cReceivedPacketCount = 0; - - RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); - - if(!bReturn) - { - if(NumberOfPackets > 0) - { - Assert(pAdapt->hMiniportHandle); - - /* we are here because the NetFlt is NOT active, - * so no need for packet queueing here, simply indicate */ - NdisMIndicateReceivePacket(pAdapt->hMiniportHandle, - PacketArray, - NumberOfPackets); - } - break; - } - /* - * We need return the packet here - */ - for (i = 0; i < NumberOfPackets; i ++) - { - vboxNetFltWinMpReturnPacket(pAdapt, PacketArray[i]); - } - - /* break to ensure we do not call RTSpinlockRelease extra time */ - break; - } - - /* we are here only in case pAdapt->cReceivedPacketCount == 0 */ - RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); - } while (FALSE); -} - -/** - * ReceivePacket handler. Called by NDIS if the miniport below supports - * NDIS 4.0 style receives. Re-package the buffer chain in a new packet - * and indicate the new packet to protocols above us. Any context for - * packets indicated up must be kept in the MiniportReserved field. - * - * @param ProtocolBindingContext - Pointer to our adapter structure. - * @param Packet - Pointer to the packet - * @return INT == 0 -> We are done with the packet - * != 0 -> We will keep the packet and call NdisReturnPackets() this - * many times when done. */ -static INT -vboxNetFltWinRecvPacketPassThru( - IN PADAPT pAdapt, - IN PNDIS_PACKET pPacket, - IN BOOLEAN bForceIndicate - ) -{ - NDIS_STATUS fStatus; - PNDIS_PACKET pMyPacket; - - Assert(KeGetCurrentIrql() == DISPATCH_LEVEL); - - fStatus = vboxNetFltWinPrepareRecvPacket(pAdapt, pPacket, &pMyPacket, true); - - Assert(pMyPacket); - - if(pMyPacket != NULL) - { - if (fStatus == NDIS_STATUS_RESOURCES) - { - vboxNetFltWinPtQueueReceivedPacket(pAdapt, pMyPacket, TRUE); - - /* - * Our ReturnPackets handler will not be called for this packet. - * We should reclaim it right here. - */ - NdisDprFreePacket(pMyPacket); - - return 0; - } - - vboxNetFltWinPtQueueReceivedPacket(pAdapt, pMyPacket, bForceIndicate); - - return 1; - } - - return 0; -} - -/** - * process the packet receive in a "passthru" mode - */ -static NDIS_STATUS -vboxNetFltWinRecvPassThru( - IN PADAPT pAdapt, - IN PNDIS_PACKET pPacket) -{ - - NDIS_STATUS fStatus; - PNDIS_PACKET pMyPacket; - /* - * The miniport below did indicate up a packet. Use information - * from that packet to construct a new packet to indicate up. - */ - - Assert(KeGetCurrentIrql() == DISPATCH_LEVEL); - - /* - * Get a packet off the pool and indicate that up - */ - NdisDprAllocatePacket(&fStatus, - &pMyPacket, - pAdapt->hRecvPacketPoolHandle); - Assert(fStatus == NDIS_STATUS_SUCCESS); - if (fStatus == NDIS_STATUS_SUCCESS) - { - /* - * Make our packet point to data from the original - * packet. NOTE: this works only because we are - * indicating a receive directly from the context of - * our receive indication. If we need to queue this - * packet and indicate it from another thread context, - * we will also have to allocate a new buffer and copy - * over the packet contents, OOB data and per-packet - * information. This is because the packet data - * is available only for the duration of this - * receive indication call. - */ - NDIS_PACKET_FIRST_NDIS_BUFFER(pMyPacket) = NDIS_PACKET_FIRST_NDIS_BUFFER(pPacket); - NDIS_PACKET_LAST_NDIS_BUFFER(pMyPacket) = NDIS_PACKET_LAST_NDIS_BUFFER(pPacket); - - /* - * Get the original packet (it could be the same packet as the - * one received or a different one based on the number of layered - * miniports below) and set it on the indicated packet so the OOB - * data is visible correctly at protocols above. - */ - NDIS_SET_ORIGINAL_PACKET(pMyPacket, NDIS_GET_ORIGINAL_PACKET(pPacket)); - NDIS_SET_PACKET_HEADER_SIZE(pMyPacket, NDIS_GET_PACKET_HEADER_SIZE(pPacket)); - - /* - * Copy packet flags. - */ - NdisGetPacketFlags(pMyPacket) = NdisGetPacketFlags(pPacket); - - /* - * Force protocols above to make a copy if they want to hang - * on to data in this packet. This is because we are in our - * Receive handler (not ReceivePacket) and we can't return a - * ref count from here. - */ - NDIS_SET_PACKET_STATUS(pMyPacket, NDIS_STATUS_RESOURCES); - - /* - * By setting NDIS_STATUS_RESOURCES, we also know that we can reclaim - * this packet as soon as the call to NdisMIndicateReceivePacket - * returns. - * - * NOTE: we queue the packet and indicate this packet immediately with - * the already queued packets together. We have to the queue the packet - * first because some versions of NDIS might call protocols' - * ReceiveHandler(not ReceivePacketHandler) if the packet indicate status - * is NDIS_STATUS_RESOURCES. If the miniport below indicates an array of - * packets, some of them with status NDIS_STATUS_SUCCESS, some of them - * with status NDIS_STATUS_RESOURCES, vboxNetFltWinPtReceive might be called, by - * doing this way, we preserve the receive order of packets. - */ - vboxNetFltWinPtQueueReceivedPacket(pAdapt, pMyPacket, TRUE); - /* - * Reclaim the indicated packet. Since we had set its status - * to NDIS_STATUS_RESOURCES, we are guaranteed that protocols - * above are done with it. - */ - NdisDprFreePacket(pMyPacket); - - } - return fStatus; -} - -#endif /* #ifndef VBOX_NETFLT_ONDEMAND_BIND */ - - - - -/** - * process the ProtocolReceive in an "active" mode - * - * @return NDIS_STATUS_SUCCESS - the packet is processed - * NDIS_STATUS_PENDING - the packet is being processed, we are waiting for the ProtocolTransferDataComplete to be called - * NDIS_STATUS_NOT_ACCEPTED - the packet is not needed - typically this is because this is a loopback packet - * NDIS_STATUS_FAILURE - packet processing failed - */ -static NDIS_STATUS -vboxNetFltWinPtReceiveActive( - IN PADAPT pAdapt, - IN NDIS_HANDLE MacReceiveContext, - IN PVOID pHeaderBuffer, - IN UINT cbHeaderBuffer, - IN PVOID pLookaheadBuffer, - IN UINT cbLookaheadBuffer, - IN UINT cbPacket - ) -{ - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - - do - { - if (cbHeaderBuffer != ETH_HEADER_SIZE) - { - Status = NDIS_STATUS_NOT_ACCEPTED; - break; - } - -#ifndef DEBUG_NETFLT_RECV_TRANSFERDATA - if (cbPacket == cbLookaheadBuffer) - { - PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt); - PINTNETSG pSG; - PUCHAR pRcvData; -#ifndef VBOX_LOOPBACK_USEFLAGS - PNDIS_PACKET pLb; -#endif - - /* allocate SG buffer */ - Status = vboxNetFltWinAllocSG(cbPacket + cbHeaderBuffer, &pSG); - if(Status != NDIS_STATUS_SUCCESS) - { - Assert(0); - break; - } - - pRcvData = (PUCHAR)pSG->aSegs[0].pv; - - NdisMoveMappedMemory(pRcvData, pHeaderBuffer, cbHeaderBuffer); - - NdisCopyLookaheadData(pRcvData+cbHeaderBuffer, - pLookaheadBuffer, - cbLookaheadBuffer, - pAdapt->fMacOptions); -#ifndef VBOX_LOOPBACK_USEFLAGS - pLb = vboxNetFltWinLbSearchLoopBackBySG(pAdapt, pSG, false); - if(pLb) - { -#ifndef DEBUG_NETFLT_RECV_NOPACKET - /* should not be here */ - Assert(0); -#endif - if(!vboxNetFltWinLbIsFromIntNet(pLb)) - { - PNDIS_PACKET pMyPacket; - pMyPacket = vboxNetFltWinNdisPacketFromSG(pAdapt, /* PADAPT */ - pSG, /* PINTNETSG */ - pSG, /* PVOID pBufToFree */ - false, /* bool bToWire */ - false); /* bool bCopyMemory */ - if(pMyPacket) - { - vboxNetFltWinPtQueueReceivedPacket(pAdapt, pMyPacket, TRUE); - /* dereference the NetFlt here & indicate SUCCESS, which would mean the caller would not do a dereference - * the pAdapt dereference will be done on packet return */ - vboxNetFltWinDereferenceNetFlt(pNetFlt); - Status = NDIS_STATUS_SUCCESS; - } - else - { - vboxNetFltWinMemFree(pSG); - Status = NDIS_STATUS_FAILURE; - } - } - else - { - vboxNetFltWinMemFree(pSG); - Status = NDIS_STATUS_NOT_ACCEPTED; - } - break; - } -#endif - VBOXNETFLT_LBVERIFYSG(pNetFlt, pSG); - - /* enqueue SG */ -#ifdef VBOX_NETFLT_ONDEMAND_BIND -# ifdef VBOXNETFLT_NO_PACKET_QUEUE -# error "port me or remove VBOX_NETFLT_ONDEMAND_BIND" -# endif - { - uint32_t fFlags = MACS_EQUAL(((PRTNETETHERHDR)pRcvData)->SrcMac, pNetFlt->u.s.MacAddr) ? - PACKET_SG | PACKET_MINE | PACKET_SRC_HOST : PACKET_SG | PACKET_MINE; - Status = vboxNetFltWinQuEnqueuePacket(pNetFlt, pSG, fFlags); - } -#else -# ifdef VBOXNETFLT_NO_PACKET_QUEUE - if (vboxNetFltWinPostIntnet(pNetFlt, pSG, PACKET_SG)) - { - /* drop it */ - vboxNetFltWinMemFree(pSG); - vboxNetFltWinDereferenceAdapt(pAdapt); - } - else - { - PNDIS_PACKET pMyPacket = vboxNetFltWinNdisPacketFromSG(pAdapt, /* PADAPT */ - pSG, /* PINTNETSG */ - pSG, /* PVOID pBufToFree */ - false, /* bool bToWire */ - false); /* bool bCopyMemory */ - Assert(pMyPacket); - if (pMyPacket) - { - NDIS_SET_PACKET_STATUS(pMyPacket, NDIS_STATUS_SUCCESS); - - DBG_CHECK_PACKET_AND_SG(pMyPacket, pSG); - - LogFlow(("non-ndis packet info, packet created (%p)\n", pMyPacket)); - NdisMIndicateReceivePacket(pAdapt->hMiniportHandle, &pMyPacket, 1); - } - else - { - vboxNetFltWinDereferenceAdapt(pAdapt); - Status = NDIS_STATUS_RESOURCES; - } - } - vboxNetFltWinDereferenceNetFlt(pNetFlt); -# else - Status = vboxNetFltWinQuEnqueuePacket(pNetFlt, pSG, PACKET_SG | PACKET_MINE); - if(Status != NDIS_STATUS_SUCCESS) - { - Assert(0); - vboxNetFltWinMemFree(pSG); - break; - } -# endif -#endif - } - else -#endif /* #ifndef DEBUG_NETFLT_RECV_TRANSFERDATA */ - { - PNDIS_PACKET pPacket; - PNDIS_BUFFER pTransferBuffer; - PNDIS_BUFFER pOrigBuffer; - PUCHAR pMemBuf; - UINT cbBuf = cbPacket + cbHeaderBuffer; - UINT BytesTransferred; - - /* allocate NDIS Packet buffer */ -#ifdef VBOX_NETFLT_ONDEMAND_BIND - /* use the Send packet pool for packet allocation */ - NdisAllocatePacket(&Status, &pPacket, pAdapt->hSendPacketPoolHandle); -#else - NdisAllocatePacket(&Status, &pPacket, pAdapt->hRecvPacketPoolHandle); -#endif - if(Status != NDIS_STATUS_SUCCESS) - { - Assert(0); - break; - } - - VBOXNETFLT_OOB_INIT(pPacket); - -#ifdef VBOX_LOOPBACK_USEFLAGS - /* set "don't loopback" flags */ - NdisSetPacketFlags(pPacket, g_fPacketDontLoopBack); -#else - NdisSetPacketFlags(pPacket, 0); -#endif - - Status = vboxNetFltWinMemAlloc(&pMemBuf, cbBuf); - if(Status != NDIS_STATUS_SUCCESS) - { - Assert(0); - NdisFreePacket(pPacket); - break; - } -#ifdef VBOX_NETFLT_ONDEMAND_BIND - /* use the Send buffer pool for buffer allocation */ - NdisAllocateBuffer(&Status, &pTransferBuffer, pAdapt->hSendBufferPoolHandle, pMemBuf + cbHeaderBuffer, cbPacket); -#else - NdisAllocateBuffer(&Status, &pTransferBuffer, pAdapt->hRecvBufferPoolHandle, pMemBuf + cbHeaderBuffer, cbPacket); -#endif - if(Status != NDIS_STATUS_SUCCESS) - { - Assert(0); - Status = NDIS_STATUS_FAILURE; - NdisFreePacket(pPacket); - vboxNetFltWinMemFree(pMemBuf); - break; - } - -#ifdef VBOX_NETFLT_ONDEMAND_BIND - /* use the Send buffer pool for buffer allocation */ - NdisAllocateBuffer(&Status, &pOrigBuffer, pAdapt->hSendBufferPoolHandle, pMemBuf, cbBuf); -#else - NdisAllocateBuffer(&Status, &pOrigBuffer, pAdapt->hRecvBufferPoolHandle, pMemBuf, cbBuf); -#endif - if(Status != NDIS_STATUS_SUCCESS) - { - Assert(0); - Status = NDIS_STATUS_FAILURE; - NdisFreeBuffer(pTransferBuffer); - NdisFreePacket(pPacket); - vboxNetFltWinMemFree(pMemBuf); - break; - } - - NdisChainBufferAtBack(pPacket, pTransferBuffer); - - NdisMoveMappedMemory(pMemBuf, pHeaderBuffer, cbHeaderBuffer); - -#ifndef VBOX_NETFLT_ONDEMAND_BIND - vboxNetFltWinPutPacketToList(&pAdapt->TransferDataList, pPacket, pOrigBuffer); -#endif - -#ifdef DEBUG_NETFLT_RECV_TRANSFERDATA - if(cbPacket == cbLookaheadBuffer) - { - NdisCopyLookaheadData(pMemBuf+cbHeaderBuffer, - pLookaheadBuffer, - cbLookaheadBuffer, - pAdapt->fMacOptions); - } - else -#endif - { - Assert(cbPacket > cbLookaheadBuffer); - - NdisTransferData( - &Status, - pAdapt->hBindingHandle, - MacReceiveContext, - 0, /* ByteOffset */ - cbPacket, - pPacket, - &BytesTransferred); - } - if(Status != NDIS_STATUS_PENDING) - { - vboxNetFltWinPtTransferDataComplete(pAdapt, pPacket, Status, BytesTransferred); - } - } - } while(0); - - return Status; -} - - -/** - * Handle receive data indicated up by the miniport below. We pass - * it along to the protocol above us. - * - * If the miniport below indicates packets, NDIS would more - * likely call us at our ReceivePacket handler. However we - * might be called here in certain situations even though - * the miniport below has indicated a receive packet, e.g. - * if the miniport had set packet status to NDIS_STATUS_RESOURCES. - * - * @param ProtocolBindingContext - * @param MacReceiveContext - * @param pHeaderBuffer - * @param cbHeaderBuffer - * @param pLookAheadBuffer - * @param cbLookAheadBuffer - * @param cbPacket - * @return NDIS_STATUS_SUCCESS if we processed the receive successfully, - * NDIS_STATUS_XXX error code if we discarded it. */ -static NDIS_STATUS -vboxNetFltWinPtReceive( - IN NDIS_HANDLE ProtocolBindingContext, - IN NDIS_HANDLE MacReceiveContext, - IN PVOID pHeaderBuffer, - IN UINT cbHeaderBuffer, - IN PVOID pLookAheadBuffer, - IN UINT cbLookAheadBuffer, - IN UINT cbPacket - ) -{ - PADAPT pAdapt = (PADAPT)ProtocolBindingContext; - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt); -#ifdef VBOX_NETFLT_ONDEMAND_BIND -#if 0 - uint32_t fFlags; -#endif - - pNetFltIf = vboxNetFltWinReferenceAdaptNetFltFromAdapt(pAdapt); - if(pNetFltIf) - { - do - { -#if 0 - pPacket = NdisGetReceivedPacket(pAdapt->hBindingHandle, MacReceiveContext); - if(pPacket) - { -# ifdef DEBUG_NETFLT_LOOPBACK -# error "implement (see comments in the sources below this #error:)" - /* @todo FIXME no need for the PPACKET_INFO mechanism here; - instead the the NDIS_PACKET.ProtocolReserved + INTERLOCKED_SINGLE_LIST mechanism \ - similar to that used in TrasferData handling should be used; - */ - -// if(vboxNetFltWinIsLoopedBackPacket(pAdapt, pPacket)) -# else - if(vboxNetFltWinIsLoopedBackPacket(pPacket) || cbHeaderBuffer != ETH_HEADER_SIZE) -# endif - - { -// Assert(0); - /* nothing else to do here, just return the packet */ -// NdisReturnPackets(&pPacket, 1); -// break; - } - - fFlags = MACS_EQUAL(((PRTNETETHERHDR)pHeaderBuffer)->SrcMac, pNetFltIf->u.s.MacAddr) ? - PACKET_COPY | PACKET_SRC_HOST : PACKET_COPY; - Status = vboxNetFltWinQuEnqueuePacket(pNetFltIf, pPacket, fFlags); - if(Status == NDIS_STATUS_SUCCESS) - { - NdisReturnPackets(&pPacket, 1); - pAdapt = NULL; - pNetFltIf = NULL; - break; - } - } -#endif - Status = vboxNetFltWinPtReceiveActive(pAdapt, MacReceiveContext, pHeaderBuffer, cbHeaderBuffer, - pLookAheadBuffer, cbLookAheadBuffer, cbPacket); - if(NT_SUCCESS(Status)) - { - if(Status != NDIS_STATUS_NOT_ACCEPTED) - { - pAdapt = NULL; - pNetFltIf = NULL; - } - else - { - /* this is a looopback packet, nothing to do here */ - } - break; - } - } while(0); - - if(pNetFltIf) - vboxNetFltWinDereferenceNetFlt(pNetFltIf); - if(pAdapt) - vboxNetFltWinDereferenceAdapt(pAdapt); - - -#if 0 - if(pPacket) - { - NdisReturnPackets(&pPacket, 1); - } -#endif - /* we are here because the vboxNetFltWinPtReceiveActive returned pending, - * which means our ProtocolDataTransferComplete we will called, - * so return SUCCESS instead of NOT_ACCEPTED ?? */ -// return NDIS_STATUS_SUCCESS; - } - return NDIS_STATUS_NOT_ACCEPTED; -#else /* if NOT defined VBOX_NETFLT_ONDEMAND_BIND */ - PNDIS_PACKET pPacket = NULL; - bool bNetFltActive; - bool fAdaptActive = vboxNetFltWinReferenceAdaptNetFlt(pNetFlt, pAdapt, &bNetFltActive); - const bool bPassThruActive = !bNetFltActive; - if(fAdaptActive) - { - do - { -#ifndef DEBUG_NETFLT_RECV_NOPACKET - /* - * Get at the packet, if any, indicated up by the miniport below. - */ - pPacket = NdisGetReceivedPacket(pAdapt->hBindingHandle, MacReceiveContext); - if (pPacket != NULL) - { -#ifndef VBOX_LOOPBACK_USEFLAGS - PNDIS_PACKET pLb = NULL; -#endif - do - { -#ifdef VBOX_LOOPBACK_USEFLAGS - if(vboxNetFltWinIsLoopedBackPacket(pPacket)) - { - Assert(0); - /* nothing else to do here, just return the packet */ - //NdisReturnPackets(&pPacket, 1); - Status = NDIS_STATUS_NOT_ACCEPTED; - break; - } - - VBOXNETFLT_LBVERIFY(pNetFlt, pPacket); -#endif - if(bNetFltActive) - { -#ifndef VBOX_LOOPBACK_USEFLAGS - pLb = vboxNetFltWinLbSearchLoopBack(pAdapt, pPacket, false); - if(!pLb) -#endif - { - VBOXNETFLT_LBVERIFY(pNetFlt, pPacket); - -#ifdef VBOXNETFLT_NO_PACKET_QUEUE - if (vboxNetFltWinPostIntnet(pNetFlt, pPacket, 0)) - { - /* drop it */ - break; - } -#else - Status = vboxNetFltWinQuEnqueuePacket(pNetFlt, pPacket, PACKET_COPY); - Assert(Status == NDIS_STATUS_SUCCESS); - if(Status == NDIS_STATUS_SUCCESS) - { - //NdisReturnPackets(&pPacket, 1); - fAdaptActive = false; - bNetFltActive = false; - break; - } -#endif - } -#ifndef VBOX_LOOPBACK_USEFLAGS - else if(vboxNetFltWinLbIsFromIntNet(pLb)) - { - /* nothing else to do here, just return the packet */ - //NdisReturnPackets(&pPacket, 1); - Status = NDIS_STATUS_NOT_ACCEPTED; - break; - } - /* we are here because this is a looped back packet set not from intnet - * we will post it to the upper protocol */ -#endif - } - -#ifndef VBOX_LOOPBACK_USEFLAGS - Assert(!pLb || !vboxNetFltWinLbIsFromIntNet(pLb)); -#endif - Status = vboxNetFltWinRecvPassThru(pAdapt, pPacket); - /* we are done with packet processing, and we will - * not receive packet return event for this packet, - * fAdaptActive should be true to ensure we release adapt*/ - Assert(fAdaptActive); - } while(FALSE); - -#ifdef VBOXNETFLT_NO_PACKET_QUEUE - if(Status == NDIS_STATUS_SUCCESS || Status == NDIS_STATUS_NOT_ACCEPTED -# ifndef VBOX_LOOPBACK_USEFLAGS - || pLb -# endif - ) -#endif - { - break; - } - } -#endif - if(bNetFltActive) - { - Status = vboxNetFltWinPtReceiveActive(pAdapt, MacReceiveContext, pHeaderBuffer, cbHeaderBuffer, - pLookAheadBuffer, cbLookAheadBuffer, cbPacket); - if(NT_SUCCESS(Status)) - { - if(Status != NDIS_STATUS_NOT_ACCEPTED) - { - fAdaptActive = false; - bNetFltActive = false; - } - else - { -#ifndef VBOX_LOOPBACK_USEFLAGS - /* this is a loopback packet, nothing to do here */ -#else - Assert(0); - /* should not be here */ -#endif - } - break; - } - } - - /* Fall through if the miniport below us has either not - * indicated a packet or we could not allocate one */ - if(pPacket != NULL) - { - /* - * We are here because we failed to allocate packet - */ - vboxNetFltWinPtFlushReceiveQueue(pAdapt, false); - } - - /* we are done with packet processing, and we will - * not receive packet return event for this packet, - * fAdaptActive should be true to ensure we release adapt*/ - Assert(fAdaptActive); - - { - /* Note: we're using KeGetCurrentProcessorNumber, which is not entirely correct in case - * we're running on 64bit win7+, which can handle > 64 CPUs, however since KeGetCurrentProcessorNumber - * always returns the number < than the number of CPUs in the first group, we're guaranteed to have CPU index < 64 - * @todo: use KeGetCurrentProcessorNumberEx for Win7+ 64 and dynamically extended array */ - ULONG Proc = KeGetCurrentProcessorNumber(); - Assert(Proc < RT_ELEMENTS(pAdapt->abIndicateRcvComplete)); - pAdapt->abIndicateRcvComplete[Proc] = TRUE; - switch (pAdapt->Medium) - { - case NdisMedium802_3: - case NdisMediumWan: - NdisMEthIndicateReceive(pAdapt->hMiniportHandle, - MacReceiveContext, - (PCHAR)pHeaderBuffer, - cbHeaderBuffer, - pLookAheadBuffer, - cbLookAheadBuffer, - cbPacket); - break; - default: - Assert(FALSE); - break; - } - } - } while(0); - - if(bNetFltActive) - { - vboxNetFltWinDereferenceNetFlt(pNetFlt); - } - else if(bPassThruActive) - { - vboxNetFltWinDereferenceModePassThru(pNetFlt); - } - if(fAdaptActive) - { - vboxNetFltWinDereferenceAdapt(pAdapt); - } - } - else - { - Status = NDIS_STATUS_FAILURE; - } - - return Status; -#endif -} - -/** - * Called by the adapter below us when it is done indicating a batch of - * received packets. - * - * @param ProtocolBindingContext Pointer to our adapter structure. - * @return None */ -static VOID -vboxNetFltWinPtReceiveComplete( - IN NDIS_HANDLE ProtocolBindingContext - ) -{ -#ifndef VBOX_NETFLT_ONDEMAND_BIND - PADAPT pAdapt =(PADAPT)ProtocolBindingContext; - PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt); - ULONG NumberOfPackets = 0; - /* since the receive array queued packets do not hold the reference we need to - * reference the PassThru/NetFlt mode here to avoid packet reordering caused by - * concurrently running vboxNetFltWinPtReceiveComplete and vboxNetFltPortOsSetActive - * on netflt activation/deactivation */ - bool bNetFltActive; - bool fAdaptActive = vboxNetFltWinReferenceAdaptNetFlt(pNetFlt, pAdapt, &bNetFltActive); - /* Note: we're using KeGetCurrentProcessorNumber, which is not entirely correct in case - * we're running on 64bit win7+, which can handle > 64 CPUs, however since KeGetCurrentProcessorNumber - * always returns the number < than the number of CPUs in the first group, we're guaranteed to have CPU index < 64 - * @todo: use KeGetCurrentProcessorNumberEx for Win7+ 64 and dynamically extended array */ - ULONG Proc = KeGetCurrentProcessorNumber(); - Assert(Proc < RT_ELEMENTS(pAdapt->abIndicateRcvComplete)); - - vboxNetFltWinPtFlushReceiveQueue(pAdapt, false); - - if ((pAdapt->hMiniportHandle != NULL) - /* && (pAdapt->MPDeviceState == NdisDeviceStateD0) */ - && (pAdapt->abIndicateRcvComplete[Proc] == TRUE)) - { - switch (pAdapt->Medium) - { - case NdisMedium802_3: - case NdisMediumWan: - NdisMEthIndicateReceiveComplete(pAdapt->hMiniportHandle); - break; - default: - Assert(FALSE); - break; - } - } - - pAdapt->abIndicateRcvComplete[Proc] = FALSE; - - if(fAdaptActive) - { - if(bNetFltActive) - { - vboxNetFltWinDereferenceNetFlt(pNetFlt); - } - else - { - vboxNetFltWinDereferenceModePassThru(pNetFlt); - } - vboxNetFltWinDereferenceAdapt(pAdapt); - } -#endif -} - -/** - * ReceivePacket handler. Called by NDIS if the miniport below supports - * NDIS 4.0 style receives. Re-package the buffer chain in a new packet - * and indicate the new packet to protocols above us. Any context for - * packets indicated up must be kept in the MiniportReserved field. - * - * @param ProtocolBindingContext - Pointer to our adapter structure. - * @param Packet - Pointer to the packet - * @return == 0 -> We are done with the packet, - * != 0 -> We will keep the packet and call NdisReturnPackets() this many times when done. - */ -static INT -vboxNetFltWinPtReceivePacket( - IN NDIS_HANDLE ProtocolBindingContext, - IN PNDIS_PACKET pPacket - ) -{ - PADAPT pAdapt =(PADAPT)ProtocolBindingContext; - INT cRefCount = 0; - PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt); -#ifdef VBOX_NETFLT_ONDEMAND_BIND - PNDIS_BUFFER pBuffer; - PVOID pVA; - UINT cbLength; - uint32_t fFlags; - - pNetFltIf = vboxNetFltWinReferenceAdaptNetFltFromAdapt(pAdapt); - - if(pNetFltIf) - { - NDIS_STATUS Status; - bool bResources; - do - { -#ifdef DEBUG_NETFLT_LOOPBACK -# error "implement (see comments in the sources below this #error:)" - /* @todo FIXME no need for the PPACKET_INFO mechanism here; - instead the the NDIS_PACKET.ProtocolReserved + INTERLOCKED_SINGLE_LIST mechanism \ - similar to that used in TrasferData handling should be used; - */ - -// if(vboxNetFltWinIsLoopedBackPacket(pAdapt, pPacket)) -#else - if(vboxNetFltWinIsLoopedBackPacket(pPacket)) -#endif - - { - Assert(0); - NdisReturnPackets(&pPacket, 1); - break; - } - bResources = NDIS_GET_PACKET_STATUS(pPacket) == NDIS_STATUS_RESOURCES; - - NdisQueryPacket(pPacket, NULL, NULL, &pBuffer, NULL); - if(!pBuffer) - { - Assert(0); - NdisReturnPackets(&pPacket, 1); - cRefCount = 0; - break; - } - - NdisQueryBufferSafe(pBuffer, &pVA, &cbLength, NormalPagePriority); - if(!pVA || !cbLength) - { - Assert(0); - NdisReturnPackets(&pPacket, 1); - cRefCount = 0; - break; - } - - fFlags = MACS_EQUAL(((PRTNETETHERHDR)pVA)->SrcMac, pNetFltIf->u.s.MacAddr) ? PACKET_SRC_HOST : 0; - - Status = vboxNetFltWinQuEnqueuePacket(pNetFltIf, pPacket, bResources ? fFlags | PACKET_COPY : fFlags); - if(Status == NDIS_STATUS_SUCCESS) - { - if(bResources) - { - cRefCount = 0; - NdisReturnPackets(&pPacket, 1); - } - else - { - cRefCount = 1; - } - pNetFltIf = NULL; - pAdapt = NULL; - break; - } - else - { - Assert(0); - NdisReturnPackets(&pPacket, 1); - cRefCount = 0; - break; - } - } while (0); - - if(pNetFltIf) - vboxNetFltWinDereferenceNetFlt(pNetFltIf); - if(pAdapt) - vboxNetFltWinDereferenceAdapt(pAdapt); - return cRefCount; - } - /* we are here because we are inactive, simply return the packet */ - NdisReturnPackets(&pPacket, 1); - return 0; -#else - bool bNetFltActive; - bool fAdaptActive = vboxNetFltWinReferenceAdaptNetFlt(pNetFlt, pAdapt, &bNetFltActive); - const bool bPassThruActive = !bNetFltActive; - if(fAdaptActive) - { - do - { -#ifdef VBOX_LOOPBACK_USEFLAGS - if(vboxNetFltWinIsLoopedBackPacket(pPacket)) - { - Assert(0); - Log(("lb_rp")); - - /* nothing else to do here, just return the packet */ - cRefCount = 0; - //NdisReturnPackets(&pPacket, 1); - break; - } - - VBOXNETFLT_LBVERIFY(pNetFlt, pPacket); -#endif - - if(bNetFltActive) - { -#ifndef VBOX_LOOPBACK_USEFLAGS - PNDIS_PACKET pLb = vboxNetFltWinLbSearchLoopBack(pAdapt, pPacket, false); - if(!pLb) -#endif - { -#ifndef VBOXNETFLT_NO_PACKET_QUEUE - NDIS_STATUS fStatus; -#endif - bool bResources = NDIS_GET_PACKET_STATUS(pPacket) == NDIS_STATUS_RESOURCES; - - VBOXNETFLT_LBVERIFY(pNetFlt, pPacket); - - /*TODO: remove this assert. - * this is a temporary assert for debugging purposes: - * we're probably doing something wrong with the packets if the miniport reports NDIS_STATUS_RESOURCES */ - Assert(!bResources); - -#ifdef VBOXNETFLT_NO_PACKET_QUEUE - if (vboxNetFltWinPostIntnet(pNetFlt, pPacket, 0)) - { - /* drop it */ - cRefCount = 0; - break; - } - -#else - fStatus = vboxNetFltWinQuEnqueuePacket(pNetFlt, pPacket, bResources ? PACKET_COPY : 0); - if(fStatus == NDIS_STATUS_SUCCESS) - { - bNetFltActive = false; - fAdaptActive = false; - if(bResources) - { - cRefCount = 0; - //NdisReturnPackets(&pPacket, 1); - } - else - { - cRefCount = 1; - } - break; - } - else - { - Assert(0); - } -#endif - } -#ifndef VBOX_LOOPBACK_USEFLAGS - else if(vboxNetFltWinLbIsFromIntNet(pLb)) - { - /* the packet is from intnet, it has already been set to the host, - * no need for loopng it back to the host again */ - /* nothing else to do here, just return the packet */ - cRefCount = 0; - //NdisReturnPackets(&pPacket, 1); - break; - } -#endif - } - - cRefCount = vboxNetFltWinRecvPacketPassThru(pAdapt, pPacket, bNetFltActive); - if(cRefCount) - { - Assert(cRefCount == 1); - fAdaptActive = false; - } - - } while(FALSE); - - if(bNetFltActive) - { - vboxNetFltWinDereferenceNetFlt(pNetFlt); - } - else if(bPassThruActive) - { - vboxNetFltWinDereferenceModePassThru(pNetFlt); - } - if(fAdaptActive) - { - vboxNetFltWinDereferenceAdapt(pAdapt); - } - } - else - { - cRefCount = 0; - //NdisReturnPackets(&pPacket, 1); - } - - return cRefCount; -#endif -} - -/** - * This routine is called from NDIS to notify our protocol edge of a - * reconfiguration of parameters for either a specific binding (pAdapt - * is not NULL), or global parameters if any (pAdapt is NULL). - * - * @param pAdapt - Pointer to our adapter structure. - * @param pNetPnPEvent - the reconfigure event - * @return NDIS_STATUS_SUCCESS */ -static NDIS_STATUS -vboxNetFltWinPtPnPNetEventReconfigure( - IN PADAPT pAdapt, - IN PNET_PNP_EVENT pNetPnPEvent - ) -{ - NDIS_STATUS ReconfigStatus = NDIS_STATUS_SUCCESS; - NDIS_STATUS ReturnStatus = NDIS_STATUS_SUCCESS; - - do - { - /* - * Is this is a global reconfiguration notification ? - */ - if (pAdapt == NULL) - { - /* - * An important event that causes this notification to us is if - * one of our upper-edge miniport instances was enabled after being - * disabled earlier, e.g. from Device Manager in Win2000. Note that - * NDIS calls this because we had set up an association between our - * miniport and protocol entities by calling NdisIMAssociateMiniport. - * - * Since we would have torn down the lower binding for that miniport, - * we need NDIS' assistance to re-bind to the lower miniport. The - * call to NdisReEnumerateProtocolBindings does exactly that. - */ - NdisReEnumerateProtocolBindings (g_hProtHandle); - break; - } - - ReconfigStatus = NDIS_STATUS_SUCCESS; - - } while(FALSE); - - LogFlow(("<==PtPNPNetEventReconfigure: pAdapt %p\n", pAdapt)); - - return ReconfigStatus; -} - -static NDIS_STATUS -vboxNetFltWinPtPnPNetEventBindsComplete( - IN PADAPT pAdapt, - IN PNET_PNP_EVENT pNetPnPEvent - ) -{ - return NDIS_STATUS_SUCCESS; -} - -DECLHIDDEN(bool) vboxNetFltWinPtCloseAdapter(PADAPT pAdapt, PNDIS_STATUS pStatus) -{ - PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt); - RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; - - RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp); - - if(pAdapt->bClosingAdapter) - { - RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); - Assert(0); - return false; - } - if (pAdapt->hBindingHandle == NULL) - { - RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); - Assert(0); - return false; - } - - pAdapt->bClosingAdapter = true; - RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); - - /* - * Close the binding below. and wait for it to complete - */ - NdisResetEvent(&pAdapt->hEvent); - - NdisCloseAdapter(pStatus, pAdapt->hBindingHandle); - - if (*pStatus == NDIS_STATUS_PENDING) - { - NdisWaitEvent(&pAdapt->hEvent, 0); - *pStatus = pAdapt->Status; - } - - Assert (*pStatus == NDIS_STATUS_SUCCESS); - - pAdapt->hBindingHandle = NULL; - - return true; -} - -/** - * This is a notification to our protocol edge of the power state - * of the lower miniport. If it is going to a low-power state, we must - * wait here for all outstanding sends and requests to complete. - * - * @param pAdapt - Pointer to the adpater structure - * @param pNetPnPEvent - The Net Pnp Event. this contains the new device state - * @return NDIS_STATUS_SUCCESS or the status returned by upper-layer protocols. - * */ -static NDIS_STATUS -vboxNetFltWinPtPnPNetEventSetPower( - IN PADAPT pAdapt, - IN PNET_PNP_EVENT pNetPnPEvent - ) -{ - PNDIS_DEVICE_POWER_STATE pDeviceState =(PNDIS_DEVICE_POWER_STATE)(pNetPnPEvent->Buffer); - NDIS_DEVICE_POWER_STATE PrevDeviceState = vboxNetFltWinGetPowerState(&pAdapt->PTState); - NDIS_STATUS ReturnStatus; - PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt); - RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; - int cPPUsage; - - ReturnStatus = NDIS_STATUS_SUCCESS; - - /* - * Set the Internal Device State, this blocks all new sends or receives - */ - RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp); - - vboxNetFltWinSetPowerState(&pAdapt->PTState, *pDeviceState); - - /* - * Check if the miniport below is going to a low power state. - */ - if (vboxNetFltWinGetPowerState(&pAdapt->PTState) > NdisDeviceStateD0) - { - /* - * If the miniport below is going to standby, fail all incoming requests - */ - if (PrevDeviceState == NdisDeviceStateD0) - { - pAdapt->bStandingBy = TRUE; - } - RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); -#ifndef VBOX_NETFLT_ONDEMAND_BIND - - vboxNetFltWinPtFlushReceiveQueue(pAdapt, false); - - vboxNetFltWinWaitDereference(&pAdapt->MPState); -#endif - - /* - * Wait for outstanding sends and requests to complete. - */ - vboxNetFltWinWaitDereference(&pAdapt->PTState); - -#ifndef VBOX_NETFLT_ONDEMAND_BIND - while (ASMAtomicUoReadBool((volatile bool *)&pAdapt->bOutstandingRequests)) - { - /* - * sleep till outstanding requests complete - */ - vboxNetFltWinSleep(2); - } - - /* - * If the below miniport is going to low power state, complete the queued request - */ - RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp); - if (pAdapt->bQueuedRequest) - { - pAdapt->bQueuedRequest = FALSE; - RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); - vboxNetFltWinPtRequestComplete(pAdapt, &pAdapt->Request, NDIS_STATUS_FAILURE); - } - else - { - RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); - } -#endif - - /* check packet pool is empty */ - cPPUsage = NdisPacketPoolUsage(pAdapt->hSendPacketPoolHandle); - Assert(cPPUsage == 0); - cPPUsage = NdisPacketPoolUsage(pAdapt->hRecvPacketPoolHandle); - Assert(cPPUsage == 0); - /* for debugging only, ignore the err in release */ - NOREF(cPPUsage); - -#ifndef VBOX_NETFLT_ONDEMAND_BIND - Assert(pAdapt->bOutstandingRequests == FALSE); -#endif - } - else - { - /* - * If the physical miniport is powering up (from Low power state to D0), - * clear the flag - */ - if (PrevDeviceState > NdisDeviceStateD0) - { - pAdapt->bStandingBy = FALSE; - } - -#ifdef VBOX_NETFLT_ONDEMAND_BIND - RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); -#else - /* - * The device below is being turned on. If we had a request - * pending, send it down now. - */ - if (pAdapt->bQueuedRequest == TRUE) - { - NDIS_STATUS Status; - - pAdapt->bQueuedRequest = FALSE; - - pAdapt->bOutstandingRequests = TRUE; - RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); - - NdisRequest(&Status, - pAdapt->hBindingHandle, - &pAdapt->Request); - - if (Status != NDIS_STATUS_PENDING) - { - vboxNetFltWinPtRequestComplete(pAdapt, - &pAdapt->Request, - Status); - - } - } - else - { - RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); - } - -#endif /* #ifndef VBOX_NETFLT_ONDEMAND_BIND */ - - } - - return ReturnStatus; -} - -/** - * This is called by NDIS to notify us of a PNP event related to a lower - * binding. Based on the event, this dispatches to other helper routines. - * - * @param ProtocolBindingContext - Pointer to our adapter structure. Can be NULL - * for "global" notifications - * @param pNetPnPEvent - Pointer to the PNP event to be processed. - * @return NDIS_STATUS code indicating status of event processing. - * */ -static NDIS_STATUS -vboxNetFltWinPtPnPHandler( - IN NDIS_HANDLE ProtocolBindingContext, - IN PNET_PNP_EVENT pNetPnPEvent - ) -{ - PADAPT pAdapt =(PADAPT)ProtocolBindingContext; - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - - LogFlow(("vboxNetFltWinPtPnPHandler: Adapt %p, Event %d\n", pAdapt, pNetPnPEvent->NetEvent)); - - switch (pNetPnPEvent->NetEvent) - { - case NetEventSetPower: - Status = vboxNetFltWinPtPnPNetEventSetPower(pAdapt, pNetPnPEvent); - break; - - case NetEventReconfigure: - DBGPRINT(("NetEventReconfigure, pAdapt(%p)", pAdapt)); - Status = vboxNetFltWinPtPnPNetEventReconfigure(pAdapt, pNetPnPEvent); - break; - case NetEventBindsComplete: - DBGPRINT(("NetEventBindsComplete")); - Status = vboxNetFltWinPtPnPNetEventBindsComplete(pAdapt, pNetPnPEvent); - break; - default: - Status = NDIS_STATUS_SUCCESS; - break; - } - - return Status; -} -#ifdef __cplusplus -# define PTCHARS_40(_p) ((_p).Ndis40Chars) -#else -# define PTCHARS_40(_p) (_p) -#endif - -/** - * register the protocol edge - */ -DECLHIDDEN(NDIS_STATUS) -vboxNetFltWinPtRegister( - IN PDRIVER_OBJECT DriverObject, - IN PUNICODE_STRING RegistryPath - ) -{ - NDIS_STATUS Status; - NDIS_PROTOCOL_CHARACTERISTICS PChars; - NDIS_STRING Name; - - /* - * Now register the protocol. - */ - NdisZeroMemory(&PChars, sizeof(NDIS_PROTOCOL_CHARACTERISTICS)); - PTCHARS_40(PChars).MajorNdisVersion = VBOXNETFLT_PROT_MAJOR_NDIS_VERSION; - PTCHARS_40(PChars).MinorNdisVersion = VBOXNETFLT_PROT_MINOR_NDIS_VERSION; - - /* - * Make sure the protocol-name matches the service-name - * (from the INF) under which this protocol is installed. - * This is needed to ensure that NDIS can correctly determine - * the binding and call us to bind to miniports below. - */ - NdisInitUnicodeString(&Name, VBOXNETFLT_PROTOCOL_NAME); /* Protocol name */ - PTCHARS_40(PChars).Name = Name; - PTCHARS_40(PChars).OpenAdapterCompleteHandler = vboxNetFltWinPtOpenAdapterComplete; - PTCHARS_40(PChars).CloseAdapterCompleteHandler = vboxNetFltWinPtCloseAdapterComplete; - PTCHARS_40(PChars).SendCompleteHandler = vboxNetFltWinPtSendComplete; - PTCHARS_40(PChars).TransferDataCompleteHandler = vboxNetFltWinPtTransferDataComplete; - - PTCHARS_40(PChars).ResetCompleteHandler = vboxNetFltWinPtResetComplete; - PTCHARS_40(PChars).RequestCompleteHandler = vboxNetFltWinPtRequestComplete; - PTCHARS_40(PChars).ReceiveHandler = vboxNetFltWinPtReceive; - PTCHARS_40(PChars).ReceiveCompleteHandler = vboxNetFltWinPtReceiveComplete; - PTCHARS_40(PChars).StatusHandler = vboxNetFltWinPtStatus; - PTCHARS_40(PChars).StatusCompleteHandler = vboxNetFltWinPtStatusComplete; - PTCHARS_40(PChars).BindAdapterHandler = vboxNetFltWinPtBindAdapter; - PTCHARS_40(PChars).UnbindAdapterHandler = vboxNetFltWinPtUnbindAdapter; - PTCHARS_40(PChars).UnloadHandler = vboxNetFltWinPtUnloadProtocol; -#if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(DEBUG_NETFLT_RECV) - PTCHARS_40(PChars).ReceivePacketHandler = vboxNetFltWinPtReceivePacket; -#else - PTCHARS_40(PChars).ReceivePacketHandler = NULL; -#endif - PTCHARS_40(PChars).PnPEventHandler= vboxNetFltWinPtPnPHandler; - - NdisRegisterProtocol(&Status, - &g_hProtHandle, - &PChars, - sizeof(NDIS_PROTOCOL_CHARACTERISTICS)); - - return Status; -} - -/** - * deregister the protocol edge - */ -DECLHIDDEN(NDIS_STATUS) -vboxNetFltWinPtDeregister() -{ - NDIS_STATUS Status; - - if (g_hProtHandle != NULL) - { - NdisDeregisterProtocol(&Status, g_hProtHandle); - g_hProtHandle = NULL; - } - - return Status; -} - -#ifndef VBOX_NETFLT_ONDEMAND_BIND -/** - * returns the protocol handle - */ -DECLHIDDEN(NDIS_HANDLE) vboxNetFltWinPtGetHandle() -{ - return g_hProtHandle; -} -#endif diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltPt-win.h b/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltPt-win.h deleted file mode 100644 index 73abdc1b6..000000000 --- a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltPt-win.h +++ /dev/null @@ -1,43 +0,0 @@ -/* $Id: VBoxNetFltPt-win.h $ */ -/** @file - * VBoxNetFlt - Network Filter Driver (Host), Windows Specific Code. Protocol edge of ndis filter driver - */ - -/* - * Copyright (C) 2008 Oracle Corporation - * - * This file is part of VirtualBox Open Source Edition (OSE), as - * available from http://www.virtualbox.org. This file is free software; - * you can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) as published by the Free Software - * Foundation, in version 2 as it comes in the "COPYING" file of the - * VirtualBox OSE distribution. VirtualBox OSE is distributed in the - * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. - */ -/* - * Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample. - * Copyright (c) 1993-1999, Microsoft Corporation - */ - -#ifndef ___VBoxNetFltPt_win_h___ -#define ___VBoxNetFltPt_win_h___ - -#ifdef VBOXNETADP -# error "No protocol edge" -#endif -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtRegister(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath); -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtDeregister(); -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtDoUnbinding(PADAPT pAdapt, bool bOnUnbind); -DECLHIDDEN(VOID) vboxNetFltWinPtFlushReceiveQueue(IN PADAPT pAdapt, IN bool bReturn); -DECLHIDDEN(VOID) vboxNetFltWinPtQueueReceivedPacket(IN PADAPT pAdapt, IN PNDIS_PACKET Packet, IN BOOLEAN DoIndicate); -DECLHIDDEN(VOID) vboxNetFltWinPtRequestComplete(IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_REQUEST NdisRequest, IN NDIS_STATUS Status); -DECLHIDDEN(bool) vboxNetFltWinPtCloseAdapter(PADAPT pAdapt, PNDIS_STATUS pStatus); - -#ifdef VBOX_NETFLT_ONDEMAND_BIND -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtDoBinding(IN PADAPT pAdapt); -#else -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtDoBinding(IN PADAPT pAdapt, IN PNDIS_STRING pOurDeviceName, IN PNDIS_STRING pBindToDeviceName); -DECLHIDDEN(NDIS_HANDLE) vboxNetFltWinPtGetHandle(); -#endif - -#endif diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/WinNetConfig.cpp b/src/VBox/HostDrivers/VBoxNetFlt/win/WinNetConfig.cpp deleted file mode 100644 index 43e232bb2..000000000 --- a/src/VBox/HostDrivers/VBoxNetFlt/win/WinNetConfig.cpp +++ /dev/null @@ -1,4368 +0,0 @@ -/* $Id: WinNetConfig.cpp $ */ -/** @file - * VBoxNetCfgWin - Briefly describe this file, optionally with a longer description in a separate paragraph. - */ - -/* - * Copyright (C) 2008 Oracle Corporation - * - * This file is part of VirtualBox Open Source Edition (OSE), as - * available from http://www.virtualbox.org. This file is free software; - * you can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) as published by the Free Software - * Foundation, in version 2 as it comes in the "COPYING" file of the - * VirtualBox OSE distribution. VirtualBox OSE is distributed in the - * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. - */ -/* - * Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample. - *+--------------------------------------------------------------------------- - * - * Microsoft Windows - * Copyright (C) Microsoft Corporation, 2001. - * - * Author: Alok Sinha 15-May-01 - * - *---------------------------------------------------------------------------- - */ -#include "VBox/WinNetConfig.h" - -#define _WIN32_DCOM - - -#include <iphlpapi.h> - -#include <devguid.h> -#include <stdio.h> -#include <regstr.h> -//#define INITGUID -//#include <guiddef.h> -//#include <devguid.h> -//#include <objbase.h> -//#include <setupapi.h> -#include <shlobj.h> -#include <cfgmgr32.h> -#include <tchar.h> -//#include <VBox/com/Guid.h> -//#include <VBox/com/String.h> -//#include <wtypes.h> -#include <objbase.h> - -#include <crtdbg.h> -#include <stdlib.h> - -#include <Wbemidl.h> -#include <comdef.h> - -//#include <Winsock2.h> - -//using namespace com; - -#ifndef Assert -//# ifdef DEBUG -//# define Assert(_expr) assert(_expr) -//# else -//# define Assert(_expr) do{ }while(0) -//# endif -# define Assert _ASSERT -# define AssertMsg(expr, msg) do{}while(0) -#endif -static LOG_ROUTINE g_Logger = NULL; - -static VOID DoLogging(LPCWSTR szString, ...); -#define Log DoLogging - -#define DbgLog - -#define VBOX_NETCFG_LOCK_TIME_OUT 5000 - -typedef bool (*ENUMERATION_CALLBACK) (LPCWSTR pFileName, PVOID pContext); - -typedef struct _INF_INFO -{ - LPCWSTR pPnPId; -}INF_INFO, *PINF_INFO; - -typedef struct _INFENUM_CONTEXT -{ - INF_INFO InfInfo; - DWORD Flags; - HRESULT hr; -} INFENUM_CONTEXT, *PINFENUM_CONTEXT; - -static bool vboxNetCfgWinInfEnumerationCallback(LPCWSTR pFileName, PVOID pCtxt); - -class VBoxNetCfgStringList -{ -public: - VBoxNetCfgStringList(int aSize); - - ~VBoxNetCfgStringList(); - - HRESULT add(LPWSTR pStr); - - int size() {return mSize;} - - LPWSTR get(int i) {return maList[i];} -private: - HRESULT resize(int newSize); - - LPWSTR *maList; - int mBufSize; - int mSize; -}; - -VBoxNetCfgStringList::VBoxNetCfgStringList(int aSize) -{ - maList = (LPWSTR*)CoTaskMemAlloc( sizeof(maList[0]) * aSize); - mBufSize = aSize; - mSize = 0; -} - -VBoxNetCfgStringList::~VBoxNetCfgStringList() -{ - if(!mBufSize) - return; - - for(int i = 0; i < mSize; ++i) - { - CoTaskMemFree(maList[i]); - } - - CoTaskMemFree(maList); -} - -HRESULT VBoxNetCfgStringList::add(LPWSTR pStr) -{ - if(mSize == mBufSize) - { - int hr = resize(mBufSize+10); - if(SUCCEEDED(hr)) - return hr; - } - size_t cStr = wcslen(pStr) + 1; - LPWSTR str = (LPWSTR)CoTaskMemAlloc( sizeof(maList[0][0]) * cStr); - memcpy(str, pStr, sizeof(maList[0][0]) * cStr); - maList[mSize] = str; - ++mSize; - return S_OK; -} - -HRESULT VBoxNetCfgStringList::resize(int newSize) -{ - Assert(newSize >= mSize); - if(newSize < mSize) - return E_FAIL; - LPWSTR* pOld = maList; - maList = (LPWSTR*)CoTaskMemAlloc( sizeof(maList[0]) * newSize); - mBufSize = newSize; - memcpy(maList, pOld, mSize*sizeof(maList[0])); - CoTaskMemFree(pOld); - return S_OK; -} - -static HRESULT vboxNetCfgWinCollectInfs(const GUID * pGuid, LPCWSTR pPnPId, VBoxNetCfgStringList & list) -{ - DWORD winEr = ERROR_SUCCESS; - int counter = 0; - HDEVINFO hDevInfo = SetupDiCreateDeviceInfoList( - pGuid, /* IN LPGUID ClassGuid, OPTIONAL */ - NULL /*IN HWND hwndParent OPTIONAL */ - ); - if(hDevInfo != INVALID_HANDLE_VALUE) - { - if(SetupDiBuildDriverInfoList(hDevInfo, - NULL, /*IN OUT PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL*/ - SPDIT_CLASSDRIVER /*IN DWORD DriverType*/ - )) - { - SP_DRVINFO_DATA DrvInfo; - DrvInfo.cbSize = sizeof(SP_DRVINFO_DATA); - char DetailBuf[16384]; - PSP_DRVINFO_DETAIL_DATA pDrvDetail = (PSP_DRVINFO_DETAIL_DATA)DetailBuf; - - for(DWORD i = 0;;i++) - { - if(SetupDiEnumDriverInfo(hDevInfo, - NULL, /* IN PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL*/ - SPDIT_CLASSDRIVER , /*IN DWORD DriverType,*/ - i, /*IN DWORD MemberIndex,*/ - &DrvInfo /*OUT PSP_DRVINFO_DATA DriverInfoData*/ - )) - { - DWORD dwReq; - pDrvDetail->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA); - if(SetupDiGetDriverInfoDetail( - hDevInfo, /*IN HDEVINFO DeviceInfoSet,*/ - NULL, /*IN PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL*/ - &DrvInfo, /*IN PSP_DRVINFO_DATA DriverInfoData,*/ - pDrvDetail, /*OUT PSP_DRVINFO_DETAIL_DATA DriverInfoDetailData, OPTIONAL*/ - sizeof(DetailBuf), /*IN DWORD DriverInfoDetailDataSize,*/ - &dwReq /*OUT PDWORD RequiredSize OPTIONAL*/ - )) - { - for(WCHAR * pHwId = pDrvDetail->HardwareID; pHwId && *pHwId && pHwId < (TCHAR*)(DetailBuf + sizeof(DetailBuf)/sizeof(DetailBuf[0])) ;pHwId += _tcslen(pHwId) + 1) - { - if(!wcsicmp(pHwId, pPnPId)) - { - Assert(pDrvDetail->InfFileName[0]); - if(pDrvDetail->InfFileName) - { - list.add(pDrvDetail->InfFileName); - } - } - } - } - else - { - DWORD winEr = GetLastError(); - Log(L"Err SetupDiGetDriverInfoDetail (%d), req = %d", winEr, dwReq); -// Assert(0); - } - - } - else - { - DWORD winEr = GetLastError(); - if(winEr == ERROR_NO_MORE_ITEMS) - { - break; - } - - Assert(0); - } - } - - SetupDiDestroyDriverInfoList(hDevInfo, - NULL, /*IN PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL*/ - SPDIT_CLASSDRIVER/*IN DWORD DriverType*/ - ); - } - else - { - winEr = GetLastError(); - Assert(0); - } - - SetupDiDestroyDeviceInfoList(hDevInfo); - } - else - { - winEr = GetLastError(); - Assert(0); - } - - return HRESULT_FROM_WIN32(winEr); -} - -// -// Function: GetKeyValue -// -// Purpose: Retrieve the value of a key from the inf file. -// -// Arguments: -// hInf [in] Inf file handle. -// lpszSection [in] Section name. -// lpszKey [in] Key name. -// dwIndex [in] Key index. -// lppszValue [out] Key value. -// -// Returns: S_OK on success, otherwise and error code. -// -// Notes: -// - -static HRESULT vboxNetCfgWinGetKeyValue (HINF hInf, - LPCWSTR lpszSection, - LPCWSTR lpszKey, - DWORD dwIndex, - LPWSTR *lppszValue) -{ - INFCONTEXT infCtx; - DWORD dwSizeNeeded; - HRESULT hr; - - *lppszValue = NULL; - - if ( SetupFindFirstLineW(hInf, - lpszSection, - lpszKey, - &infCtx) == FALSE ) - { - DWORD winEr = GetLastError(); - DbgLog(L"vboxNetCfgWinGetKeyValue: SetupFindFirstLineW failed, winEr = (%d)\n", winEr); - //Assert(0); - return HRESULT_FROM_WIN32(winEr); - } - - SetupGetStringFieldW( &infCtx, - dwIndex, - NULL, - 0, - &dwSizeNeeded ); - - *lppszValue = (LPWSTR)CoTaskMemAlloc( sizeof(WCHAR) * dwSizeNeeded ); - - if ( !*lppszValue ) - { - Log(L"vboxNetCfgWinGetKeyValue: CoTaskMemAlloc failed\n"); - Assert(0); - return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); - } - - if ( SetupGetStringFieldW(&infCtx, - dwIndex, - *lppszValue, - dwSizeNeeded, - NULL) == FALSE ) - { - DWORD winEr = GetLastError(); - DbgLog(L"vboxNetCfgWinGetKeyValue: SetupGetStringFieldW failed, winEr = (%d)\n", winEr); - hr = HRESULT_FROM_WIN32(winEr); - //Assert(0); - CoTaskMemFree( *lppszValue ); - *lppszValue = NULL; - } - else - { - hr = S_OK; - } - - return hr; -} - -// -// Function: GetPnpID -// -// Purpose: Retrieve PnpID from an inf file. -// -// Arguments: -// lpszInfFile [in] Inf file to search. -// lppszPnpID [out] PnpID found. -// -// Returns: TRUE on success. -// -// Notes: -// - -static HRESULT vboxNetCfgWinGetPnpID (LPCWSTR lpszInfFile, - LPWSTR *lppszPnpID) -{ - HINF hInf; - LPWSTR lpszModelSection; - HRESULT hr; - - *lppszPnpID = NULL; - - hInf = SetupOpenInfFileW( lpszInfFile, - NULL, - INF_STYLE_WIN4, - NULL ); - - if ( hInf == INVALID_HANDLE_VALUE ) - { - DWORD winEr = GetLastError(); - DbgLog(L"vboxNetCfgWinGetPnpID: SetupOpenInfFileW failed, winEr = (%d), for file (%s)\n", winEr, lpszInfFile); - //Assert(0); - return HRESULT_FROM_WIN32(winEr); - } - - // - // Read the Model section name from Manufacturer section. - // - - hr = vboxNetCfgWinGetKeyValue( hInf, - L"Manufacturer", - NULL, - 1, - &lpszModelSection ); - //Assert(hr == S_OK); - if ( hr == S_OK ) - { - - // - // Read PnpID from the Model section. - // - - hr = vboxNetCfgWinGetKeyValue( hInf, - lpszModelSection, - NULL, - 2, - lppszPnpID ); - //Assert(hr == S_OK); - if ( hr != S_OK ) - { - DbgLog(L"vboxNetCfgWinGetPnpID: vboxNetCfgWinGetKeyValue lpszModelSection failed, hr = (0x%x), for file (%s)\n", hr, lpszInfFile); - } - - CoTaskMemFree( lpszModelSection ); - } - else - { - DbgLog(L"vboxNetCfgWinGetPnpID: vboxNetCfgWinGetKeyValue Manufacturer failed, hr = (0x%x), for file (%s)\n", hr, lpszInfFile); - } - - SetupCloseInfFile( hInf ); - - return hr; -} - -VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinUninstallInfs (const GUID * pGuid, LPCWSTR pPnPId, DWORD Flags) -{ - VBoxNetCfgStringList list(128); - HRESULT hr = vboxNetCfgWinCollectInfs(pGuid, pPnPId, list); - if(hr == S_OK) - { - INFENUM_CONTEXT Context; - Context.InfInfo.pPnPId = pPnPId; - Context.Flags = Flags; - Context.hr = S_OK; - int size = list.size(); - for (int i = 0; i < size; ++i) - { - LPCWSTR pInf = list.get(i); - const WCHAR* pRel = wcsrchr(pInf, '\\'); - if(pRel) - ++pRel; - else - pRel = pInf; - - vboxNetCfgWinInfEnumerationCallback(pRel, &Context); -// Log(L"inf : %s\n", list.get(i)); - } - } - return hr; -} - -static HRESULT vboxNetCfgWinEnumFiles(LPCWSTR pPattern, ENUMERATION_CALLBACK pCallback, PVOID pContext) -{ - WIN32_FIND_DATA Data; - memset(&Data, 0, sizeof(Data)); - HRESULT hr = S_OK; - - HANDLE hEnum = FindFirstFile(pPattern,&Data); - if(hEnum != INVALID_HANDLE_VALUE) - { - - do - { - if(!pCallback(Data.cFileName, pContext)) - { - break; - } - - /* next iteration */ - memset(&Data, 0, sizeof(Data)); - BOOL bNext = FindNextFile(hEnum,&Data); - if(!bNext) - { - int winEr = GetLastError(); - if(winEr != ERROR_NO_MORE_FILES) - { - Log(L"vboxNetCfgWinEnumFiles: FindNextFile err winEr (%d)\n", winEr); - Assert(0); - hr = HRESULT_FROM_WIN32(winEr); - } - break; - } - }while(true); - FindClose(hEnum); - } - else - { - int winEr = GetLastError(); - if(winEr != ERROR_NO_MORE_FILES) - { - Log(L"vboxNetCfgWinEnumFiles: FindFirstFile err winEr (%d)\n", winEr); - Assert(0); - hr = HRESULT_FROM_WIN32(winEr); - } - } - - return hr; -} - -static bool vboxNetCfgWinInfEnumerationCallback(LPCWSTR pFileName, PVOID pCtxt) -{ - PINFENUM_CONTEXT pContext = (PINFENUM_CONTEXT)pCtxt; -// Log(L"vboxNetCfgWinInfEnumerationCallback: pFileName (%s)\n", pFileName); - - LPWSTR lpszPnpID; - HRESULT hr = vboxNetCfgWinGetPnpID (pFileName, - &lpszPnpID); -// Assert(hr == S_OK); - if(hr == S_OK) - { - if(!wcsicmp(pContext->InfInfo.pPnPId, lpszPnpID)) - { - if(!SetupUninstallOEMInfW(pFileName, - pContext->Flags, /*DWORD Flags could be SUOI_FORCEDELETE */ - NULL /*__in PVOID Reserved == NULL */ - )) - { - DWORD dwError = GetLastError(); - - Log(L"vboxNetCfgWinInfEnumerationCallback: SetupUninstallOEMInf failed for file (%s), r (%d)\n", pFileName, dwError); - Assert(0); - hr = HRESULT_FROM_WIN32( dwError ); - } - } - CoTaskMemFree(lpszPnpID); - } - else - { - DbgLog(L"vboxNetCfgWinInfEnumerationCallback: vboxNetCfgWinGetPnpID failed, hr = (0x%x)\n", hr); - } - - return true; -} - - -static HRESULT VBoxNetCfgWinUninstallInfs(LPCWSTR pPnPId, DWORD Flags) -{ - WCHAR InfDirPath[MAX_PATH]; - HRESULT hr = SHGetFolderPathW(NULL, /* HWND hwndOwner*/ - CSIDL_WINDOWS, /* int nFolder*/ - NULL, /*HANDLE hToken*/ - SHGFP_TYPE_CURRENT, /*DWORD dwFlags*/ - InfDirPath); - Assert(hr == S_OK); - if(hr == S_OK) - { - wcscat(InfDirPath, L"\\inf\\oem*.inf"); - - INFENUM_CONTEXT Context; - Context.InfInfo.pPnPId = pPnPId; - Context.Flags = Flags; - Context.hr = S_OK; - hr = vboxNetCfgWinEnumFiles(InfDirPath, vboxNetCfgWinInfEnumerationCallback, &Context); - Assert(hr == S_OK); - if(hr == S_OK) - { - hr = Context.hr; - } - else - { - Log(L"VBoxNetCfgWinUninstallInfs: vboxNetCfgWinEnumFiles failed, hr = (0x%x)\n", hr); - } -// -// HANDLE hInfDir = CreateFileW(InfDirPath, -// FILE_READ_DATA, /* DWORD dwDesiredAccess*/ -// FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, /* DWORD dwShareMode */ -// NULL, /* LPSECURITY_ATTRIBUTES lpSecurityAttributes */ -// OPEN_EXISTING, /* DWORD dwCreationDisposition */ -// 0, /* DWORD dwFlagsAndAttributes */ -// NULL); -// if(hInfDir != INVALID_HANDLE_VALUE) -// { -// -// CloseHandle(hInfDir); -// } -// else -// { -// int winEr = GetLastError(); -// hr = HRESULT_FROM_WIN32(winEr); -// } - } - else - { - Log(L"VBoxNetCfgWinUninstallInfs: SHGetFolderPathW failed, hr = (0x%x)\n", hr); - } - - return hr; - -} - - - -/** - * Release reference - * - * @param punk Pointer to the interface to release reference to. - */ -VBOXNETCFGWIN_DECL(VOID) -VBoxNetCfgWinReleaseRef(IN IUnknown* punk) -{ - if(punk) - { - punk->Release(); - } - - return; -} - -/** - * Get a reference to INetCfg. - * - * @return HRESULT S_OK on success, otherwise an error code - * @param fGetWriteLock If TRUE, Write lock requested - * @param lpszAppName Application name requesting the reference. - * @param ppnc pointer the Reference to INetCfg to be stored to - * @param lpszLockedBy pointer the Application name who holds the write lock to be stored to, optional - */ -VBOXNETCFGWIN_DECL(HRESULT) -VBoxNetCfgWinQueryINetCfgEx(IN BOOL fGetWriteLock, - IN LPCWSTR lpszAppName, - IN DWORD cmsTimeout, - OUT INetCfg **ppnc, - OUT LPWSTR *lpszLockedBy) -{ - INetCfg *pnc = NULL; - INetCfgLock *pncLock = NULL; - HRESULT hr = S_OK; - - /* - * Initialize the output parameters. - */ - *ppnc = NULL; - - if ( lpszLockedBy ) - { - *lpszLockedBy = NULL; - } -// COM should be initialized before using the NetConfig API -// /* -// * Initialize COM -// */ -// hr = CoInitialize( NULL ); - - if ( hr == S_OK ) - { - - /* - * Create the object implementing INetCfg. - */ - hr = CoCreateInstance( CLSID_CNetCfg, - NULL, CLSCTX_INPROC_SERVER, - IID_INetCfg, - (void**)&pnc ); - Assert(hr == S_OK); - if ( hr == S_OK ) - { - - if ( fGetWriteLock ) - { - - /* - * Get the locking reference - */ - hr = pnc->QueryInterface( IID_INetCfgLock, - (LPVOID *)&pncLock ); - Assert(hr == S_OK); - if ( hr == S_OK ) - { - - /* - * Attempt to lock the INetCfg for read/write - */ - hr = pncLock->AcquireWriteLock( cmsTimeout, - lpszAppName, - lpszLockedBy); - if (hr == S_FALSE ) - { - Log(L"VBoxNetCfgWinQueryINetCfg: WriteLock busy\n"); - hr = NETCFG_E_NO_WRITE_LOCK; - } - else if (hr != S_OK) - { - Log(L"VBoxNetCfgWinQueryINetCfg: AcquireWriteLock failed, hr (0x%x)\n", hr); - } - } - else - { - Log(L"VBoxNetCfgWinQueryINetCfg: QueryInterface for IID_INetCfgLock failed, hr (0x%x)\n", hr); - } - } - - if ( hr == S_OK ) - { - - /* - * Initialize the INetCfg object. - */ - hr = pnc->Initialize( NULL ); - Assert(hr == S_OK); - if ( hr == S_OK ) - { - *ppnc = pnc; - pnc->AddRef(); - } - else - { - Log(L"VBoxNetCfgWinQueryINetCfg: Initialize failed, hr (0x%x)\n", hr); - - /* - * Initialize failed, if obtained lock, release it - */ - if ( pncLock ) - { - pncLock->ReleaseWriteLock(); - } - } - } - - VBoxNetCfgWinReleaseRef( pncLock ); - VBoxNetCfgWinReleaseRef( pnc ); - } - else - { - Log(L"VBoxNetCfgWinQueryINetCfg: CoCreateInstance for CLSID_CNetCfg failed, hr (0x%x)\n", hr); - } - -// COM should be initialized before using the NetConfig API -// /* -// * In case of error, uninitialize COM. -// */ -// if ( hr != S_OK ) -// { -// CoUninitialize(); -// } - } - - return hr; -} - -/** - * Get a reference to INetCfg. - * - * @return HRESULT S_OK on success, otherwise an error code - * @param fGetWriteLock If TRUE, Write lock requested - * @param lpszAppName Application name requesting the reference. - * @param ppnc pointer the Reference to INetCfg to be stored to - * @param lpszLockedBy pointer the Application name who holds the write lock to be stored to, optional - */ -VBOXNETCFGWIN_DECL(HRESULT) -VBoxNetCfgWinQueryINetCfg(IN BOOL fGetWriteLock, - IN LPCWSTR lpszAppName, - OUT INetCfg **ppnc, - OUT LPWSTR *lpszLockedBy) -{ - return VBoxNetCfgWinQueryINetCfgEx(fGetWriteLock, - lpszAppName, - VBOX_NETCFG_LOCK_TIME_OUT, - ppnc, - lpszLockedBy); -} -/** - * Release a reference to INetCfg. - * - * @param pnc Reference to INetCfg to release. - * @param fHasWriteLock If TRUE, reference was held with write lock. - * @return S_OK on success, otherwise an error code. - */ -VBOXNETCFGWIN_DECL(HRESULT) -VBoxNetCfgWinReleaseINetCfg(IN INetCfg *pnc, - IN BOOL fHasWriteLock) -{ - INetCfgLock *pncLock = NULL; - HRESULT hr = S_OK; - - /* - * Uninitialize INetCfg - */ - hr = pnc->Uninitialize(); - Assert(hr == S_OK); - /* - * If write lock is present, unlock it - */ - if ( hr == S_OK && fHasWriteLock ) - { - - /* - * Get the locking reference - */ - hr = pnc->QueryInterface( IID_INetCfgLock, - (LPVOID *)&pncLock); - Assert(hr == S_OK); - if ( hr == S_OK ) - { - hr = pncLock->ReleaseWriteLock(); - VBoxNetCfgWinReleaseRef( pncLock ); - } - } - else if(hr != S_OK) - { - Log(L"VBoxNetCfgWinReleaseINetCfg: Uninitialize failed, hr (0x%x)\n", hr); - } - - VBoxNetCfgWinReleaseRef( pnc ); - -// COM should be initialized before using the NetConfig API -// /* -// * Uninitialize COM. -// */ -// CoUninitialize(); - - return hr; -} - -/** - * Get network component enumerator reference. - * - * @param pnc Reference to INetCfg. - * @param pguidClass Class GUID of the network component. - * @param ppencc address the Enumerator reference to be stored to. - * @return S_OK on success, otherwise an error code. - */ -VBOXNETCFGWIN_DECL(HRESULT) -VBoxNetCfgWinGetComponentEnum(INetCfg *pnc, - IN const GUID *pguidClass, - OUT IEnumNetCfgComponent **ppencc) -{ - INetCfgClass *pncclass; - HRESULT hr; - - *ppencc = NULL; - - /* - * Get the class reference. - */ - hr = pnc->QueryNetCfgClass( pguidClass, - IID_INetCfgClass, - (PVOID *)&pncclass ); - Assert(hr == S_OK); - if ( hr == S_OK ) - { - - /* - * Get the enumerator reference. - */ - hr = pncclass->EnumComponents( ppencc ); - - /* - * We don't need the class reference any more. - */ - VBoxNetCfgWinReleaseRef( pncclass ); - } - else - { - Log(L"VBoxNetCfgWinGetComponentEnum: QueryNetCfgClass for IID_INetCfgClass failed, hr (0x%x)\n", hr); - } - - return hr; -} - -/** - * Enumerates the first network component. - * - * @param pencc Component enumerator reference. - * @param ppncc address the Network component reference to be stored to - * @return S_OK on success, otherwise an error code. - */ -/** - * Enumerate the next network component. - * The function behaves just like VBoxNetCfgWinGetFirstComponent if - * it is called right after VBoxNetCfgWinGetComponentEnum. - * - * @param pencc Component enumerator reference. - * @param ppncc address the Network component reference to be stored to. - * @return S_OK on success, otherwise an error code. - */ -VBOXNETCFGWIN_DECL(HRESULT) -VBoxNetCfgWinGetNextComponent(IN IEnumNetCfgComponent *pencc, - OUT INetCfgComponent **ppncc) -{ - HRESULT hr; - ULONG ulCount; - - *ppncc = NULL; - - hr = pencc->Next( 1, - ppncc, - &ulCount ); - Assert(hr == S_OK || hr == S_FALSE); - if(hr != S_OK && hr != S_FALSE) - { - Log(L"VBoxNetCfgWinGetNextComponent: Next failed, hr (0x%x)\n", hr); - } - return hr; -} - -/** - * Install a network component(protocols, clients and services) - * given its INF file. - * @param pnc Reference to INetCfg. - * @param lpszComponentId PnpID of the network component. - * @param pguidClass Class GUID of the network component. - * @return S_OK on success, otherwise an error code. - */ -VBOXNETCFGWIN_DECL(HRESULT) -VBoxNetCfgWinInstallComponent(IN INetCfg *pnc, - IN LPCWSTR szComponentId, - IN const GUID *pguidClass) -{ - INetCfgClassSetup *pncClassSetup = NULL; - INetCfgComponent *pncc = NULL; - OBO_TOKEN OboToken; - HRESULT hr = S_OK; - - /* - * OBO_TOKEN specifies on whose behalf this - * component is being installed. - * Set it to OBO_USER so that szComponentId will be installed - * on behalf of the user. - */ - - ZeroMemory( &OboToken, - sizeof(OboToken) ); - OboToken.Type = OBO_USER; - - /* - * Get component's setup class reference. - */ - hr = pnc->QueryNetCfgClass ( pguidClass, - IID_INetCfgClassSetup, - (void**)&pncClassSetup ); - Assert(hr == S_OK); - if ( hr == S_OK ) - { - - hr = pncClassSetup->Install( szComponentId, - &OboToken, - 0, - 0, /* Upgrade from build number. */ - NULL, /* Answerfile name */ - NULL, /* Answerfile section name */ - &pncc ); /* Reference after the component */ - /* is installed. */ - Assert(hr == S_OK); - if ( S_OK == hr ) - { - - /* - * we don't need to use pncc (INetCfgComponent), release it - */ - VBoxNetCfgWinReleaseRef( pncc ); - } - else - { - Log(L"VBoxNetCfgWinInstallComponent: Install failed, hr (0x%x)\n", hr); - } - - VBoxNetCfgWinReleaseRef( pncClassSetup ); - } - else - { - Log(L"VBoxNetCfgWinInstallComponent: QueryNetCfgClass for IID_INetCfgClassSetup failed, hr (0x%x)\n", hr); - } - - return hr; -} - -static HRESULT vboxNetCfgWinRemoveInf(IN LPCWSTR pInfFullPath, DWORD Flags) -{ - DWORD dwError; - HRESULT hr = S_OK; - WCHAR Drive[_MAX_DRIVE]; - WCHAR Dir[_MAX_DIR]; - WCHAR DirWithDrive[_MAX_DRIVE+_MAX_DIR]; - WCHAR OemInfFullPath[MAX_PATH]; - PWCHAR pOemInfName; - - /* - * Get the path where the INF file is. - */ - _wsplitpath( pInfFullPath, Drive, Dir, NULL, NULL ); - - wcscpy( DirWithDrive, Drive ); - wcscat( DirWithDrive, Dir ); - - /* - * get the oem file name. - */ - if (SetupCopyOEMInfW( pInfFullPath, - DirWithDrive, /* Other files are in the */ - /* same dir. as primary INF */ - SPOST_PATH, /* First param is path to INF */ - SP_COPY_REPLACEONLY, /* we want to get the inf file name */ - OemInfFullPath, /* Name of the INF after */ - /* it's copied to %windir%\inf */ - sizeof(OemInfFullPath) / sizeof(OemInfFullPath[0]), /* Max buf. size for the above */ - NULL, /* Required size if non-null */ - &pOemInfName ) ) /* Optionally get the filename */ - { - Log(L"vboxNetCfgWinRemoveInf: found inf file (%s) for (%s)\n", OemInfFullPath, pInfFullPath); - - if(!SetupUninstallOEMInfW(pOemInfName, - Flags, /*DWORD Flags could be SUOI_FORCEDELETE */ - NULL /*__in PVOID Reserved == NULL */ - )) - { - dwError = GetLastError(); - - Log(L"vboxNetCfgWinRemoveInf: SetupUninstallOEMInf failed for file (%s), r (%d)\n", pInfFullPath, dwError); - Log(L"vboxNetCfgWinRemoveInf: DirWithDrive (%s)\n", DirWithDrive); - - Assert(0); - hr = HRESULT_FROM_WIN32( dwError ); - } - } - else - { - dwError = GetLastError(); - - Log(L"vboxNetCfgWinRemoveInf: SetupCopyOEMInfW failed for file (%s), r (%d)\n", pInfFullPath, dwError); - Log(L"vboxNetCfgWinRemoveInf: DirWithDrive (%s)\n", DirWithDrive); - - - Assert(0); - hr = HRESULT_FROM_WIN32( dwError ); - } - return hr; -} - -static HRESULT vboxNetCfgWinCopyInf(IN LPCWSTR pInfFullPath) -{ - DWORD dwError; - HRESULT hr = S_OK; - WCHAR Drive[_MAX_DRIVE]; - WCHAR Dir[_MAX_DIR]; - WCHAR DirWithDrive[_MAX_DRIVE+_MAX_DIR]; - WCHAR DirDestInf[_MAX_PATH] = { 0 }; - - /* - * Get the path where the INF file is. - */ - _wsplitpath( pInfFullPath, Drive, Dir, NULL, NULL ); - - wcscpy( DirWithDrive, Drive ); - wcscat( DirWithDrive, Dir ); - - /* - * Copy the INF file and other files referenced in the INF file. - */ - if ( !SetupCopyOEMInfW( pInfFullPath, - DirWithDrive, /* Other files are in the */ - /* same dir. as primary INF */ - SPOST_PATH, /* First param is path to INF */ - 0, /* Default copy style */ - DirDestInf, /* Name of the INF after */ - /* it's copied to %windir%\inf */ - sizeof(DirDestInf), /* Max buf. size for the above */ - NULL, /* Required size if non-null */ - NULL ) ) /* Optionally get the filename */ - { - dwError = GetLastError(); - - Log(L"vboxNetCfgWinCopyInf: SetupCopyOEMInfW failed for file (%s), r (%d)\n", pInfFullPath, dwError); - Log(L"vboxNetCfgWinCopyInf: DirWithDrive (%s), DirDestInf(%s)\n", DirWithDrive, DirDestInf); - - Assert(0); - - hr = HRESULT_FROM_WIN32( dwError ); - } - - return hr; -} - -VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinInstallInf(IN LPCWSTR pInfFullPath) -{ - return vboxNetCfgWinCopyInf(pInfFullPath); -} - -/** - * Install a network component(protocols, clients and services) - * given its INF file. - * - * @param pnc Reference to INetCfg. - * @param lpszComponentId PnpID of the network component. - * @param pguidClass Class GUID of the network component. - * @param lpszInfFullPath INF file to install from. - * @return S_OK on success, otherwise an error code. - */ -VBOXNETCFGWIN_DECL(HRESULT) -VBoxNetCfgWinInstallNetComponent(IN INetCfg *pnc, - IN LPCWSTR lpszComponentId, - IN const GUID *pguidClass, - IN LPCWSTR * apInfFullPaths, - IN UINT cInfFullPaths) -{ - HRESULT hr = S_OK; - - /* - * If full path to INF has been specified, the INF - * needs to be copied using Setup API to ensure that any other files - * that the primary INF copies will be correctly found by Setup API - */ - for(UINT i = 0; i < cInfFullPaths; i++) - { - hr = vboxNetCfgWinCopyInf(apInfFullPaths[i]); - Assert(hr == S_OK); - if(hr != S_OK) - { - Log(L"VBoxNetCfgWinInstallNetComponent: vboxNetCfgWinCopyInf failed, hr (0x%x)\n", hr); - if(i != 0) - { - /* remove infs already installed */ - for(UINT j = i-1; j != 0; j--) - { - vboxNetCfgWinRemoveInf(apInfFullPaths[j], 0); - } - } - - break; - } - } - - if (S_OK == hr) - { - /* - * Install the network component. - */ - hr = VBoxNetCfgWinInstallComponent( pnc, - lpszComponentId, - pguidClass ); - Assert(hr == S_OK); - if ( hr == S_OK ) - { - /* - * On success, apply the changes - */ - HRESULT tmpHr = pnc->Apply(); - Assert(tmpHr == S_OK); - if(tmpHr != S_OK) - { - Log(L"VBoxNetCfgWinInstallNetComponent: Apply failed, hr (0x%x)\n", tmpHr); - } - } - else - { - Log(L"VBoxNetCfgWinInstallNetComponent: VBoxNetCfgWinInstallComponent failed, hr (0x%x)\n", hr); - } - } - - return hr; -} - -/** - * Uninstall a network component. - * - * @param pnc Reference to INetCfg. - * @param lpszInfId PnpID of the network component to uninstall - * @param apInfFiles array of null-terminated strings containing the inf file names describing drivers to be removed from the system - * @param cInfFiles the size of apInfFiles array - * @return S_OK on success, otherwise an error code. - */ -VBOXNETCFGWIN_DECL(HRESULT) -VBoxNetCfgWinUninstallComponent(IN INetCfg *pnc, - IN INetCfgComponent *pncc) -{ - INetCfgClass *pncClass; - INetCfgClassSetup *pncClassSetup; - GUID guidClass; - OBO_TOKEN obo; - HRESULT hr; - - /* - * Get the class GUID. - */ - hr = pncc->GetClassGuid( &guidClass ); - Assert(hr == S_OK); - if ( hr == S_OK ) - { - - /* - * Get a reference to component's class. - */ - hr = pnc->QueryNetCfgClass( &guidClass, - IID_INetCfgClass, - (PVOID *)&pncClass ); - Assert(hr == S_OK); - if ( hr == S_OK ) - { - - /* - * Get the setup interface. - */ - hr = pncClass->QueryInterface( IID_INetCfgClassSetup, - (LPVOID *)&pncClassSetup ); - Assert(hr == S_OK); - if ( hr == S_OK ) - { - - /* - * Uninstall the component. - */ - ZeroMemory( &obo, - sizeof(OBO_TOKEN) ); - - obo.Type = OBO_USER; - - hr = pncClassSetup->DeInstall( pncc, - &obo, - NULL ); - Assert(hr == S_OK); - if ( (hr == S_OK) || (hr == NETCFG_S_REBOOT) ) - { - HRESULT tmpHr = pnc->Apply(); - /* we ignore apply failures since they might occur on misconfigured systems*/ - Assert(tmpHr == S_OK); - if ( (tmpHr != S_OK) ) - { - Log(L"VBoxNetCfgWinUninstallComponent: Apply failed, hr (0x%x), ignoring\n", tmpHr); - } - } - else - { - Log(L"VBoxNetCfgWinUninstallComponent: DeInstall failed, hr (0x%x)\n", hr); - } - - VBoxNetCfgWinReleaseRef( pncClassSetup ); - } - else - { - Log(L"VBoxNetCfgWinUninstallComponent: QueryInterface for IID_INetCfgClassSetup failed, hr (0x%x)\n", hr); - } - - VBoxNetCfgWinReleaseRef( pncClass ); - } - else - { - Log(L"VBoxNetCfgWinUninstallComponent: QueryNetCfgClass failed, hr (0x%x)\n", hr); - } - } - else - { - Log(L"VBoxNetCfgWinUninstallComponent: GetClassGuid failed, hr (0x%x)\n", hr); - } - - return hr; -} - -#define VBOXNETCFGWIN_NETFLT_ID L"sun_VBoxNetFlt" -#define VBOXNETCFGWIN_NETFLT_MP_ID L"sun_VBoxNetFltmp" - -static HRESULT vboxNetCfgWinNetFltUninstall(IN INetCfg *pNc, DWORD InfRmFlags) -{ - INetCfgComponent * pNcc = NULL; - HRESULT hr = pNc->FindComponent(VBOXNETCFGWIN_NETFLT_ID, &pNcc); - if(hr == S_OK) - { - Log(L"NetFlt Is Installed currently\n"); - - hr = VBoxNetCfgWinUninstallComponent(pNc, pNcc); - - VBoxNetCfgWinReleaseRef(pNcc); - } - else if(hr == S_FALSE) - { - Log(L"NetFlt Is Not Installed currently\n"); - hr = S_OK; - } - else - { - Log(L"vboxNetCfgWinNetFltUninstall: FindComponent for NetFlt failed, hr (0x%x)\n", hr); - hr = S_OK; - } - - VBoxNetCfgWinUninstallInfs(VBOXNETCFGWIN_NETFLT_ID, InfRmFlags); - VBoxNetCfgWinUninstallInfs(VBOXNETCFGWIN_NETFLT_MP_ID, InfRmFlags); - - return hr; -} - -VBOXNETCFGWIN_DECL(HRESULT) -VBoxNetCfgWinNetFltUninstall(IN INetCfg *pNc) -{ - return vboxNetCfgWinNetFltUninstall(pNc, 0); -} - -VBOXNETCFGWIN_DECL(HRESULT) -VBoxNetCfgWinNetFltInstall(IN INetCfg *pNc, IN LPCWSTR * apInfFullPaths, IN UINT cInfFullPaths) -{ - HRESULT hr = vboxNetCfgWinNetFltUninstall(pNc, SUOI_FORCEDELETE); - - hr = VBoxNetCfgWinInstallNetComponent(pNc, VBOXNETCFGWIN_NETFLT_ID, - &GUID_DEVCLASS_NETSERVICE, - apInfFullPaths, - cInfFullPaths); - - return hr; -} - - -/** - * Get network component's binding path enumerator reference. - * - * @param pncc Network component reference. - * @param dwBindingType EBP_ABOVE or EBP_BELOW. - * @param ppencbp address the Enumerator reference to be stored to - * @return S_OK on success, otherwise an error code. - */ -VBOXNETCFGWIN_DECL(HRESULT) -VBoxNetCfgWinGetBindingPathEnum(IN INetCfgComponent *pncc, - IN DWORD dwBindingType, - OUT IEnumNetCfgBindingPath **ppencbp) -{ - INetCfgComponentBindings *pnccb = NULL; - HRESULT hr; - - *ppencbp = NULL; - - /* Get component's binding. */ - hr = pncc->QueryInterface( IID_INetCfgComponentBindings, - (PVOID *)&pnccb ); - Assert(hr == S_OK); - if ( hr == S_OK ) - { - - /* Get binding path enumerator reference. */ - hr = pnccb->EnumBindingPaths( dwBindingType, - ppencbp ); - if(hr != S_OK) - { - Log(L"VBoxNetCfgWinGetBindingPathEnum: EnumBindingPaths failed, hr (0x%x)\n", hr); - } - - VBoxNetCfgWinReleaseRef( pnccb ); - } - else - { - Log(L"VBoxNetCfgWinGetBindingPathEnum: QueryInterface for IID_INetCfgComponentBindings failed, hr (0x%x)\n", hr); - } - - return hr; -} - -/** - * Enumerates the first binding path. - * - * @param pencc Binding path enumerator reference. - * @param ppncc address the Binding path reference to be stored to - * @return S_OK on success, otherwise an error code. - */ -VBOXNETCFGWIN_DECL(HRESULT) -VBoxNetCfgWinGetFirstComponent(IN IEnumNetCfgComponent *pencc, - OUT INetCfgComponent **ppncc) -{ - HRESULT hr; - ULONG ulCount; - - *ppncc = NULL; - - pencc->Reset(); - - hr = pencc->Next( 1, - ppncc, - &ulCount ); - Assert(hr == S_OK || hr == S_FALSE); - if(hr != S_OK && hr != S_FALSE) - { - Log(L"VBoxNetCfgWinGetFirstComponent: Next failed, hr (0x%x)\n", hr); - } - return hr; -} - -VBOXNETCFGWIN_DECL(HRESULT) -VBoxNetCfgWinGetFirstBindingPath(IN IEnumNetCfgBindingPath *pencbp, - OUT INetCfgBindingPath **ppncbp) -{ - ULONG ulCount; - HRESULT hr; - - *ppncbp = NULL; - - pencbp->Reset(); - - hr = pencbp->Next( 1, - ppncbp, - &ulCount ); - Assert(hr == S_OK || hr == S_FALSE); - if(hr != S_OK && hr != S_FALSE) - { - Log(L"VBoxNetCfgWinGetFirstBindingPath: Next failed, hr (0x%x)\n", hr); - } - - return hr; -} - -/** - * Get binding interface enumerator reference. - * - * @param pncbp Binding path reference. - * @param ppencbp address the Enumerator reference to be stored to - * @return S_OK on success, otherwise an error code - */ -VBOXNETCFGWIN_DECL(HRESULT) -VBoxNetCfgWinGetBindingInterfaceEnum(IN INetCfgBindingPath *pncbp, - OUT IEnumNetCfgBindingInterface **ppencbi) -{ - HRESULT hr; - - *ppencbi = NULL; - - hr = pncbp->EnumBindingInterfaces( ppencbi ); - Assert(hr == S_OK); - if(hr != S_OK) - { - Log(L"VBoxNetCfgWinGetBindingInterfaceEnum: EnumBindingInterfaces failed, hr (0x%x)\n", hr); - } - - return hr; -} - -/** - * Enumerates the first binding interface. - * - * @param pencbi Binding interface enumerator reference. - * @param ppncbi address the Binding interface reference to be stored to - * @return S_OK on success, otherwise an error code - */ -VBOXNETCFGWIN_DECL(HRESULT) -VBoxNetCfgWinGetFirstBindingInterface(IN IEnumNetCfgBindingInterface *pencbi, - OUT INetCfgBindingInterface **ppncbi) -{ - ULONG ulCount; - HRESULT hr; - - *ppncbi = NULL; - - pencbi->Reset(); - - hr = pencbi->Next( 1, - ppncbi, - &ulCount ); - Assert(hr == S_OK || hr == S_FALSE); - if(hr != S_OK && hr != S_FALSE) - { - Log(L"VBoxNetCfgWinGetFirstBindingInterface: Next failed, hr (0x%x)\n", hr); - } - - return hr; -} - -/*@ - * Enumerate the next binding interface. - * The function behaves just like VBoxNetCfgWinGetFirstBindingInterface if - * it is called right after VBoxNetCfgWinGetBindingInterfaceEnum. - * - * @param pencbi Binding interface enumerator reference. - * @param ppncbi address the Binding interface reference t be stored to - * @return S_OK on success, otherwise an error code - */ -VBOXNETCFGWIN_DECL(HRESULT) -VBoxNetCfgWinGetNextBindingInterface(IN IEnumNetCfgBindingInterface *pencbi, - OUT INetCfgBindingInterface **ppncbi) -{ - ULONG ulCount; - HRESULT hr; - - *ppncbi = NULL; - - hr = pencbi->Next( 1, - ppncbi, - &ulCount ); - Assert(hr == S_OK || hr == S_FALSE); - if(hr != S_OK && hr != S_FALSE) - { - Log(L"VBoxNetCfgWinGetNextBindingInterface: Next failed, hr (0x%x)\n", hr); - } - - return hr; -} - -/** - * Enumerate the next binding path. - * The function behaves just like VBoxNetCfgWinGetFirstBindingPath if - * it is called right after VBoxNetCfgWinGetBindingPathEnum. - * - * @param pencbp Binding path enumerator reference. - * @param ppncbp Address the Binding path reference to be stored to - * @return S_OK on success, otherwise an error code. - */ -VBOXNETCFGWIN_DECL(HRESULT) -VBoxNetCfgWinGetNextBindingPath(IN IEnumNetCfgBindingPath *pencbp, - OUT INetCfgBindingPath **ppncbp) -{ - ULONG ulCount; - HRESULT hr; - - *ppncbp = NULL; - - hr = pencbp->Next( 1, - ppncbp, - &ulCount ); - Assert(hr == S_OK || hr == S_FALSE); - if(hr != S_OK && hr != S_FALSE) - { - Log(L"VBoxNetCfgWinGetNextBindingPath: Next failed, hr (0x%x)\n", hr); - } - - return hr; -} - -/* - * helper function to get the component by its guid given enum interface - */ -static HRESULT vboxNetCfgWinGetComponentByGuidEnum(IEnumNetCfgComponent *pEnumNcc, IN const GUID * pGuid, OUT INetCfgComponent ** ppNcc) -{ - INetCfgComponent * pNcc; - GUID NccGuid; - HRESULT hr; - - hr = VBoxNetCfgWinGetFirstComponent( pEnumNcc, &pNcc ); - Assert(hr == S_OK || hr == S_FALSE); - while(hr == S_OK) - { - ULONG uComponentStatus; - hr = pNcc->GetDeviceStatus(&uComponentStatus); - if(hr == S_OK) - { - if(uComponentStatus == 0) - { - hr = pNcc->GetInstanceGuid(&NccGuid); - Assert(hr == S_OK); - if(hr == S_OK) - { - if(NccGuid == *pGuid) - { - /* found the needed device */ - *ppNcc = pNcc; - break; - } - } - else - { - Log(L"vboxNetCfgWinGetComponentByGuidEnum: GetInstanceGuid failed, hr (0x%x)\n", hr); - } - } - } - - VBoxNetCfgWinReleaseRef(pNcc); - - hr = VBoxNetCfgWinGetNextComponent( pEnumNcc, &pNcc ); - } - - return hr; -} - -/** - * get the component by its guid - */ -VBOXNETCFGWIN_DECL(HRESULT) -VBoxNetCfgWinGetComponentByGuid(IN INetCfg *pNc, - IN const GUID *pguidClass, - IN const GUID * pComponentGuid, - OUT INetCfgComponent **ppncc) -{ - IEnumNetCfgComponent *pEnumNcc; - HRESULT hr = VBoxNetCfgWinGetComponentEnum( pNc, pguidClass, &pEnumNcc ); - Assert(hr == S_OK); - if(hr == S_OK) - { - hr = vboxNetCfgWinGetComponentByGuidEnum(pEnumNcc, pComponentGuid, ppncc); - Assert(hr == S_OK || hr == S_FALSE); - if(hr == S_FALSE) - { - Log(L"VBoxNetCfgWinGetComponentByGuid: component not found \n"); - } - else if(hr != S_OK) - { - Log(L"VBoxNetCfgWinGetComponentByGuid: vboxNetCfgWinGetComponentByGuidEnum failed, hr (0x%x)\n", hr); - } - VBoxNetCfgWinReleaseRef(pEnumNcc); - } - else - { - Log(L"VBoxNetCfgWinGetComponentByGuid: VBoxNetCfgWinGetComponentEnum failed, hr (0x%x)\n", hr); - } - return hr; -} - -typedef BOOL (*VBOXNETCFGWIN_NETCFGENUM_CALLBACK) (IN INetCfg *pNc, IN INetCfgComponent *pNcc, PVOID pContext); - -static HRESULT vboxNetCfgWinEnumNetCfgComponents(IN INetCfg *pNc, - IN const GUID *pguidClass, - VBOXNETCFGWIN_NETCFGENUM_CALLBACK callback, - PVOID pContext) -{ - IEnumNetCfgComponent *pEnumComponent; - HRESULT hr = pNc->EnumComponents(pguidClass, &pEnumComponent); - bool bBreak = false; - Assert(hr == S_OK); - if(hr == S_OK) - { - INetCfgComponent *pNcc; - hr = pEnumComponent->Reset(); - Assert(hr == S_OK); - do - { - hr = VBoxNetCfgWinGetNextComponent(pEnumComponent, &pNcc); - Assert(hr == S_OK || hr == S_FALSE); - if(hr == S_OK) - { - /* this is E_NOTIMPL for all components other than NET */ -// ULONG uComponentStatus; -// hr = pNcc->GetDeviceStatus(&uComponentStatus); -// if(hr == S_OK) - { - if(!callback(pNc, pNcc, pContext)) - { - bBreak = true; - } - } - VBoxNetCfgWinReleaseRef(pNcc); - } - else - { - if(hr ==S_FALSE) - { - hr = S_OK; - } - else - { - Log(L"vboxNetCfgWinEnumNetCfgComponents: VBoxNetCfgWinGetNextComponent failed, hr (0x%x)\n", hr); - } - break; - } - } while(!bBreak); - - VBoxNetCfgWinReleaseRef(pEnumComponent); - } - return hr; -} - -static VOID DoLogging(LPCWSTR szString, ...) -{ - LOG_ROUTINE pRoutine = (LOG_ROUTINE)(*((void * volatile *)&g_Logger)); - if(pRoutine) - { - WCHAR szBuffer[1024] = {0}; - va_list pArgList; - va_start(pArgList, szString); - _vsnwprintf(szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]), szString, pArgList); - va_end(pArgList); - - pRoutine(szBuffer); - } -} - -VBOXNETCFGWIN_DECL(VOID) VBoxNetCfgWinSetLogging(LOG_ROUTINE Log) -{ - *((void * volatile *)&g_Logger) = Log; -} - -static BOOL vboxNetCfgWinRemoveAllNetDevicesOfIdCallback(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDev, PVOID pContext) -{ - DWORD winEr; - HRESULT hr = S_OK; - SP_REMOVEDEVICE_PARAMS rmdParams; - rmdParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER); - rmdParams.ClassInstallHeader.InstallFunction = DIF_REMOVE; - rmdParams.Scope = DI_REMOVEDEVICE_GLOBAL; - rmdParams.HwProfile = 0; - if(SetupDiSetClassInstallParams(hDevInfo,pDev,&rmdParams.ClassInstallHeader,sizeof(rmdParams))) - { - if(SetupDiSetSelectedDevice (hDevInfo, pDev)) - { - if(SetupDiCallClassInstaller(DIF_REMOVE,hDevInfo,pDev)) - { - SP_DEVINSTALL_PARAMS devParams; - /* - * see if device needs reboot - */ - devParams.cbSize = sizeof(devParams); - if(SetupDiGetDeviceInstallParams(hDevInfo,pDev,&devParams)) - { - if(devParams.Flags & (DI_NEEDRESTART|DI_NEEDREBOOT)) - { - // - // reboot required - // - hr = S_FALSE; - Log(L"vboxNetCfgWinRemoveAllNetDevicesOfIdCallback: !!!REBOOT REQUIRED!!!\n"); - } - } - else - { - // - // appears to have succeeded - // - } - } - else - { - winEr = GetLastError(); - Log(L"vboxNetCfgWinRemoveAllNetDevicesOfIdCallback: SetupDiCallClassInstaller failed winErr(%d)\n", winEr); - hr = HRESULT_FROM_WIN32(winEr); - } - } - else - { - winEr = GetLastError(); - Log(L"vboxNetCfgWinRemoveAllNetDevicesOfIdCallback: SetupDiSetSelectedDevice failed winErr(%d)\n", winEr); - hr = HRESULT_FROM_WIN32(winEr); - } - } - else - { - winEr = GetLastError(); - Log(L"vboxNetCfgWinRemoveAllNetDevicesOfIdCallback: SetupDiSetClassInstallParams failed winErr(%d)\n", winEr); - hr = HRESULT_FROM_WIN32(winEr); - } - - return TRUE; -} - -VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinRemoveAllNetDevicesOfId(LPWSTR pPnPId) -{ - return VBoxNetCfgWinEnumNetDevices(pPnPId, vboxNetCfgWinRemoveAllNetDevicesOfIdCallback, NULL); -} - -VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinEnumNetDevices(LPWSTR pPnPId, VBOXNETCFGWIN_NETENUM_CALLBACK callback, PVOID pContext) -{ - DWORD winEr; - HRESULT hr = S_OK; - - HDEVINFO hDevInfo = SetupDiGetClassDevsExW( - &GUID_DEVCLASS_NET, - NULL, /* IN PCTSTR Enumerator, OPTIONAL*/ - NULL, /*IN HWND hwndParent, OPTIONAL*/ - DIGCF_PRESENT, /*IN DWORD Flags,*/ - NULL, /*IN HDEVINFO DeviceInfoSet, OPTIONAL*/ - NULL, /*IN PCTSTR MachineName, OPTIONAL*/ - NULL /*IN PVOID Reserved*/ - ); - if(hDevInfo != INVALID_HANDLE_VALUE) - { - DWORD iDev = 0; - SP_DEVINFO_DATA Dev; - PBYTE pBuffer = NULL; - DWORD cbBuffer = 0; - DWORD cbRequired = 0; - BOOL bEnumCompleted; - size_t cPnPId = wcslen(pPnPId); - - Dev.cbSize = sizeof(Dev); - - for(; bEnumCompleted = SetupDiEnumDeviceInfo(hDevInfo, iDev, &Dev); iDev++) - { - if(!SetupDiGetDeviceRegistryPropertyW(hDevInfo,&Dev, - SPDRP_HARDWAREID, /* IN DWORD Property,*/ - NULL, /*OUT PDWORD PropertyRegDataType, OPTIONAL*/ - pBuffer, /*OUT PBYTE PropertyBuffer,*/ - cbBuffer, /* IN DWORD PropertyBufferSize,*/ - &cbRequired /*OUT PDWORD RequiredSize OPTIONAL*/ - )) - { - winEr = GetLastError(); - if(winEr != ERROR_INSUFFICIENT_BUFFER) - { - Log(L"VBoxNetCfgWinEnumNetDevices: SetupDiGetDeviceRegistryPropertyW (1) failed winErr(%d)\n", winEr); - hr = HRESULT_FROM_WIN32(winEr); - break; - } - - if(pBuffer) - { - free(pBuffer); - } - - pBuffer = (PBYTE)malloc(cbRequired); - cbBuffer = cbRequired; - - if(!SetupDiGetDeviceRegistryPropertyW(hDevInfo,&Dev, - SPDRP_HARDWAREID, /* IN DWORD Property,*/ - NULL, /*OUT PDWORD PropertyRegDataType, OPTIONAL*/ - pBuffer, /*OUT PBYTE PropertyBuffer,*/ - cbBuffer, /* IN DWORD PropertyBufferSize,*/ - &cbRequired /*OUT PDWORD RequiredSize OPTIONAL*/ - )) - { - winEr = GetLastError(); - Log(L"VBoxNetCfgWinEnumNetDevices: SetupDiGetDeviceRegistryPropertyW (2) failed winErr(%d)\n", winEr); - hr = HRESULT_FROM_WIN32(winEr); - break; - } - } - - PWCHAR pCurId = (PWCHAR)pBuffer; - size_t cCurId = wcslen(pCurId); - if(cCurId >= cPnPId) - { - pCurId += cCurId - cPnPId; - if(!wcsnicmp(pCurId, pPnPId, cPnPId)) - { - - if(!callback(hDevInfo,&Dev,pContext)) - break; - } - } - - } - - if(pBuffer) - free(pBuffer); - - if(bEnumCompleted) - { - winEr = GetLastError(); - hr = winEr == ERROR_NO_MORE_ITEMS ? S_OK : HRESULT_FROM_WIN32(winEr); - } - - SetupDiDestroyDeviceInfoList(hDevInfo); - } - else - { - DWORD winEr = GetLastError(); - Log(L"VBoxNetCfgWinEnumNetDevices: SetupDiGetClassDevsExW failed winErr(%d)\n", winEr); - hr = HRESULT_FROM_WIN32(winEr); - } - - return hr; -} - - - -/* The original source of the VBoxNetAdp adapter creation/destruction code has the following copyright */ -/* - Copyright 2004 by the Massachusetts Institute of Technology - - All rights reserved. - - Permission to use, copy, modify, and distribute this software and its - documentation for any purpose and without fee is hereby granted, - provided that the above copyright notice appear in all copies and that - both that copyright notice and this permission notice appear in - supporting documentation, and that the name of the Massachusetts - Institute of Technology (M.I.T.) not be used in advertising or publicity - pertaining to distribution of the software without specific, written - prior permission. - - M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING - ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL - M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR - ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, - ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - SOFTWARE. -*/ - - -#define NETSHELL_LIBRARY _T("netshell.dll") - -/** - * Use the IShellFolder API to rename the connection. - */ -static HRESULT rename_shellfolder (PCWSTR wGuid, PCWSTR wNewName) -{ - /* This is the GUID for the network connections folder. It is constant. - * {7007ACC7-3202-11D1-AAD2-00805FC1270E} */ - const GUID CLSID_NetworkConnections = { - 0x7007ACC7, 0x3202, 0x11D1, { - 0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E - } - }; - - LPITEMIDLIST pidl = NULL; - IShellFolder *pShellFolder = NULL; - HRESULT hr; - - /* Build the display name in the form "::{GUID}". */ - if (wcslen (wGuid) >= MAX_PATH) - return E_INVALIDARG; - WCHAR szAdapterGuid[MAX_PATH + 2] = {0}; - swprintf (szAdapterGuid, L"::%ls", wGuid); - - /* Create an instance of the network connections folder. */ - hr = CoCreateInstance (CLSID_NetworkConnections, NULL, - CLSCTX_INPROC_SERVER, IID_IShellFolder, - reinterpret_cast <LPVOID *> (&pShellFolder)); - /* Parse the display name. */ - if (SUCCEEDED (hr)) - { - hr = pShellFolder->ParseDisplayName (NULL, NULL, szAdapterGuid, NULL, - &pidl, NULL); - } - if (SUCCEEDED (hr)) - { - hr = pShellFolder->SetNameOf (NULL, pidl, wNewName, SHGDN_NORMAL, - &pidl); - } - - CoTaskMemFree (pidl); - - if (pShellFolder) - pShellFolder->Release(); - - return hr; -} - -VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinRenameConnection (LPWSTR pGuid, PCWSTR NewName) -{ - typedef HRESULT (WINAPI *lpHrRenameConnection) (const GUID *, PCWSTR); - lpHrRenameConnection RenameConnectionFunc = NULL; - HRESULT status; -// Guid guid(*pDevInstanceGuid); -// Bstr bstr(guid.toString()); -// BSTR GuidString = bstr.mutableRaw(); -// WCHAR GuidString[50]; -// -// int length = StringFromGUID2(*pDevInstanceGuid, GuidString, sizeof(GuidString)/sizeof(GuidString[0])); -// if(!length) -// return E_FAIL; - -// strString[wcslen(strString) - 1] = L'\0'; -// -// WCHAR * GuidString = strString + 1; - - /* First try the IShellFolder interface, which was unimplemented - * for the network connections folder before XP. */ - status = rename_shellfolder (pGuid, NewName); - if (status == E_NOTIMPL) - { -/** @todo that code doesn't seem to work! */ - /* The IShellFolder interface is not implemented on this platform. - * Try the (undocumented) HrRenameConnection API in the netshell - * library. */ - CLSID clsid; - HINSTANCE hNetShell; - status = CLSIDFromString ((LPOLESTR) pGuid, &clsid); - if (FAILED(status)) - return E_FAIL; - hNetShell = LoadLibrary (NETSHELL_LIBRARY); - if (hNetShell == NULL) - return E_FAIL; - RenameConnectionFunc = - (lpHrRenameConnection) GetProcAddress (hNetShell, - "HrRenameConnection"); - if (RenameConnectionFunc == NULL) - { - FreeLibrary (hNetShell); - return E_FAIL; - } - status = RenameConnectionFunc (&clsid, NewName); - FreeLibrary (hNetShell); - } - if (FAILED (status)) - return status; - - return S_OK; -} - -#define DRIVERHWID _T("sun_VBoxNetAdp") - -#define SetErrBreak(strAndArgs) \ - if (1) { \ - hrc = E_FAIL; \ - Log strAndArgs; \ - Assert(0); \ - break; \ - } else do {} while (0) - - -VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinRemoveHostOnlyNetworkInterface (const GUID *pGUID, BSTR *pErrMsg) -{ -// LogFlowFuncEnter(); -// LogFlowFunc (("Network connection GUID = {%RTuuid}\n", aGUID.raw())); - -// AssertReturn (aClient, VERR_INVALID_POINTER); -// AssertReturn (!aGUID.isEmpty(), VERR_INVALID_PARAMETER); - - HRESULT hrc = S_OK; - - do - { - TCHAR lszPnPInstanceId [512] = {0}; - - /* We have to find the device instance ID through a registry search */ - - HKEY hkeyNetwork = 0; - HKEY hkeyConnection = 0; - - do - { - WCHAR strRegLocation [256]; - WCHAR GuidString[50]; - - int length = StringFromGUID2(*pGUID, GuidString, sizeof(GuidString)/sizeof(GuidString[0])); - if(!length) - SetErrBreak((L"Failed to create a Guid string")); - - swprintf (strRegLocation, - L"SYSTEM\\CurrentControlSet\\Control\\Network\\" - L"{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s", - GuidString); - - LONG status; - status = RegOpenKeyExW (HKEY_LOCAL_MACHINE, strRegLocation, 0, - KEY_READ, &hkeyNetwork); - if ((status != ERROR_SUCCESS) || !hkeyNetwork) - SetErrBreak (( - L"Host interface network is not found in registry (%s) [1]", - strRegLocation)); - - status = RegOpenKeyExW (hkeyNetwork, L"Connection", 0, - KEY_READ, &hkeyConnection); - if ((status != ERROR_SUCCESS) || !hkeyConnection) - SetErrBreak (( - L"Host interface network is not found in registry (%s) [2]", - strRegLocation)); - - DWORD len = sizeof (lszPnPInstanceId); - DWORD dwKeyType; - status = RegQueryValueExW (hkeyConnection, L"PnPInstanceID", NULL, - &dwKeyType, (LPBYTE) lszPnPInstanceId, &len); - if ((status != ERROR_SUCCESS) || (dwKeyType != REG_SZ)) - SetErrBreak (( - L"Host interface network is not found in registry (%s) [3]", - strRegLocation)); - } - while (0); - - if (hkeyConnection) - RegCloseKey (hkeyConnection); - if (hkeyNetwork) - RegCloseKey (hkeyNetwork); - - if (FAILED (hrc)) - break; - - /* - * Now we are going to enumerate all network devices and - * wait until we encounter the right device instance ID - */ - - HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE; - - do - { - BOOL ok; - DWORD ret = 0; - GUID netGuid; - SP_DEVINFO_DATA DeviceInfoData; - DWORD index = 0; - BOOL found = FALSE; - DWORD size = 0; - - /* initialize the structure size */ - DeviceInfoData.cbSize = sizeof (SP_DEVINFO_DATA); - - /* copy the net class GUID */ - memcpy (&netGuid, &GUID_DEVCLASS_NET, sizeof (GUID_DEVCLASS_NET)); - - /* return a device info set contains all installed devices of the Net class */ - hDeviceInfo = SetupDiGetClassDevs (&netGuid, NULL, NULL, DIGCF_PRESENT); - - if (hDeviceInfo == INVALID_HANDLE_VALUE) - SetErrBreak ((L"SetupDiGetClassDevs failed (0x%08X)", GetLastError())); - - /* enumerate the driver info list */ - while (TRUE) - { - TCHAR *deviceHwid; - - ok = SetupDiEnumDeviceInfo (hDeviceInfo, index, &DeviceInfoData); - - if (!ok) - { - if (GetLastError() == ERROR_NO_MORE_ITEMS) - break; - else - { - index++; - continue; - } - } - - /* try to get the hardware ID registry property */ - ok = SetupDiGetDeviceRegistryProperty (hDeviceInfo, - &DeviceInfoData, - SPDRP_HARDWAREID, - NULL, - NULL, - 0, - &size); - if (!ok) - { - if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) - { - index++; - continue; - } - - deviceHwid = (TCHAR *) malloc (size); - ok = SetupDiGetDeviceRegistryProperty (hDeviceInfo, - &DeviceInfoData, - SPDRP_HARDWAREID, - NULL, - (PBYTE)deviceHwid, - size, - NULL); - if (!ok) - { - free (deviceHwid); - deviceHwid = NULL; - index++; - continue; - } - } - else - { - /* something is wrong. This shouldn't have worked with a NULL buffer */ - index++; - continue; - } - - for (TCHAR *t = deviceHwid; - t && *t && t < &deviceHwid[size / sizeof(TCHAR)]; - t += _tcslen (t) + 1) - { - if (!_tcsicmp (DRIVERHWID, t)) - { - /* get the device instance ID */ - TCHAR devID [MAX_DEVICE_ID_LEN]; - if (CM_Get_Device_ID(DeviceInfoData.DevInst, - devID, MAX_DEVICE_ID_LEN, 0) == CR_SUCCESS) - { - /* compare to what we determined before */ - if (wcscmp(devID, lszPnPInstanceId) == 0) - { - found = TRUE; - break; - } - } - } - } - - if (deviceHwid) - { - free (deviceHwid); - deviceHwid = NULL; - } - - if (found) - break; - - index++; - } - - if (found == FALSE) - SetErrBreak ((L"Host Interface Network driver not found (0x%08X)", - GetLastError())); - - ok = SetupDiSetSelectedDevice (hDeviceInfo, &DeviceInfoData); - if (!ok) - SetErrBreak ((L"SetupDiSetSelectedDevice failed (0x%08X)", - GetLastError())); - - ok = SetupDiCallClassInstaller (DIF_REMOVE, hDeviceInfo, &DeviceInfoData); - if (!ok) - SetErrBreak ((L"SetupDiCallClassInstaller (DIF_REMOVE) failed (0x%08X)", - GetLastError())); - } - while (0); - - /* clean up the device info set */ - if (hDeviceInfo != INVALID_HANDLE_VALUE) - SetupDiDestroyDeviceInfoList (hDeviceInfo); - - if (FAILED (hrc)) - break; - } - while (0); - -// LogFlowFunc (("vrc=%Rrc\n", vrc)); -// LogFlowFuncLeave(); - return hrc; -} - -static UINT WINAPI vboxNetCfgWinPspFileCallback( - PVOID Context, - UINT Notification, - UINT_PTR Param1, - UINT_PTR Param2 - ) -{ - switch(Notification) - { - case SPFILENOTIFY_TARGETNEWER: - case SPFILENOTIFY_TARGETEXISTS: - return TRUE; - } - return SetupDefaultQueueCallback(Context, Notification, Param1, Param2); -} - -static BOOL vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority (IN INetCfg *pNc, IN INetCfgComponent *pNcc, PVOID pContext) -{ - INetCfgComponentBindings *pNccb = NULL; - IEnumNetCfgBindingPath *pEnumNccbp; - GUID *pGuid = (GUID*)pContext; - HRESULT hr; - bool bFound = false; - - /* Get component's binding. */ - hr = pNcc->QueryInterface( IID_INetCfgComponentBindings, - (PVOID *)&pNccb ); - Assert(hr == S_OK); - if ( hr == S_OK ) - { - /* Get binding path enumerator reference. */ - hr = pNccb->EnumBindingPaths(EBP_BELOW, &pEnumNccbp); - Assert(hr == S_OK); - if(hr == S_OK) - { - INetCfgBindingPath *pNccbp; - hr = pEnumNccbp->Reset(); - Assert(hr == S_OK); - do - { - hr = VBoxNetCfgWinGetNextBindingPath(pEnumNccbp, &pNccbp); - Assert(hr == S_OK || hr == S_FALSE); - if(hr == S_OK) - { -// if(pNccbp->IsEnabled() == S_OK) - { - IEnumNetCfgBindingInterface *pEnumNcbi; - hr = VBoxNetCfgWinGetBindingInterfaceEnum(pNccbp, &pEnumNcbi); - Assert(hr == S_OK); - if ( hr == S_OK ) - { - INetCfgBindingInterface *pNcbi; - hr = pEnumNcbi->Reset(); - Assert(hr == S_OK); - do - { - hr = VBoxNetCfgWinGetNextBindingInterface(pEnumNcbi, &pNcbi); - Assert(hr == S_OK || hr == S_FALSE); - if(hr == S_OK) - { - INetCfgComponent * pNccBoud; - hr = pNcbi->GetLowerComponent(&pNccBoud); - Assert(hr == S_OK); - if(hr == S_OK) - { - ULONG uComponentStatus; - hr = pNccBoud->GetDeviceStatus(&uComponentStatus); - if(hr == S_OK) - { -// if(uComponentStatus == 0) - { - GUID guid; - hr = pNccBoud->GetInstanceGuid(&guid); - if(guid == *pGuid) - { - hr = pNccb->MoveAfter(pNccbp, NULL); - Assert(hr == S_OK); - bFound = true; - } - } - } - VBoxNetCfgWinReleaseRef(pNccBoud); - } - VBoxNetCfgWinReleaseRef(pNcbi); - } - else - { - if(hr == S_FALSE) - { - hr = S_OK; - } - else - { - Log(L"vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority: VBoxNetCfgWinGetNextBindingInterface failed, hr (0x%x)\n", hr); - } - break; - } - } while(!bFound); - VBoxNetCfgWinReleaseRef(pEnumNcbi); - } - else - { - Log(L"vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority: VBoxNetCfgWinGetBindingInterfaceEnum failed, hr (0x%x)\n", hr); - } - } - - VBoxNetCfgWinReleaseRef(pNccbp); - } - else - { - if(hr = S_FALSE) - { - hr = S_OK; - } - else - { - Log(L"vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority: VBoxNetCfgWinGetNextBindingPath failed, hr (0x%x)\n", hr); - } - break; - } - } while(!bFound); - - VBoxNetCfgWinReleaseRef(pEnumNccbp); - } - else - { - Log(L"vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority: EnumBindingPaths failed, hr (0x%x)\n", hr); - } - - VBoxNetCfgWinReleaseRef( pNccb ); - } - else - { - Log(L"vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority: QueryInterface for IID_INetCfgComponentBindings failed, hr (0x%x)\n", hr); - } - - return true; -} - -static BOOL vboxNetCfgWinListUpperBindings (IN INetCfg *pNc, IN INetCfgComponent *pNcc, PVOID pContext) -{ - INetCfgComponentBindings *pNccb = NULL; - IEnumNetCfgBindingPath *pEnumNccbp; - GUID *pGuid = (GUID*)pContext; - HRESULT hr; - LPWSTR pszwCompDisplayName; - - hr = pNcc->GetDisplayName(&pszwCompDisplayName); - Assert(hr == S_OK); - if ( hr == S_OK ) - { - Log(L" enumerating bindings for component (%s)\n", pszwCompDisplayName); - /* Get component's binding. */ - hr = pNcc->QueryInterface( IID_INetCfgComponentBindings, - (PVOID *)&pNccb ); - Assert(hr == S_OK); - if ( hr == S_OK ) - { - /* Get binding path enumerator reference. */ - hr = pNccb->EnumBindingPaths(EBP_ABOVE, &pEnumNccbp); - Assert(hr == S_OK); - if(hr == S_OK) - { - INetCfgBindingPath *pNccbp; - hr = pEnumNccbp->Reset(); - Assert(hr == S_OK); - do - { - hr = VBoxNetCfgWinGetNextBindingPath(pEnumNccbp, &pNccbp); - Assert(hr == S_OK || hr == S_FALSE); - if(hr == S_OK) - { - LPWSTR pszwPathToken; - hr = pNccbp->GetPathToken(&pszwPathToken); - Assert(hr == S_OK); - if(hr == S_OK) - { - Log(L" enumerating bp (%s), enabled(0x%x)\n", pszwPathToken, pNccbp->IsEnabled()); - IEnumNetCfgBindingInterface *pEnumNcbi; - hr = VBoxNetCfgWinGetBindingInterfaceEnum(pNccbp, &pEnumNcbi); - Assert(hr == S_OK); - if ( hr == S_OK ) - { - INetCfgBindingInterface *pNcbi; - hr = pEnumNcbi->Reset(); - Assert(hr == S_OK); - do - { - hr = VBoxNetCfgWinGetNextBindingInterface(pEnumNcbi, &pNcbi); - Assert(hr == S_OK || hr == S_FALSE); - if(hr == S_OK) - { - LPWSTR pszwInterfaceName; - hr = pNcbi->GetName(&pszwInterfaceName); - if(hr == S_OK) - { - Log(L" enumerating bi (%s)\n", pszwInterfaceName); - INetCfgComponent * pNccBoud; - hr = pNcbi->GetUpperComponent(&pNccBoud); - Assert(hr == S_OK); - if(hr == S_OK) - { - LPWSTR pszwDisplayName; - hr = pNccBoud->GetDisplayName(&pszwDisplayName); - Assert(hr == S_OK); - if(hr == S_OK) - { - Log(L" name (%s)\n", pszwDisplayName); - CoTaskMemFree(pszwDisplayName); - } - else - { - Log(L" ERROR getting name (0x%x)\n", hr); - } - - VBoxNetCfgWinReleaseRef(pNccBoud); - } - VBoxNetCfgWinReleaseRef(pNcbi); - } - else - { - Log(L" ERROR getting bi name (0x%x)\n", hr); - } - } - else - { - if(hr == S_FALSE) - { - hr = S_OK; - break; - } - else - { - Log(L"vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority: VBoxNetCfgWinGetNextBindingInterface failed, hr (0x%x)\n", hr); - } - break; - } - } while(true); - VBoxNetCfgWinReleaseRef(pEnumNcbi); - } - else - { - Log(L"vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority: VBoxNetCfgWinGetBindingInterfaceEnum failed, hr (0x%x)\n", hr); - } - CoTaskMemFree(pszwPathToken); - } - else - { - Log(L" ERROR getting bp name (0x%x)\n", hr); - } - - VBoxNetCfgWinReleaseRef(pNccbp); - } - else - { - if(hr = S_FALSE) - { - hr = S_OK; - break; - } - else - { - Log(L"vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority: VBoxNetCfgWinGetNextBindingPath failed, hr (0x%x)\n", hr); - } - break; - } - } while(true); - - VBoxNetCfgWinReleaseRef(pEnumNccbp); - } - else - { - Log(L"vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority: EnumBindingPaths failed, hr (0x%x)\n", hr); - } - - VBoxNetCfgWinReleaseRef( pNccb ); - } - else - { - Log(L"vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority: QueryInterface for IID_INetCfgComponentBindings failed, hr (0x%x)\n", hr); - } - - CoTaskMemFree(pszwCompDisplayName); - } - else - { - Log(L" ERROR getting component name (0x%x)\n", hr); - } - - return true; -} - -VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinCreateHostOnlyNetworkInterface (LPCWSTR pInfPath, bool bIsInfPathFile, /* <- input params */ - GUID *pGuid, BSTR *lppszName, BSTR *pErrMsg) /* <- output params */ -{ - HRESULT hrc = S_OK; - - HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE; - SP_DEVINFO_DATA DeviceInfoData; - PVOID pQueueCallbackContext = NULL; - DWORD ret = 0; - BOOL found = FALSE; - BOOL registered = FALSE; - BOOL destroyList = FALSE; - WCHAR pWCfgGuidString [50]; - WCHAR DevName[256]; - - do - { - BOOL ok; - GUID netGuid; - SP_DRVINFO_DATA DriverInfoData; - SP_DEVINSTALL_PARAMS DeviceInstallParams; - TCHAR className [MAX_PATH]; - DWORD index = 0; - PSP_DRVINFO_DETAIL_DATA pDriverInfoDetail; - /* for our purposes, 2k buffer is more - * than enough to obtain the hardware ID - * of the VBoxNetAdp driver. */ - DWORD detailBuf [2048]; - - HKEY hkey = NULL; - DWORD cbSize; - DWORD dwValueType; - - /* initialize the structure size */ - DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); - DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA); - - /* copy the net class GUID */ - memcpy(&netGuid, &GUID_DEVCLASS_NET, sizeof(GUID_DEVCLASS_NET)); - - /* create an empty device info set associated with the net class GUID */ - hDeviceInfo = SetupDiCreateDeviceInfoList (&netGuid, NULL); - if (hDeviceInfo == INVALID_HANDLE_VALUE) - SetErrBreak ((L"SetupDiCreateDeviceInfoList failed (0x%08X)", - GetLastError())); - - /* get the class name from GUID */ - ok = SetupDiClassNameFromGuid (&netGuid, className, MAX_PATH, NULL); - if (!ok) - SetErrBreak ((L"SetupDiClassNameFromGuid failed (0x%08X)", - GetLastError())); - - /* create a device info element and add the new device instance - * key to registry */ - ok = SetupDiCreateDeviceInfo (hDeviceInfo, className, &netGuid, NULL, NULL, - DICD_GENERATE_ID, &DeviceInfoData); - if (!ok) - SetErrBreak ((L"SetupDiCreateDeviceInfo failed (0x%08X)", - GetLastError())); - - /* select the newly created device info to be the currently - selected member */ - ok = SetupDiSetSelectedDevice (hDeviceInfo, &DeviceInfoData); - if (!ok) - SetErrBreak ((L"SetupDiSetSelectedDevice failed (0x%08X)", - GetLastError())); - - if(pInfPath) - { - /* get the device install parameters and disable filecopy */ - DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); - ok = SetupDiGetDeviceInstallParams (hDeviceInfo, &DeviceInfoData, - &DeviceInstallParams); - if (ok) - { - memset(DeviceInstallParams.DriverPath, 0, sizeof(DeviceInstallParams.DriverPath)); - size_t pathLenght = wcslen(pInfPath) + 1/* null terminator */; - if(pathLenght < sizeof(DeviceInstallParams.DriverPath)/sizeof(DeviceInstallParams.DriverPath[0])) - { - memcpy(DeviceInstallParams.DriverPath, pInfPath, pathLenght*sizeof(DeviceInstallParams.DriverPath[0])); - - if(bIsInfPathFile) - { - DeviceInstallParams.Flags |= DI_ENUMSINGLEINF; - } - - ok = SetupDiSetDeviceInstallParams (hDeviceInfo, &DeviceInfoData, - &DeviceInstallParams); - if(!ok) - { - DWORD winEr = GetLastError(); - Log(L"SetupDiSetDeviceInstallParams: SetupDiSetDeviceInstallParams failed, winEr (%d)\n", winEr); - Assert(0); - break; - } - } - else - { - Log(L"SetupDiSetDeviceInstallParams: inf path is too long\n"); - Assert(0); - break; - } - } - else - { - DWORD winEr = GetLastError(); - Assert(0); - Log(L"VBoxNetCfgWinCreateHostOnlyNetworkInterface: SetupDiGetDeviceInstallParams failed, winEr (%d)\n", winEr); - } - - } - - /* build a list of class drivers */ - ok = SetupDiBuildDriverInfoList (hDeviceInfo, &DeviceInfoData, - SPDIT_CLASSDRIVER); - if (!ok) - SetErrBreak ((L"SetupDiBuildDriverInfoList failed (0x%08X)", - GetLastError())); - - destroyList = TRUE; - - /* enumerate the driver info list */ - while (TRUE) - { - BOOL ret; - - ret = SetupDiEnumDriverInfo (hDeviceInfo, &DeviceInfoData, - SPDIT_CLASSDRIVER, index, &DriverInfoData); - - /* if the function failed and GetLastError() returned - * ERROR_NO_MORE_ITEMS, then we have reached the end of the - * list. Otherwise there was something wrong with this - * particular driver. */ - if (!ret) - { - if(GetLastError() == ERROR_NO_MORE_ITEMS) - break; - else - { - index++; - continue; - } - } - - pDriverInfoDetail = (PSP_DRVINFO_DETAIL_DATA) detailBuf; - pDriverInfoDetail->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA); - - /* if we successfully find the hardware ID and it turns out to - * be the one for the loopback driver, then we are done. */ - if (SetupDiGetDriverInfoDetail (hDeviceInfo, - &DeviceInfoData, - &DriverInfoData, - pDriverInfoDetail, - sizeof (detailBuf), - NULL)) - { - TCHAR * t; - - /* pDriverInfoDetail->HardwareID is a MULTISZ string. Go through the - * whole list and see if there is a match somewhere. */ - t = pDriverInfoDetail->HardwareID; - while (t && *t && t < (TCHAR *) &detailBuf [RT_ELEMENTS(detailBuf)]) - { - if (!_tcsicmp(t, DRIVERHWID)) - break; - - t += _tcslen(t) + 1; - } - - if (t && *t && t < (TCHAR *) &detailBuf [RT_ELEMENTS(detailBuf)]) - { - found = TRUE; - break; - } - } - - index ++; - } - - if (!found) - SetErrBreak ((L"Could not find Host Interface Networking driver! " - L"Please reinstall")); - - /* set the loopback driver to be the currently selected */ - ok = SetupDiSetSelectedDriver (hDeviceInfo, &DeviceInfoData, - &DriverInfoData); - if (!ok) - SetErrBreak ((L"SetupDiSetSelectedDriver failed (0x%08X)", - GetLastError())); - - /* register the phantom device to prepare for install */ - ok = SetupDiCallClassInstaller (DIF_REGISTERDEVICE, hDeviceInfo, - &DeviceInfoData); - if (!ok) - { - DWORD err = GetLastError(); - SetErrBreak ((L"SetupDiCallClassInstaller failed (0x%08X)", - err)); - } - - /* registered, but remove if errors occur in the following code */ - registered = TRUE; - - /* ask the installer if we can install the device */ - ok = SetupDiCallClassInstaller (DIF_ALLOW_INSTALL, hDeviceInfo, - &DeviceInfoData); - if (!ok) - { - if (GetLastError() != ERROR_DI_DO_DEFAULT) - SetErrBreak ((L"SetupDiCallClassInstaller (DIF_ALLOW_INSTALL) failed (0x%08X)", - GetLastError())); - /* that's fine */ - } - - /* get the device install parameters and disable filecopy */ - DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); - ok = SetupDiGetDeviceInstallParams (hDeviceInfo, &DeviceInfoData, - &DeviceInstallParams); - if (ok) - { - pQueueCallbackContext = SetupInitDefaultQueueCallback(NULL); - if(pQueueCallbackContext) - { - DeviceInstallParams.InstallMsgHandlerContext = pQueueCallbackContext; - DeviceInstallParams.InstallMsgHandler = (PSP_FILE_CALLBACK)vboxNetCfgWinPspFileCallback; - ok = SetupDiSetDeviceInstallParams (hDeviceInfo, &DeviceInfoData, - &DeviceInstallParams); - if(!ok) - { - DWORD winEr = GetLastError(); - Assert(0); - Log(L"SetupDiSetDeviceInstallParams: SetupDiSetDeviceInstallParams failed, winEr (%d)\n", winEr); - } - Assert(ok); - } - else - { - DWORD winEr = GetLastError(); - Assert(0); - Log(L"VBoxNetCfgWinCreateHostOnlyNetworkInterface: SetupInitDefaultQueueCallback failed, winEr (%d)\n", winEr); - } - } - else - { - DWORD winEr = GetLastError(); - Assert(0); - Log(L"VBoxNetCfgWinCreateHostOnlyNetworkInterface: SetupDiGetDeviceInstallParams failed, winEr (%d)\n", winEr); - } - - /* install the files first */ - ok = SetupDiCallClassInstaller (DIF_INSTALLDEVICEFILES, hDeviceInfo, - &DeviceInfoData); - if (!ok) - SetErrBreak ((L"SetupDiCallClassInstaller (DIF_INSTALLDEVICEFILES) failed (0x%08X)", - GetLastError())); - - /* get the device install parameters and disable filecopy */ - DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); - ok = SetupDiGetDeviceInstallParams (hDeviceInfo, &DeviceInfoData, - &DeviceInstallParams); - if (ok) - { - DeviceInstallParams.Flags |= DI_NOFILECOPY; - ok = SetupDiSetDeviceInstallParams (hDeviceInfo, &DeviceInfoData, - &DeviceInstallParams); - if (!ok) - SetErrBreak ((L"SetupDiSetDeviceInstallParams failed (0x%08X)", - GetLastError())); - } - - /* - * Register any device-specific co-installers for this device, - */ - - ok = SetupDiCallClassInstaller (DIF_REGISTER_COINSTALLERS, - hDeviceInfo, - &DeviceInfoData); - if (!ok) - SetErrBreak ((L"SetupDiCallClassInstaller (DIF_REGISTER_COINSTALLERS) failed (0x%08X)", - GetLastError())); - - /* - * install any installer-specified interfaces. - * and then do the real install - */ - ok = SetupDiCallClassInstaller (DIF_INSTALLINTERFACES, - hDeviceInfo, - &DeviceInfoData); - if (!ok) - SetErrBreak ((L"SetupDiCallClassInstaller (DIF_INSTALLINTERFACES) failed (0x%08X)", - GetLastError())); - - ok = SetupDiCallClassInstaller (DIF_INSTALLDEVICE, - hDeviceInfo, - &DeviceInfoData); - if (!ok) - SetErrBreak ((L"SetupDiCallClassInstaller (DIF_INSTALLDEVICE) failed (0x%08X)", - GetLastError())); - - /* Figure out NetCfgInstanceId */ - hkey = SetupDiOpenDevRegKey (hDeviceInfo, - &DeviceInfoData, - DICS_FLAG_GLOBAL, - 0, - DIREG_DRV, - KEY_READ); - if (hkey == INVALID_HANDLE_VALUE) - SetErrBreak ((L"SetupDiOpenDevRegKey failed (0x%08X)", - GetLastError())); - - cbSize = sizeof (pWCfgGuidString); - DWORD ret; - ret = RegQueryValueExW (hkey, L"NetCfgInstanceId", NULL, - &dwValueType, (LPBYTE) pWCfgGuidString, &cbSize); - - RegCloseKey (hkey); - - if(!SetupDiGetDeviceRegistryPropertyW(hDeviceInfo, &DeviceInfoData, - SPDRP_FRIENDLYNAME , /* IN DWORD Property,*/ - NULL, /*OUT PDWORD PropertyRegDataType, OPTIONAL*/ - (PBYTE)DevName, /*OUT PBYTE PropertyBuffer,*/ - sizeof(DevName), /* IN DWORD PropertyBufferSize,*/ - NULL /*OUT PDWORD RequiredSize OPTIONAL*/ - )) - { - int err = GetLastError(); - if(err != ERROR_INVALID_DATA) - { - SetErrBreak ((L"SetupDiGetDeviceRegistryProperty failed (0x%08X)", - err)); - } - - if(!SetupDiGetDeviceRegistryPropertyW(hDeviceInfo, &DeviceInfoData, - SPDRP_DEVICEDESC , /* IN DWORD Property,*/ - NULL, /*OUT PDWORD PropertyRegDataType, OPTIONAL*/ - (PBYTE)DevName, /*OUT PBYTE PropertyBuffer,*/ - sizeof(DevName), /* IN DWORD PropertyBufferSize,*/ - NULL /*OUT PDWORD RequiredSize OPTIONAL*/ - )) - { - err = GetLastError(); - SetErrBreak ((L"SetupDiGetDeviceRegistryProperty failed (0x%08X)", - err)); - } - } - } - while (0); - - /* - * cleanup - */ - if(pQueueCallbackContext) - { - SetupTermDefaultQueueCallback(pQueueCallbackContext); - } - - if (hDeviceInfo != INVALID_HANDLE_VALUE) - { - /* an error has occurred, but the device is registered, we must remove it */ - if (ret != 0 && registered) - SetupDiCallClassInstaller (DIF_REMOVE, hDeviceInfo, &DeviceInfoData); - - found = SetupDiDeleteDeviceInfo (hDeviceInfo, &DeviceInfoData); - - /* destroy the driver info list */ - if (destroyList) - SetupDiDestroyDriverInfoList (hDeviceInfo, &DeviceInfoData, - SPDIT_CLASSDRIVER); - /* clean up the device info set */ - SetupDiDestroyDeviceInfoList (hDeviceInfo); - } - - /* return the network connection GUID on success */ - if (SUCCEEDED(hrc)) - { - WCHAR ConnectoinName[128]; - ULONG cbName = sizeof(ConnectoinName); - - HRESULT hr = VBoxNetCfgWinGenHostonlyConnectionName (DevName, ConnectoinName, &cbName); - if(hr == S_OK) - { - hr = VBoxNetCfgWinRenameConnection (pWCfgGuidString, ConnectoinName); - } - - if(lppszName) - { - *lppszName = ::SysAllocString ((const OLECHAR *) DevName); - if ( !*lppszName ) - { - Log(L"VBoxNetCfgWinCreateHostOnlyNetworkInterface: SysAllocString failed\n"); - Assert(0); - hrc = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); - } - } - - if(pGuid) - { - hrc = CLSIDFromString(pWCfgGuidString, (LPCLSID) pGuid); - if(hrc != S_OK) - { - Log(L"VBoxNetCfgWinCreateHostOnlyNetworkInterface: CLSIDFromString failed, hrc (0x%x)\n", hrc); - Assert(0); - } - } - - INetCfg *pNc; - LPWSTR lpszApp = NULL; - - - - hr = VBoxNetCfgWinQueryINetCfgEx( TRUE, - L"VirtualBox Host-Only Creation", - 30000, /* on Vista we often get 6to4svc.dll holding the lock, wait for 30 sec, */ - &pNc, /* TODO: special handling for 6to4svc.dll ???, i.e. several retrieves */ - &lpszApp ); - Assert(hr == S_OK); - if(hr == S_OK) - { - hr = vboxNetCfgWinEnumNetCfgComponents(pNc, - &GUID_DEVCLASS_NETSERVICE, - vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority, - pGuid); - Assert(hr == S_OK); - - hr = vboxNetCfgWinEnumNetCfgComponents(pNc, - &GUID_DEVCLASS_NETTRANS, - vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority, - pGuid); - Assert(hr == S_OK); - - hr = vboxNetCfgWinEnumNetCfgComponents(pNc, - &GUID_DEVCLASS_NETCLIENT, - vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority, - pGuid); - Assert(hr == S_OK); - - if(hr == S_OK) - { - hr = pNc->Apply(); - Assert(hr == S_OK); - } - - VBoxNetCfgWinReleaseINetCfg(pNc, TRUE); - } - else if(hr == NETCFG_E_NO_WRITE_LOCK && lpszApp) - { - Log(L"VBoxNetCfgWinCreateHostOnlyNetworkInterface: app %s is holding the lock, failed\n", lpszApp); - CoTaskMemFree(lpszApp); - } - else - { - Log(L"VBoxNetCfgWinCreateHostOnlyNetworkInterface: VBoxNetCfgWinQueryINetCfgEx failed, hr 0x%x\n", hr); - } - } - - return hrc; -} - -#undef SetErrBreak - -VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinEnumUpperBindings () -{ - INetCfg *pNc; - LPWSTR lpszApp = NULL; - HRESULT hr = VBoxNetCfgWinQueryINetCfgEx( FALSE, - L"VirtualBox Host-Only Creation", - 30000, /* on Vista we often get 6to4svc.dll holding the lock, wait for 30 sec, */ - &pNc, /* TODO: special handling for 6to4svc.dll ???, i.e. several retrieves */ - &lpszApp ); - Assert(hr == S_OK); - if(hr == S_OK) - { - Log(L"Enumerating Net\n"); - hr = vboxNetCfgWinEnumNetCfgComponents(pNc, - &GUID_DEVCLASS_NET, - vboxNetCfgWinListUpperBindings, - NULL); - Assert(hr == S_OK); - - Log(L"Enumerating NetService\n"); - hr = vboxNetCfgWinEnumNetCfgComponents(pNc, - &GUID_DEVCLASS_NETSERVICE, - vboxNetCfgWinListUpperBindings, - NULL); - Assert(hr == S_OK); - - Log(L"Enumerating NetTrans\n"); - hr = vboxNetCfgWinEnumNetCfgComponents(pNc, - &GUID_DEVCLASS_NETTRANS, - vboxNetCfgWinListUpperBindings, - NULL); - Assert(hr == S_OK); - - Log(L"Enumerating NetClient\n"); - hr = vboxNetCfgWinEnumNetCfgComponents(pNc, - &GUID_DEVCLASS_NETCLIENT, - vboxNetCfgWinListUpperBindings, - NULL); - Assert(hr == S_OK); - - if(hr == S_OK) - { - hr = pNc->Apply(); - Assert(hr == S_OK); - } - - VBoxNetCfgWinReleaseINetCfg(pNc, FALSE); - } - else if(hr == NETCFG_E_NO_WRITE_LOCK && lpszApp) - { - Log(L"VBoxNetCfgWinCreateHostOnlyNetworkInterface: app %s is holding the lock, failed\n", lpszApp); - CoTaskMemFree(lpszApp); - } - else - { - Log(L"VBoxNetCfgWinCreateHostOnlyNetworkInterface: VBoxNetCfgWinQueryINetCfgEx failed, hr 0x%x\n", hr); - } - - return hr; -} - - -#define VBOX_CONNECTION_NAME L"VirtualBox Host-Only Network" -VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinGenHostonlyConnectionName (PCWSTR DevName, WCHAR *pBuf, PULONG pcbBuf) -{ - const WCHAR * pSuffix = wcsrchr( DevName, L'#' ); - ULONG cbSize = sizeof(VBOX_CONNECTION_NAME); - ULONG cbSufSize = 0; - - if(pSuffix) - { - cbSize += (ULONG)wcslen(pSuffix) * 2; - cbSize += 2; /* for space */ - } - - if(*pcbBuf < cbSize) - { - *pcbBuf = cbSize; - return E_FAIL; - } - - wcscpy(pBuf, VBOX_CONNECTION_NAME); - if(pSuffix) - { - wcscat(pBuf, L" "); - wcscat(pBuf, pSuffix); - } - - return S_OK; -} - -/* network settings config */ -/** - * Strong referencing operators. Used as a second argument to ComPtr<>/ComObjPtr<>. - */ -template <class C> -class ComStrongRef -{ -protected: - - static void addref (C *p) { p->AddRef(); } - static void release (C *p) { p->Release(); } -}; - -/** - * Weak referencing operators. Used as a second argument to ComPtr<>/ComObjPtr<>. - */ -template <class C> -class ComWeakRef -{ -protected: - - static void addref (C * /* p */) {} - static void release (C * /* p */) {} -}; - -/** - * Base template for smart COM pointers. Not intended to be used directly. - */ -template <class C, template <class> class RefOps = ComStrongRef> -class ComPtrBase : protected RefOps <C> -{ -public: - - /* special template to disable AddRef()/Release() */ - template <class I> - class NoAddRefRelease : public I - { - private: -#if !defined (VBOX_WITH_XPCOM) - STDMETHOD_(ULONG, AddRef)() = 0; - STDMETHOD_(ULONG, Release)() = 0; -#else /* !defined (VBOX_WITH_XPCOM) */ - NS_IMETHOD_(nsrefcnt) AddRef(void) = 0; - NS_IMETHOD_(nsrefcnt) Release(void) = 0; -#endif /* !defined (VBOX_WITH_XPCOM) */ - }; - -protected: - - ComPtrBase () : p (NULL) {} - ComPtrBase (const ComPtrBase &that) : p (that.p) { addref(); } - ComPtrBase (C *that_p) : p (that_p) { addref(); } - - ~ComPtrBase() { release(); } - - ComPtrBase &operator= (const ComPtrBase &that) - { - safe_assign (that.p); - return *this; - } - - ComPtrBase &operator= (C *that_p) - { - safe_assign (that_p); - return *this; - } - -public: - - void setNull() - { - release(); - p = NULL; - } - - bool isNull() const - { - return (p == NULL); - } - - bool operator! () const { return isNull(); } - - bool operator< (C* that_p) const { return p < that_p; } - bool operator== (C* that_p) const { return p == that_p; } - - template <class I> - bool equalsTo (I *aThat) const - { - return ComPtrEquals (p, aThat); - } - - template <class OC> - bool equalsTo (const ComPtrBase <OC> &oc) const - { - return equalsTo ((OC *) oc); - } - - /** Intended to pass instances as in parameters to interface methods */ - operator C* () const { return p; } - - /** - * Dereferences the instance (redirects the -> operator to the managed - * pointer). - */ - NoAddRefRelease <C> *operator-> () const - { - AssertMsg (p, ("Managed pointer must not be null\n")); - return (NoAddRefRelease <C> *) p; - } - - template <class I> - HRESULT queryInterfaceTo (I **pp) const - { - if (pp) - { - if (p) - { - return p->QueryInterface (COM_IIDOF (I), (void **) pp); - } - else - { - *pp = NULL; - return S_OK; - } - } - - return E_INVALIDARG; - } - - /** Intended to pass instances as out parameters to interface methods */ - C **asOutParam() - { - setNull(); - return &p; - } - -private: - - void addref() - { - if (p) - RefOps <C>::addref (p); - } - - void release() - { - if (p) - RefOps <C>::release (p); - } - - void safe_assign (C *that_p) - { - /* be aware of self-assignment */ - if (that_p) - RefOps <C>::addref (that_p); - release(); - p = that_p; - } - - C *p; -}; - -/** - * Smart COM pointer wrapper that automatically manages refcounting of - * interface pointers. - * - * @param I COM interface class - */ -template <class I, template <class> class RefOps = ComStrongRef> -class ComPtr : public ComPtrBase <I, RefOps> -{ - typedef ComPtrBase <I, RefOps> Base; - -public: - - ComPtr () : Base() {} - ComPtr (const ComPtr &that) : Base (that) {} - ComPtr &operator= (const ComPtr &that) - { - Base::operator= (that); - return *this; - } - - template <class OI> - ComPtr (OI *that_p) : Base () { operator= (that_p); } - - /* specialization for I */ - ComPtr (I *that_p) : Base (that_p) {} - - template <class OC> - ComPtr (const ComPtr <OC, RefOps> &oc) : Base () { operator= ((OC *) oc); } - - template <class OI> - ComPtr &operator= (OI *that_p) - { - if (that_p) - that_p->QueryInterface (COM_IIDOF (I), (void **) Base::asOutParam()); - else - Base::setNull(); - return *this; - } - - /* specialization for I */ - ComPtr &operator=(I *that_p) - { - Base::operator= (that_p); - return *this; - } - - template <class OC> - ComPtr &operator= (const ComPtr <OC, RefOps> &oc) - { - return operator= ((OC *) oc); - } -}; - -static HRESULT netIfWinFindAdapterClassById(IWbemServices * pSvc, const GUID * pGuid, IWbemClassObject **pAdapterConfig) -{ - HRESULT hres; - WCHAR aQueryString[256]; - WCHAR GuidString[50]; - - int length = StringFromGUID2(*pGuid, GuidString, sizeof(GuidString)/sizeof(GuidString[0])); - if(length) - { - swprintf(aQueryString, L"SELECT * FROM Win32_NetworkAdapterConfiguration WHERE SettingID = \"%s\"", GuidString); - // Step 6: -------------------------------------------------- - // Use the IWbemServices pointer to make requests of WMI ---- - - IEnumWbemClassObject* pEnumerator = NULL; - hres = pSvc->ExecQuery( - bstr_t("WQL"), - bstr_t(aQueryString), - WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, - NULL, - &pEnumerator); - if(SUCCEEDED(hres)) - { - // Step 7: ------------------------------------------------- - // Get the data from the query in step 6 ------------------- - - IWbemClassObject *pclsObj; - ULONG uReturn = 0; - - if (pEnumerator) - { - HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, - &pclsObj, &uReturn); - - if(SUCCEEDED(hres)) - { - if(uReturn) - { - pEnumerator->Release(); - *pAdapterConfig = pclsObj; - hres = S_OK; - return hres; - } - else - { - hres = S_FALSE; - } - } - - pEnumerator->Release(); - } - } - else - { - Log(L"Query for operating system name failed. Error code = 0x%x\n", hres); - } - } - else - { - DWORD winEr = GetLastError(); - Log(L"Failed to create guid string from guid, winEr (%d)\n", winEr); - hres = HRESULT_FROM_WIN32( winEr ); - } - - return hres; -} - -static HRESULT netIfWinIsHostOnly(IWbemClassObject * pAdapterConfig, BOOL * pbIsHostOnly) -{ - VARIANT vtServiceName; - BOOL bIsHostOnly = FALSE; - VariantInit(&vtServiceName); - - HRESULT hr = pAdapterConfig->Get(L"ServiceName", 0, &vtServiceName, 0, 0); - if(SUCCEEDED(hr)) - { - *pbIsHostOnly = (bstr_t(vtServiceName.bstrVal) == bstr_t("VBoxNetAdp")); - - VariantClear(&vtServiceName); - } - - return hr; -} - -static HRESULT netIfWinGetIpSettings(IWbemClassObject * pAdapterConfig, ULONG *pIpv4, ULONG *pMaskv4) -{ - VARIANT vtIp; - HRESULT hr; - VariantInit(&vtIp); - - *pIpv4 = 0; - *pMaskv4 = 0; - - hr = pAdapterConfig->Get(L"IPAddress", 0, &vtIp, 0, 0); - if(SUCCEEDED(hr)) - { - if(vtIp.vt == (VT_ARRAY | VT_BSTR)) - { - VARIANT vtMask; - VariantInit(&vtMask); - hr = pAdapterConfig->Get(L"IPSubnet", 0, &vtMask, 0, 0); - if(SUCCEEDED(hr)) - { - if(vtMask.vt == (VT_ARRAY | VT_BSTR)) - { - SAFEARRAY * pIpArray = vtIp.parray; - SAFEARRAY * pMaskArray = vtMask.parray; - if(pIpArray && pMaskArray) - { - BSTR pCurIp; - BSTR pCurMask; - for(long index = 0; - SafeArrayGetElement(pIpArray, &index, (PVOID)&pCurIp) == S_OK - && SafeArrayGetElement(pMaskArray, &index, (PVOID)&pCurMask) == S_OK; - index++) - { - _bstr_t ip(pCurIp); - - ULONG Ipv4 = inet_addr((char*)(ip)); - if(Ipv4 != INADDR_NONE) - { - *pIpv4 = Ipv4; - _bstr_t mask(pCurMask); - *pMaskv4 = inet_addr((char*)(mask)); - break; - } - } - } - } - else - { - *pIpv4 = 0; - *pMaskv4 = 0; - } - - VariantClear(&vtMask); - } - } - else - { - *pIpv4 = 0; - *pMaskv4 = 0; - } - - VariantClear(&vtIp); - } - - return hr; -} - - -static HRESULT netIfWinHasIpSettings(IWbemClassObject * pAdapterConfig, SAFEARRAY * pCheckIp, SAFEARRAY * pCheckMask, bool *pFound) -{ - VARIANT vtIp; - HRESULT hr; - VariantInit(&vtIp); - - *pFound = false; - - hr = pAdapterConfig->Get(L"IPAddress", 0, &vtIp, 0, 0); - if(SUCCEEDED(hr)) - { - VARIANT vtMask; - VariantInit(&vtMask); - hr = pAdapterConfig->Get(L"IPSubnet", 0, &vtMask, 0, 0); - if(SUCCEEDED(hr)) - { - SAFEARRAY * pIpArray = vtIp.parray; - SAFEARRAY * pMaskArray = vtMask.parray; - if(pIpArray && pMaskArray) - { - BSTR pIp, pMask; - for(long k = 0; - SafeArrayGetElement(pCheckIp, &k, (PVOID)&pIp) == S_OK - && SafeArrayGetElement(pCheckMask, &k, (PVOID)&pMask) == S_OK; - k++) - { - BSTR pCurIp; - BSTR pCurMask; - for(long index = 0; - SafeArrayGetElement(pIpArray, &index, (PVOID)&pCurIp) == S_OK - && SafeArrayGetElement(pMaskArray, &index, (PVOID)&pCurMask) == S_OK; - index++) - { - if(!wcsicmp(pCurIp, pIp)) - { - if(!wcsicmp(pCurMask, pMask)) - { - *pFound = true; - } - break; - } - } - } - } - - - VariantClear(&vtMask); - } - - VariantClear(&vtIp); - } - - return hr; -} - -static HRESULT netIfWinWaitIpSettings(IWbemServices *pSvc, const GUID * pGuid, SAFEARRAY * pCheckIp, SAFEARRAY * pCheckMask, ULONG sec2Wait, bool *pFound) -{ - /* on Vista we need to wait for the address to get applied */ - /* wait for the address to appear in the list */ - HRESULT hr = S_OK; - ULONG i; - *pFound = false; - ComPtr <IWbemClassObject> pAdapterConfig; - for(i = 0; - (hr = netIfWinFindAdapterClassById(pSvc, pGuid, pAdapterConfig.asOutParam())) == S_OK - && (hr = netIfWinHasIpSettings(pAdapterConfig, pCheckIp, pCheckMask, pFound)) == S_OK - && !(*pFound) - && i < sec2Wait/6; - i++) - { - Sleep(6000); - } - - return hr; -} - -static HRESULT netIfWinCreateIWbemServices(IWbemServices ** ppSvc) -{ - HRESULT hres; - - // Step 3: --------------------------------------------------- - // Obtain the initial locator to WMI ------------------------- - - IWbemLocator *pLoc = NULL; - - hres = CoCreateInstance( - CLSID_WbemLocator, - 0, - CLSCTX_INPROC_SERVER, - IID_IWbemLocator, (LPVOID *) &pLoc); - if(SUCCEEDED(hres)) - { - // Step 4: ----------------------------------------------------- - // Connect to WMI through the IWbemLocator::ConnectServer method - - IWbemServices *pSvc = NULL; - - // Connect to the root\cimv2 namespace with - // the current user and obtain pointer pSvc - // to make IWbemServices calls. - hres = pLoc->ConnectServer( - _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace - NULL, // User name. NULL = current user - NULL, // User password. NULL = current - 0, // Locale. NULL indicates current - NULL, // Security flags. - 0, // Authority (e.g. Kerberos) - 0, // Context object - &pSvc // pointer to IWbemServices proxy - ); - if(SUCCEEDED(hres)) - { - Log(L"Connected to ROOT\\CIMV2 WMI namespace\n"); - - // Step 5: -------------------------------------------------- - // Set security levels on the proxy ------------------------- - - hres = CoSetProxyBlanket( - pSvc, // Indicates the proxy to set - RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx - RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx - NULL, // Server principal name - RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx - RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx - NULL, // client identity - EOAC_NONE // proxy capabilities - ); - if(SUCCEEDED(hres)) - { - *ppSvc = pSvc; - /* do not need it any more */ - pLoc->Release(); - return hres; - } - else - { - Log(L"Could not set proxy blanket. Error code = 0x%x\n", hres); - } - - pSvc->Release(); - } - else - { - Log(L"Could not connect. Error code = 0x%x\n", hres); - } - - pLoc->Release(); - } - else - { - Log(L"Failed to create IWbemLocator object. Err code = 0x%x\n", hres); -// CoUninitialize(); - } - - return hres; -} - -static HRESULT netIfWinAdapterConfigPath(IWbemClassObject *pObj, BSTR * pStr) -{ - VARIANT index; - - // Get the value of the key property - HRESULT hr = pObj->Get(L"Index", 0, &index, 0, 0); - if(SUCCEEDED(hr)) - { - WCHAR strIndex[8]; - swprintf(strIndex, L"%u", index.uintVal); - *pStr = (bstr_t(L"Win32_NetworkAdapterConfiguration.Index='") + strIndex + "'").copy(); - } - else - { - DWORD dwError = GetLastError(); - Assert(0); - hr = HRESULT_FROM_WIN32( dwError ); - } - return hr; -} - -static HRESULT netIfExecMethod(IWbemServices * pSvc, IWbemClassObject *pClass, BSTR ObjPath, - BSTR MethodName, LPWSTR *pArgNames, LPVARIANT *pArgs, UINT cArgs, - IWbemClassObject** ppOutParams - ) -{ - HRESULT hres = S_OK; - // Step 6: -------------------------------------------------- - // Use the IWbemServices pointer to make requests of WMI ---- - - ComPtr<IWbemClassObject> pInParamsDefinition; - ComPtr<IWbemClassObject> pClassInstance; - - if(cArgs) - { - hres = pClass->GetMethod(MethodName, 0, - pInParamsDefinition.asOutParam(), NULL); - if(SUCCEEDED(hres)) - { - hres = pInParamsDefinition->SpawnInstance(0, pClassInstance.asOutParam()); - - if(SUCCEEDED(hres)) - { - for(UINT i = 0; i < cArgs; i++) - { - // Store the value for the in parameters - hres = pClassInstance->Put(pArgNames[i], 0, - pArgs[i], 0); - if(FAILED(hres)) - { - break; - } - } - } - } - } - - if(SUCCEEDED(hres)) - { - IWbemClassObject* pOutParams = NULL; - hres = pSvc->ExecMethod(ObjPath, MethodName, 0, - NULL, pClassInstance, &pOutParams, NULL); - if(SUCCEEDED(hres)) - { - *ppOutParams = pOutParams; - } - } - - return hres; -} - -static HRESULT netIfWinCreateIpArray(SAFEARRAY **ppArray, in_addr* aIp, UINT cIp) -{ - HRESULT hr; - SAFEARRAY * pIpArray = SafeArrayCreateVector(VT_BSTR, 0, cIp); - if(pIpArray) - { - for(UINT i = 0; i < cIp; i++) - { - char* addr = inet_ntoa(aIp[i]); - BSTR val = bstr_t(addr).copy(); - long aIndex[1]; - aIndex[0] = i; - hr = SafeArrayPutElement(pIpArray, aIndex, val); - if(FAILED(hr)) - { - SysFreeString(val); - SafeArrayDestroy(pIpArray); - break; - } - } - - if(SUCCEEDED(hr)) - { - *ppArray = pIpArray; - } - } - else - { - DWORD dwError = GetLastError(); - Assert(0); - hr = HRESULT_FROM_WIN32( dwError ); - } - - return hr; -} - -static HRESULT netIfWinCreateIpArrayV4V6(SAFEARRAY **ppArray, BSTR Ip) -{ - HRESULT hr; - SAFEARRAY * pIpArray = SafeArrayCreateVector(VT_BSTR, 0, 1); - if(pIpArray) - { - BSTR val = bstr_t(Ip, false).copy(); - long aIndex[1]; - aIndex[0] = 0; - hr = SafeArrayPutElement(pIpArray, aIndex, val); - if(FAILED(hr)) - { - SysFreeString(val); - SafeArrayDestroy(pIpArray); - } - - if(SUCCEEDED(hr)) - { - *ppArray = pIpArray; - } - } - else - { - DWORD dwError = GetLastError(); - Assert(0); - hr = HRESULT_FROM_WIN32( dwError ); - } - - return hr; -} - - -static HRESULT netIfWinCreateIpArrayVariantV4(VARIANT * pIpAddresses, in_addr* aIp, UINT cIp) -{ - HRESULT hr; - VariantInit(pIpAddresses); - pIpAddresses->vt = VT_ARRAY | VT_BSTR; - SAFEARRAY *pIpArray; - hr = netIfWinCreateIpArray(&pIpArray, aIp, cIp); - if(SUCCEEDED(hr)) - { - pIpAddresses->parray = pIpArray; - } - return hr; -} - -static HRESULT netIfWinCreateIpArrayVariantV4V6(VARIANT * pIpAddresses, BSTR Ip) -{ - HRESULT hr; - VariantInit(pIpAddresses); - pIpAddresses->vt = VT_ARRAY | VT_BSTR; - SAFEARRAY *pIpArray; - hr = netIfWinCreateIpArrayV4V6(&pIpArray, Ip); - if(SUCCEEDED(hr)) - { - pIpAddresses->parray = pIpArray; - } - return hr; -} - -static HRESULT netIfWinEnableStatic(IWbemServices * pSvc, const GUID * pGuid, BSTR ObjPath, VARIANT * pIp, VARIANT * pMask) -{ - ComPtr<IWbemClassObject> pClass; - BSTR ClassName = SysAllocString(L"Win32_NetworkAdapterConfiguration"); - HRESULT hr; - if(ClassName) - { - hr = pSvc->GetObject(ClassName, 0, NULL, pClass.asOutParam(), NULL); - if(SUCCEEDED(hr)) - { - LPWSTR argNames[] = {L"IPAddress", L"SubnetMask"}; - LPVARIANT args[] = {pIp, pMask}; - ComPtr<IWbemClassObject> pOutParams; - - hr = netIfExecMethod(pSvc, pClass, ObjPath, - bstr_t(L"EnableStatic"), argNames, args, 2, pOutParams.asOutParam()); - if(SUCCEEDED(hr)) - { - VARIANT varReturnValue; - hr = pOutParams->Get(bstr_t(L"ReturnValue"), 0, - &varReturnValue, NULL, 0); - Assert(SUCCEEDED(hr)); - if(SUCCEEDED(hr)) - { -// Assert(varReturnValue.vt == VT_UINT); - int winEr = varReturnValue.uintVal; - switch(winEr) - { - case 0: - { - hr = S_OK; -// bool bFound; -// HRESULT tmpHr = netIfWinWaitIpSettings(pSvc, pGuid, pIp->parray, pMask->parray, 180, &bFound); - } - break; - default: - hr = HRESULT_FROM_WIN32( winEr ); - break; - } - } - } - } - SysFreeString(ClassName); - } - else - { - DWORD dwError = GetLastError(); - Assert(0); - hr = HRESULT_FROM_WIN32( dwError ); - } - - return hr; -} - - -static HRESULT netIfWinEnableStaticV4(IWbemServices * pSvc, const GUID * pGuid, BSTR ObjPath, in_addr* aIp, in_addr * aMask, UINT cIp) -{ - VARIANT ipAddresses; - HRESULT hr = netIfWinCreateIpArrayVariantV4(&ipAddresses, aIp, cIp); - if(SUCCEEDED(hr)) - { - VARIANT ipMasks; - hr = netIfWinCreateIpArrayVariantV4(&ipMasks, aMask, cIp); - if(SUCCEEDED(hr)) - { - hr = netIfWinEnableStatic(pSvc, pGuid, ObjPath, &ipAddresses, &ipMasks); - VariantClear(&ipMasks); - } - VariantClear(&ipAddresses); - } - return hr; -} - -static HRESULT netIfWinEnableStaticV4V6(IWbemServices * pSvc, const GUID * pGuid, BSTR ObjPath, BSTR Ip, BSTR Mask) -{ - VARIANT ipAddresses; - HRESULT hr = netIfWinCreateIpArrayVariantV4V6(&ipAddresses, Ip); - if(SUCCEEDED(hr)) - { - VARIANT ipMasks; - hr = netIfWinCreateIpArrayVariantV4V6(&ipMasks, Mask); - if(SUCCEEDED(hr)) - { - hr = netIfWinEnableStatic(pSvc, pGuid, ObjPath, &ipAddresses, &ipMasks); - VariantClear(&ipMasks); - } - VariantClear(&ipAddresses); - } - return hr; -} - -/* win API allows to set gw metrics as well, we are not setting them */ -static HRESULT netIfWinSetGateways(IWbemServices * pSvc, BSTR ObjPath, VARIANT * pGw) -{ - ComPtr<IWbemClassObject> pClass; - BSTR ClassName = SysAllocString(L"Win32_NetworkAdapterConfiguration"); - HRESULT hr; - if(ClassName) - { - hr = pSvc->GetObject(ClassName, 0, NULL, pClass.asOutParam(), NULL); - if(SUCCEEDED(hr)) - { - LPWSTR argNames[] = {L"DefaultIPGateway"}; - LPVARIANT args[] = {pGw}; - ComPtr<IWbemClassObject> pOutParams; - - hr = netIfExecMethod(pSvc, pClass, ObjPath, - bstr_t(L"SetGateways"), argNames, args, 1, pOutParams.asOutParam()); - if(SUCCEEDED(hr)) - { - VARIANT varReturnValue; - hr = pOutParams->Get(bstr_t(L"ReturnValue"), 0, - &varReturnValue, NULL, 0); - Assert(SUCCEEDED(hr)); - if(SUCCEEDED(hr)) - { -// Assert(varReturnValue.vt == VT_UINT); - int winEr = varReturnValue.uintVal; - switch(winEr) - { - case 0: - hr = S_OK; - break; - default: - hr = HRESULT_FROM_WIN32( winEr ); - break; - } - } - } } - SysFreeString(ClassName); - } - else - { - DWORD dwError = GetLastError(); - Assert(0); - hr = HRESULT_FROM_WIN32( dwError ); - } - - return hr; -} - -/* win API allows to set gw metrics as well, we are not setting them */ -static HRESULT netIfWinSetGatewaysV4(IWbemServices * pSvc, BSTR ObjPath, in_addr* aGw, UINT cGw) -{ - VARIANT gwais; - HRESULT hr = netIfWinCreateIpArrayVariantV4(&gwais, aGw, cGw); - if(SUCCEEDED(hr)) - { - netIfWinSetGateways(pSvc, ObjPath, &gwais); - VariantClear(&gwais); - } - return hr; -} - -/* win API allows to set gw metrics as well, we are not setting them */ -static HRESULT netIfWinSetGatewaysV4V6(IWbemServices * pSvc, BSTR ObjPath, BSTR Gw) -{ - VARIANT vGw; - HRESULT hr = netIfWinCreateIpArrayVariantV4V6(&vGw, Gw); - if(SUCCEEDED(hr)) - { - netIfWinSetGateways(pSvc, ObjPath, &vGw); - VariantClear(&vGw); - } - return hr; -} - -static HRESULT netIfWinEnableDHCP(IWbemServices * pSvc, BSTR ObjPath) -{ - ComPtr<IWbemClassObject> pClass; - BSTR ClassName = SysAllocString(L"Win32_NetworkAdapterConfiguration"); - HRESULT hr; - if(ClassName) - { - hr = pSvc->GetObject(ClassName, 0, NULL, pClass.asOutParam(), NULL); - if(SUCCEEDED(hr)) - { - ComPtr<IWbemClassObject> pOutParams; - - hr = netIfExecMethod(pSvc, pClass, ObjPath, - bstr_t(L"EnableDHCP"), NULL, NULL, 0, pOutParams.asOutParam()); - if(SUCCEEDED(hr)) - { - VARIANT varReturnValue; - hr = pOutParams->Get(bstr_t(L"ReturnValue"), 0, - &varReturnValue, NULL, 0); - Assert(SUCCEEDED(hr)); - if(SUCCEEDED(hr)) - { -// Assert(varReturnValue.vt == VT_UINT); - int winEr = varReturnValue.uintVal; - switch(winEr) - { - case 0: - hr = S_OK; - break; - default: - hr = HRESULT_FROM_WIN32( winEr ); - break; - } - } - } - } - SysFreeString(ClassName); - } - else - { - DWORD dwError = GetLastError(); - Assert(0); - hr = HRESULT_FROM_WIN32( dwError ); - } - - return hr; -} - -static HRESULT netIfWinDhcpRediscover(IWbemServices * pSvc, BSTR ObjPath) -{ - ComPtr<IWbemClassObject> pClass; - BSTR ClassName = SysAllocString(L"Win32_NetworkAdapterConfiguration"); - HRESULT hr; - if(ClassName) - { - hr = pSvc->GetObject(ClassName, 0, NULL, pClass.asOutParam(), NULL); - if(SUCCEEDED(hr)) - { - ComPtr<IWbemClassObject> pOutParams; - - hr = netIfExecMethod(pSvc, pClass, ObjPath, - bstr_t(L"ReleaseDHCPLease"), NULL, NULL, 0, pOutParams.asOutParam()); - if(SUCCEEDED(hr)) - { - VARIANT varReturnValue; - hr = pOutParams->Get(bstr_t(L"ReturnValue"), 0, - &varReturnValue, NULL, 0); - Assert(SUCCEEDED(hr)); - if(SUCCEEDED(hr)) - { -// Assert(varReturnValue.vt == VT_UINT); - int winEr = varReturnValue.uintVal; - if(winEr == 0) - { - hr = netIfExecMethod(pSvc, pClass, ObjPath, - bstr_t(L"RenewDHCPLease"), NULL, NULL, 0, pOutParams.asOutParam()); - if(SUCCEEDED(hr)) - { - VARIANT varReturnValue; - hr = pOutParams->Get(bstr_t(L"ReturnValue"), 0, - &varReturnValue, NULL, 0); - Assert(SUCCEEDED(hr)); - if(SUCCEEDED(hr)) - { - // Assert(varReturnValue.vt == VT_UINT); - int winEr = varReturnValue.uintVal; - if(winEr == 0) - { - hr = S_OK; - } - else - { - hr = HRESULT_FROM_WIN32( winEr ); - } - } - } - } - else - { - hr = HRESULT_FROM_WIN32( winEr ); - } - } - } - } - SysFreeString(ClassName); - } - else - { - DWORD dwError = GetLastError(); - Assert(0); - hr = HRESULT_FROM_WIN32( dwError ); - } - - return hr; -} - -static HRESULT vboxNetCfgWinIsDhcpEnabled(IWbemClassObject * pAdapterConfig, BOOL *pEnabled) -{ - VARIANT vtEnabled; - HRESULT hr = pAdapterConfig->Get(L"DHCPEnabled", 0, &vtEnabled, 0, 0); - if(SUCCEEDED(hr)) - { - *pEnabled = vtEnabled.boolVal; - } - return hr; -} - -VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinGetAdapterSettings(const GUID * pGuid, PADAPTER_SETTINGS pSettings) -{ - HRESULT hr; - ComPtr <IWbemServices> pSvc; - hr = netIfWinCreateIWbemServices(pSvc.asOutParam()); - if(SUCCEEDED(hr)) - { - ComPtr <IWbemClassObject> pAdapterConfig; - hr = netIfWinFindAdapterClassById(pSvc, pGuid, pAdapterConfig.asOutParam()); - if(hr == S_OK) - { - hr = vboxNetCfgWinIsDhcpEnabled(pAdapterConfig, &pSettings->bDhcp); - if(SUCCEEDED(hr)) - { - hr = netIfWinGetIpSettings(pAdapterConfig, &pSettings->ip, &pSettings->mask); - } - } - } - - return hr; -} - -VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinIsDhcpEnabled(const GUID * pGuid, BOOL *pEnabled) -{ - HRESULT hr; - ComPtr <IWbemServices> pSvc; - hr = netIfWinCreateIWbemServices(pSvc.asOutParam()); - if(SUCCEEDED(hr)) - { - ComPtr <IWbemClassObject> pAdapterConfig; - hr = netIfWinFindAdapterClassById(pSvc, pGuid, pAdapterConfig.asOutParam()); - if(hr == S_OK) - { - VARIANT vtEnabled; - hr = pAdapterConfig->Get(L"DHCPEnabled", 0, &vtEnabled, 0, 0); - if(SUCCEEDED(hr)) - { - *pEnabled = vtEnabled.boolVal; - } - } - } - - return hr; -} - -VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinEnableStaticIpConfig(const GUID *pGuid, ULONG ip, ULONG mask) -{ - HRESULT hr; - ComPtr <IWbemServices> pSvc; - hr = netIfWinCreateIWbemServices(pSvc.asOutParam()); - if(SUCCEEDED(hr)) - { - ComPtr <IWbemClassObject> pAdapterConfig; - hr = netIfWinFindAdapterClassById(pSvc, pGuid, pAdapterConfig.asOutParam()); - if(hr == S_OK) - { - BOOL bIsHostOnly; - hr = netIfWinIsHostOnly(pAdapterConfig, &bIsHostOnly); - if(SUCCEEDED(hr)) - { - if(bIsHostOnly) - { - in_addr aIp[1]; - in_addr aMask[1]; - aIp[0].S_un.S_addr = ip; - aMask[0].S_un.S_addr = mask; - - BSTR ObjPath; - hr = netIfWinAdapterConfigPath(pAdapterConfig, &ObjPath); - if(SUCCEEDED(hr)) - { - hr = netIfWinEnableStaticV4(pSvc, pGuid, ObjPath, aIp, aMask, ip != 0 ? 1 : 0); - if(SUCCEEDED(hr)) - { -#if 0 - in_addr aGw[1]; - aGw[0].S_un.S_addr = gw; - hr = netIfWinSetGatewaysV4(pSvc, ObjPath, aGw, 1); - if(SUCCEEDED(hr)) -#endif - { - } - } - SysFreeString(ObjPath); - } - } - else - { - hr = E_FAIL; - } - } - } - } - - return hr; -} - -#if 0 -static HRESULT netIfEnableStaticIpConfigV6(const GUID *pGuid, IN_BSTR aIPV6Address, IN_BSTR aIPV6Mask, IN_BSTR aIPV6DefaultGateway) -{ - HRESULT hr; - ComPtr <IWbemServices> pSvc; - hr = netIfWinCreateIWbemServices(pSvc.asOutParam()); - if(SUCCEEDED(hr)) - { - ComPtr <IWbemClassObject> pAdapterConfig; - hr = netIfWinFindAdapterClassById(pSvc, pGuid, pAdapterConfig.asOutParam()); - if(hr == S_OK) - { - BSTR ObjPath; - hr = netIfWinAdapterConfigPath(pAdapterConfig, &ObjPath); - if(SUCCEEDED(hr)) - { - hr = netIfWinEnableStaticV4V6(pSvc, pAdapterConfig, ObjPath, aIPV6Address, aIPV6Mask); - if(SUCCEEDED(hr)) - { - if(aIPV6DefaultGateway) - { - hr = netIfWinSetGatewaysV4V6(pSvc, ObjPath, aIPV6DefaultGateway); - } - if(SUCCEEDED(hr)) - { -// hr = netIfWinUpdateConfig(pIf); - } - } - SysFreeString(ObjPath); - } - } - } - - return SUCCEEDED(hr) ? VINF_SUCCESS : VERR_GENERAL_FAILURE; -} - -static HRESULT netIfEnableStaticIpConfigV6(const GUID *pGuid, IN_BSTR aIPV6Address, ULONG aIPV6MaskPrefixLength) -{ - RTNETADDRIPV6 Mask; - int rc = prefixLength2IPv6Address(aIPV6MaskPrefixLength, &Mask); - if(RT_SUCCESS(rc)) - { - Bstr maskStr = composeIPv6Address(&Mask); - rc = netIfEnableStaticIpConfigV6(pGuid, aIPV6Address, maskStr, NULL); - } - return rc; -} -#endif - -VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinEnableDynamicIpConfig(const GUID *pGuid) -{ - HRESULT hr; - ComPtr <IWbemServices> pSvc; - hr = netIfWinCreateIWbemServices(pSvc.asOutParam()); - if(SUCCEEDED(hr)) - { - ComPtr <IWbemClassObject> pAdapterConfig; - hr = netIfWinFindAdapterClassById(pSvc, pGuid, pAdapterConfig.asOutParam()); - if(hr == S_OK) - { - BOOL bIsHostOnly; - hr = netIfWinIsHostOnly(pAdapterConfig, &bIsHostOnly); - if(SUCCEEDED(hr)) - { - if(bIsHostOnly) - { - BSTR ObjPath; - hr = netIfWinAdapterConfigPath(pAdapterConfig, &ObjPath); - if(SUCCEEDED(hr)) - { - hr = netIfWinEnableDHCP(pSvc, ObjPath); - if(SUCCEEDED(hr)) - { -// hr = netIfWinUpdateConfig(pIf); - } - SysFreeString(ObjPath); - } - } - else - { - hr = E_FAIL; - } - } - } - } - - - return hr; -} - -VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinDhcpRediscover(const GUID *pGuid) -{ - HRESULT hr; - ComPtr <IWbemServices> pSvc; - hr = netIfWinCreateIWbemServices(pSvc.asOutParam()); - if(SUCCEEDED(hr)) - { - ComPtr <IWbemClassObject> pAdapterConfig; - hr = netIfWinFindAdapterClassById(pSvc, pGuid, pAdapterConfig.asOutParam()); - if(hr == S_OK) - { - BOOL bIsHostOnly; - hr = netIfWinIsHostOnly(pAdapterConfig, &bIsHostOnly); - if(SUCCEEDED(hr)) - { - if(bIsHostOnly) - { - BSTR ObjPath; - hr = netIfWinAdapterConfigPath(pAdapterConfig, &ObjPath); - if(SUCCEEDED(hr)) - { - hr = netIfWinDhcpRediscover(pSvc, ObjPath); - if(SUCCEEDED(hr)) - { -// hr = netIfWinUpdateConfig(pIf); - } - SysFreeString(ObjPath); - } - } - else - { - hr = E_FAIL; - } - } - } - } - - - return hr; -} - -typedef bool (*IPSETTINGS_CALLBACK) (ULONG ip, ULONG mask, PVOID pContext); - -static void vboxNetCfgWinEnumIpConfig(PIP_ADAPTER_ADDRESSES pAddresses, IPSETTINGS_CALLBACK pCallback, PVOID pContext) -{ - PIP_ADAPTER_ADDRESSES pAdapter; - for (pAdapter = pAddresses; pAdapter; pAdapter = pAdapter->Next) - { - PIP_ADAPTER_UNICAST_ADDRESS pAddr = pAdapter->FirstUnicastAddress; - PIP_ADAPTER_PREFIX pPrefix = pAdapter->FirstPrefix; - - if(pAddr && pPrefix) - { - do - { - bool fIPFound, fMaskFound; - fIPFound = fMaskFound = false; - ULONG ip, mask; - for (; pAddr && !fIPFound; pAddr = pAddr->Next) - { - switch (pAddr->Address.lpSockaddr->sa_family) - { - case AF_INET: - fIPFound = true; - memcpy(&ip, - &((struct sockaddr_in *)pAddr->Address.lpSockaddr)->sin_addr.s_addr, - sizeof(ip)); - break; -// case AF_INET6: -// break; - } - } - - for (; pPrefix && !fMaskFound; pPrefix = pPrefix->Next) - { - switch (pPrefix->Address.lpSockaddr->sa_family) - { - case AF_INET: - if(!pPrefix->PrefixLength || pPrefix->PrefixLength > 31) /* in case the ip helper API is queried while NetCfg write lock is held */ - break; /* the address values can contain illegal values */ - fMaskFound = true; - mask = (~(((ULONG)~0) >> pPrefix->PrefixLength)); - mask = htonl(mask); - break; -// case AF_INET6: -// break; - } - } - - if(!fIPFound || !fMaskFound) - break; - - if(!pCallback(ip, mask, pContext)) - return; - }while(true); - } - } -} - -typedef struct _IPPROBE_CONTEXT -{ - ULONG Prefix; - bool bConflict; -}IPPROBE_CONTEXT, *PIPPROBE_CONTEXT; - -#define IPPROBE_INIT(_pContext, _addr) \ - ((_pContext)->bConflict = false, \ - (_pContext)->Prefix = _addr) - -#define IPPROBE_INIT_STR(_pContext, _straddr) \ - IPROBE_INIT(_pContext, inet_addr(_straddr)) - -static bool vboxNetCfgWinIpProbeCallback (ULONG ip, ULONG mask, PVOID pContext) -{ - PIPPROBE_CONTEXT pProbe = (PIPPROBE_CONTEXT)pContext; - - if((ip & mask) == (pProbe->Prefix & mask)) - { - pProbe->bConflict = true; - return false; - } - - return true; -} - -VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinGenHostOnlyNetworkNetworkIp(PULONG pNetIp, PULONG pNetMask) -{ - DWORD dwRc; - HRESULT hr = S_OK; - /* - * Most of the hosts probably have less than 10 adapters, - * so we'll mostly succeed from the first attempt. - */ - ULONG uBufLen = sizeof(IP_ADAPTER_ADDRESSES) * 10; - PIP_ADAPTER_ADDRESSES pAddresses = (PIP_ADAPTER_ADDRESSES)malloc(uBufLen); - if (!pAddresses) - return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); - dwRc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &uBufLen); - if (dwRc == ERROR_BUFFER_OVERFLOW) - { - /* Impressive! More than 10 adapters! Get more memory and try again. */ - free(pAddresses); - pAddresses = (PIP_ADAPTER_ADDRESSES)malloc(uBufLen); - if (!pAddresses) - return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); - dwRc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &uBufLen); - } - if (dwRc == NO_ERROR) - { - IPPROBE_CONTEXT Context; - const ULONG ip192168 = inet_addr("192.168.0.0"); - srand(GetTickCount()); - - *pNetIp = 0; - *pNetMask = 0; - - for(int i = 0; i < 255; i++) - { - ULONG ipProbe = rand()*255/RAND_MAX; - ipProbe = ip192168 | (ipProbe << 16); - IPPROBE_INIT(&Context, ipProbe); - vboxNetCfgWinEnumIpConfig(pAddresses, vboxNetCfgWinIpProbeCallback, &Context); - if(!Context.bConflict) - { - *pNetIp = ipProbe; - *pNetMask = inet_addr("255.255.255.0"); - break; - } - } - if(*pNetIp == 0) - dwRc = ERROR_DHCP_ADDRESS_CONFLICT; - } - else - { - Log(L"VBoxNetCfgWinGenHostOnlyNetworkNetworkIp: GetAdaptersAddresses err (%d)\n", dwRc); - } - free(pAddresses); - - if(dwRc != NO_ERROR) - { - hr = HRESULT_FROM_WIN32(dwRc); - } - - return hr; -} diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/Makefile.kup b/src/VBox/HostDrivers/VBoxNetFlt/win/cfg/Makefile.kup index e69de29bb..e69de29bb 100644 --- a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/Makefile.kup +++ b/src/VBox/HostDrivers/VBoxNetFlt/win/cfg/Makefile.kup diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/cfg/VBoxNetCfg.cpp b/src/VBox/HostDrivers/VBoxNetFlt/win/cfg/VBoxNetCfg.cpp new file mode 100644 index 000000000..9692ff87d --- /dev/null +++ b/src/VBox/HostDrivers/VBoxNetFlt/win/cfg/VBoxNetCfg.cpp @@ -0,0 +1,2771 @@ +/* $Id: VBoxNetCfg.cpp 37301 2011-06-01 19:57:39Z vboxsync $ */ +/** @file + * VBoxNetCfg.cpp - Network Configuration API. + */ +/* + * Copyright (C) 2011 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + */ +#include "VBox/VBoxNetCfg-win.h" +#include "VBox/VBoxDrvCfg-win.h" + +#define _WIN32_DCOM + +#include <iphlpapi.h> + +#include <devguid.h> +#include <stdio.h> +#include <regstr.h> +#include <shlobj.h> +#include <cfgmgr32.h> +#include <tchar.h> +#include <objbase.h> + +#include <crtdbg.h> +#include <stdlib.h> +#include <string.h> + +#include <Wbemidl.h> +#include <comdef.h> + + +#ifndef Assert +//# ifdef DEBUG +//# define Assert(_expr) assert(_expr) +//# else +//# define Assert(_expr) do{ }while (0) +//# endif +# define Assert _ASSERT +# define AssertMsg(expr, msg) do{}while (0) +#endif +static LOG_ROUTINE g_Logger = NULL; + +static VOID DoLogging(LPCSTR szString, ...); +#define Log DoLogging +#define LogFlow(x) DoLogging x + +#define DbgLog + +#define VBOX_NETCFG_LOCK_TIME_OUT 5000 + + +static HRESULT vboxNetCfgWinINetCfgLock(IN INetCfg *pNetCfg, + IN LPCWSTR pszwClientDescription, + IN DWORD cmsTimeout, + OUT LPWSTR *ppszwClientDescription) +{ + INetCfgLock *pLock; + HRESULT hr = pNetCfg->QueryInterface(IID_INetCfgLock, (PVOID*)&pLock); + if (FAILED(hr)) + { + LogFlow(("QueryInterface failed, hr (0x%x)\n", hr)); + return hr; + } + + hr = pLock->AcquireWriteLock(cmsTimeout, pszwClientDescription, ppszwClientDescription); + if (hr == S_FALSE) + { + LogFlow(("Write lock busy\n")); + } + else if (FAILED(hr)) + { + LogFlow(("AcquireWriteLock failed, hr (0x%x)\n", hr)); + } + + pLock->Release(); + return hr; +} + +static HRESULT vboxNetCfgWinINetCfgUnlock(IN INetCfg *pNetCfg) +{ + INetCfgLock *pLock; + HRESULT hr = pNetCfg->QueryInterface(IID_INetCfgLock, (PVOID*)&pLock); + if (FAILED(hr)) + { + LogFlow(("QueryInterface failed, hr (0x%x)\n", hr)); + return hr; + } + + hr = pLock->ReleaseWriteLock(); + if (FAILED(hr)) + LogFlow(("ReleaseWriteLock failed, hr (0x%x)\n", hr)); + + pLock->Release(); + return hr; +} + +VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinQueryINetCfg(OUT INetCfg **ppNetCfg, + IN BOOL fGetWriteLock, + IN LPCWSTR pszwClientDescription, + IN DWORD cmsTimeout, + OUT LPWSTR *ppszwClientDescription) +{ + INetCfg *pNetCfg; + HRESULT hr = CoCreateInstance(CLSID_CNetCfg, NULL, CLSCTX_INPROC_SERVER, IID_INetCfg, (PVOID*)&pNetCfg); + if (FAILED(hr)) + { + LogFlow(("CoCreateInstance failed, hr (0x%x)\n", hr)); + return hr; + } + + if (fGetWriteLock) + { + hr = vboxNetCfgWinINetCfgLock(pNetCfg, pszwClientDescription, cmsTimeout, ppszwClientDescription); + if (hr == S_FALSE) + { + LogFlow(("Write lock is busy\n", hr)); + hr = NETCFG_E_NO_WRITE_LOCK; + } + } + + if (SUCCEEDED(hr)) + { + hr = pNetCfg->Initialize(NULL); + if (SUCCEEDED(hr)) + { + *ppNetCfg = pNetCfg; + return S_OK; + } + else + LogFlow(("Initialize failed, hr (0x%x)\n", hr)); + } + + pNetCfg->Release(); + return hr; +} + +VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinReleaseINetCfg(IN INetCfg *pNetCfg, IN BOOL fHasWriteLock) +{ + HRESULT hr = pNetCfg->Uninitialize(); + if (FAILED(hr)) + { + LogFlow(("Uninitialize failed, hr (0x%x)\n", hr)); + return hr; + } + + if (fHasWriteLock) + { + hr = vboxNetCfgWinINetCfgUnlock(pNetCfg); + if (FAILED(hr)) + LogFlow(("vboxNetCfgWinINetCfgUnlock failed, hr (0x%x)\n", hr)); + } + + pNetCfg->Release(); + return hr; +} + +static HRESULT vboxNetCfgWinGetComponentByGuidEnum(IEnumNetCfgComponent *pEnumNcc, + IN const GUID *pGuid, + OUT INetCfgComponent **ppNcc) +{ + HRESULT hr = pEnumNcc->Reset(); + if (FAILED(hr)) + { + LogFlow(("Reset failed, hr (0x%x)\n", hr)); + return hr; + } + + INetCfgComponent *pNcc; + while ((hr = pEnumNcc->Next(1, &pNcc, NULL)) == S_OK) + { + ULONG uComponentStatus; + hr = pNcc->GetDeviceStatus(&uComponentStatus); + if (SUCCEEDED(hr)) + { + if (uComponentStatus == 0) + { + GUID NccGuid; + hr = pNcc->GetInstanceGuid(&NccGuid); + + if (SUCCEEDED(hr)) + { + if (NccGuid == *pGuid) + { + /* found the needed device */ + *ppNcc = pNcc; + break; + } + } + else + LogFlow(("GetInstanceGuid failed, hr (0x%x)\n", hr)); + } + } + + pNcc->Release(); + } + return hr; +} + +VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinGetComponentByGuid(IN INetCfg *pNc, + IN const GUID *pguidClass, + IN const GUID * pComponentGuid, + OUT INetCfgComponent **ppncc) +{ + IEnumNetCfgComponent *pEnumNcc; + HRESULT hr = pNc->EnumComponents(pguidClass, &pEnumNcc); + + if (SUCCEEDED(hr)) + { + hr = vboxNetCfgWinGetComponentByGuidEnum(pEnumNcc, pComponentGuid, ppncc); + if (hr == S_FALSE) + { + LogFlow(("Component not found\n")); + } + else if (FAILED(hr)) + { + LogFlow(("vboxNetCfgWinGetComponentByGuidEnum failed, hr (0x%x)\n", hr)); + } + pEnumNcc->Release(); + } + else + LogFlow(("EnumComponents failed, hr (0x%x)\n", hr)); + return hr; +} + +static HRESULT vboxNetCfgWinQueryInstaller(IN INetCfg *pNetCfg, IN const GUID *pguidClass, INetCfgClassSetup **ppSetup) +{ + HRESULT hr = pNetCfg->QueryNetCfgClass(pguidClass, IID_INetCfgClassSetup, (void**)ppSetup); + if (FAILED(hr)) + LogFlow(("QueryNetCfgClass failed, hr (0x%x)\n", hr)); + return hr; +} + +VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinInstallComponent(IN INetCfg *pNetCfg, IN LPCWSTR pszwComponentId, IN const GUID *pguidClass, + OUT INetCfgComponent **ppComponent) +{ + INetCfgClassSetup *pSetup; + HRESULT hr = vboxNetCfgWinQueryInstaller(pNetCfg, pguidClass, &pSetup); + if (FAILED(hr)) + { + LogFlow(("vboxNetCfgWinQueryInstaller failed, hr (0x%x)\n", hr)); + return hr; + } + + OBO_TOKEN Token; + ZeroMemory(&Token, sizeof (Token)); + Token.Type = OBO_USER; + + hr = pSetup->Install(pszwComponentId, &Token, + 0, /* IN DWORD dwSetupFlags */ + 0, /* IN DWORD dwUpgradeFromBuildNo */ + NULL, /* IN LPCWSTR pszwAnswerFile */ + NULL, /* IN LPCWSTR pszwAnswerSections */ + ppComponent); + if (SUCCEEDED(hr)) + { + /* ignore the apply failure */ + HRESULT tmpHr = pNetCfg->Apply(); + Assert(tmpHr == S_OK); + if (tmpHr != S_OK) + LogFlow(("Apply failed, hr (0x%x)\n", tmpHr)); + } + else + LogFlow(("Install failed, hr (0x%x)\n", hr)); + + pSetup->Release(); + return hr; +} + +VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinInstallInfAndComponent(IN INetCfg *pNetCfg, IN LPCWSTR pszwComponentId, IN const GUID *pguidClass, + IN LPCWSTR * apInfPaths, IN UINT cInfPaths, + OUT INetCfgComponent **ppComponent) +{ + HRESULT hr = S_OK; + UINT i = 0; + + LogFlow(("Installing %u INF files ...\n", cInfPaths)); + + for (; i < cInfPaths; i++) + { + LogFlow(("Installing INF file \"%ws\" ...\n", apInfPaths[i])); + hr = VBoxDrvCfgInfInstall(apInfPaths[i]); + if (FAILED(hr)) + { + LogFlow(("VBoxNetCfgWinInfInstall failed, hr (0x%x)\n", hr)); + break; + } + } + + if (SUCCEEDED(hr)) + { + hr = VBoxNetCfgWinInstallComponent(pNetCfg, pszwComponentId, pguidClass, ppComponent); + if (FAILED(hr)) + LogFlow(("VBoxNetCfgWinInstallComponent failed, hr (0x%x)\n", hr)); + } + + if (FAILED(hr)) + { + for (UINT j = i - 1; j != 0; j--) + VBoxDrvCfgInfUninstall(apInfPaths[j], 0); + } + + return hr; +} + +VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinUninstallComponent(IN INetCfg *pNetCfg, IN INetCfgComponent *pComponent) +{ + GUID GuidClass; + HRESULT hr = pComponent->GetClassGuid(&GuidClass); + if (FAILED(hr)) + { + LogFlow(("GetClassGuid failed, hr (0x%x)\n", hr)); + return hr; + } + + INetCfgClassSetup *pSetup = NULL; + hr = vboxNetCfgWinQueryInstaller(pNetCfg, &GuidClass, &pSetup); + if (FAILED(hr)) + { + LogFlow(("vboxNetCfgWinQueryInstaller failed, hr (0x%x)\n", hr)); + return hr; + } + + OBO_TOKEN Token; + ZeroMemory(&Token, sizeof(Token)); + Token.Type = OBO_USER; + + hr = pSetup->DeInstall(pComponent, &Token, NULL /* OUT LPWSTR *pmszwRefs */); + if (SUCCEEDED(hr)) + { + hr = pNetCfg->Apply(); + if (FAILED(hr)) + LogFlow(("Apply failed, hr (0x%x)\n", hr)); + } + else + LogFlow(("DeInstall failed, hr (0x%x)\n", hr)); + + if (pSetup) + pSetup->Release(); + return hr; +} + +typedef BOOL (*VBOXNETCFGWIN_NETCFGENUM_CALLBACK) (IN INetCfg *pNetCfg, IN INetCfgComponent *pNetCfgComponent, PVOID pContext); + +static HRESULT vboxNetCfgWinEnumNetCfgComponents(IN INetCfg *pNetCfg, + IN const GUID *pguidClass, + VBOXNETCFGWIN_NETCFGENUM_CALLBACK callback, + PVOID pContext) +{ + IEnumNetCfgComponent *pEnumComponent; + HRESULT hr = pNetCfg->EnumComponents(pguidClass, &pEnumComponent); + if (SUCCEEDED(hr)) + { + INetCfgComponent *pNetCfgComponent; + hr = pEnumComponent->Reset(); + do + { + hr = pEnumComponent->Next(1, &pNetCfgComponent, NULL); + if (hr == S_OK) + { +// ULONG uComponentStatus; +// hr = pNcc->GetDeviceStatus(&uComponentStatus); +// if (SUCCEEDED(hr)) + BOOL fResult = FALSE; + if (pNetCfgComponent) + { + if (pContext) + fResult = callback(pNetCfg, pNetCfgComponent, pContext); + pNetCfgComponent->Release(); + } + + if (!fResult) + break; + } + else + { + if (hr == S_FALSE) + { + hr = S_OK; + } + else + LogFlow(("Next failed, hr (0x%x)\n", hr)); + break; + } + } while (true); + pEnumComponent->Release(); + } + return hr; +} + +static BOOL vboxNetCfgWinRemoveAllNetDevicesOfIdCallback(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDev, PVOID pContext) +{ + HRESULT hr = S_OK; + SP_REMOVEDEVICE_PARAMS rmdParams; + + rmdParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER); + rmdParams.ClassInstallHeader.InstallFunction = DIF_REMOVE; + rmdParams.Scope = DI_REMOVEDEVICE_GLOBAL; + rmdParams.HwProfile = 0; + + if (SetupDiSetClassInstallParams(hDevInfo,pDev,&rmdParams.ClassInstallHeader,sizeof(rmdParams))) + { + if (SetupDiSetSelectedDevice (hDevInfo, pDev)) + { + if (SetupDiCallClassInstaller(DIF_REMOVE,hDevInfo,pDev)) + { + SP_DEVINSTALL_PARAMS devParams; + devParams.cbSize = sizeof(devParams); + if (SetupDiGetDeviceInstallParams(hDevInfo,pDev,&devParams)) + { + if (devParams.Flags & (DI_NEEDRESTART|DI_NEEDREBOOT)) + { + hr = S_FALSE; + Log(("!!!REBOOT REQUIRED!!!\n")); + } + } + } + else + { + DWORD dwErr = GetLastError(); + LogFlow(("SetupDiCallClassInstaller failed with %ld\n", dwErr)); + hr = HRESULT_FROM_WIN32(dwErr); + } + } + else + { + DWORD dwErr = GetLastError(); + LogFlow(("SetupDiSetSelectedDevice failed with %ld\n", dwErr)); + hr = HRESULT_FROM_WIN32(dwErr); + } + } + else + { + DWORD dwErr = GetLastError(); + LogFlow(("SetupDiSetClassInstallParams failed with %ld\n", dwErr)); + hr = HRESULT_FROM_WIN32(dwErr); + } + + return TRUE; +} + +typedef BOOL (*VBOXNETCFGWIN_NETENUM_CALLBACK) (HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDev, PVOID pContext); +VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinEnumNetDevices(LPCWSTR pPnPId, VBOXNETCFGWIN_NETENUM_CALLBACK callback, PVOID pContext) +{ + DWORD winEr; + HRESULT hr = S_OK; + + HDEVINFO hDevInfo = SetupDiGetClassDevsExW( + &GUID_DEVCLASS_NET, + NULL, /* IN PCTSTR Enumerator, OPTIONAL*/ + NULL, /*IN HWND hwndParent, OPTIONAL*/ + DIGCF_PRESENT, /*IN DWORD Flags,*/ + NULL, /*IN HDEVINFO DeviceInfoSet, OPTIONAL*/ + NULL, /*IN PCTSTR MachineName, OPTIONAL*/ + NULL /*IN PVOID Reserved*/ + ); + if (hDevInfo != INVALID_HANDLE_VALUE) + { + DWORD iDev = 0; + SP_DEVINFO_DATA Dev; + PBYTE pBuffer = NULL; + DWORD cbBuffer = 0; + DWORD cbRequired = 0; + BOOL bEnumCompleted; + size_t cPnPId = wcslen(pPnPId); + + Dev.cbSize = sizeof(Dev); + + for (; bEnumCompleted = SetupDiEnumDeviceInfo(hDevInfo, iDev, &Dev); iDev++) + { + if (!SetupDiGetDeviceRegistryPropertyW(hDevInfo,&Dev, + SPDRP_HARDWAREID, /* IN DWORD Property,*/ + NULL, /*OUT PDWORD PropertyRegDataType, OPTIONAL*/ + pBuffer, /*OUT PBYTE PropertyBuffer,*/ + cbBuffer, /* IN DWORD PropertyBufferSize,*/ + &cbRequired /*OUT PDWORD RequiredSize OPTIONAL*/ + )) + { + winEr = GetLastError(); + if (winEr != ERROR_INSUFFICIENT_BUFFER) + { + LogFlow(("SetupDiGetDeviceRegistryPropertyW (1) failed winErr(%d)\n", winEr)); + hr = HRESULT_FROM_WIN32(winEr); + break; + } + + if (pBuffer) + free(pBuffer); + + pBuffer = (PBYTE)malloc(cbRequired); + cbBuffer = cbRequired; + + if (!SetupDiGetDeviceRegistryPropertyW(hDevInfo,&Dev, + SPDRP_HARDWAREID, /* IN DWORD Property,*/ + NULL, /*OUT PDWORD PropertyRegDataType, OPTIONAL*/ + pBuffer, /*OUT PBYTE PropertyBuffer,*/ + cbBuffer, /* IN DWORD PropertyBufferSize,*/ + &cbRequired /*OUT PDWORD RequiredSize OPTIONAL*/ + )) + { + winEr = GetLastError(); + LogFlow(("SetupDiGetDeviceRegistryPropertyW (2) failed winErr(%d)\n", winEr)); + hr = HRESULT_FROM_WIN32(winEr); + break; + } + } + + PWCHAR pCurId = (PWCHAR)pBuffer; + size_t cCurId = wcslen(pCurId); + if (cCurId >= cPnPId) + { + pCurId += cCurId - cPnPId; + if (!wcsnicmp(pCurId, pPnPId, cPnPId)) + { + + if (!callback(hDevInfo,&Dev,pContext)) + break; + } + } + + } + + if (pBuffer) + free(pBuffer); + + if (bEnumCompleted) + { + winEr = GetLastError(); + hr = winEr == ERROR_NO_MORE_ITEMS ? S_OK : HRESULT_FROM_WIN32(winEr); + } + + SetupDiDestroyDeviceInfoList(hDevInfo); + } + else + { + DWORD winEr = GetLastError(); + LogFlow(("SetupDiGetClassDevsExW failed winErr(%d)\n", winEr)); + hr = HRESULT_FROM_WIN32(winEr); + } + + return hr; +} + +VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinRemoveAllNetDevicesOfId(IN LPCWSTR lpszPnPId) +{ + return VBoxNetCfgWinEnumNetDevices(lpszPnPId, vboxNetCfgWinRemoveAllNetDevicesOfIdCallback, NULL); +} + +/* + * logging + */ +static VOID DoLogging(LPCSTR szString, ...) +{ + LOG_ROUTINE pRoutine = (LOG_ROUTINE)(*((void * volatile *)&g_Logger)); + if (pRoutine) + { + char szBuffer[4096] = {0}; + va_list pArgList; + va_start(pArgList, szString); + _vsnprintf(szBuffer, RT_ELEMENTS(szBuffer), szString, pArgList); + va_end(pArgList); + + pRoutine(szBuffer); + } +} + +VBOXNETCFGWIN_DECL(VOID) VBoxNetCfgWinSetLogging(IN LOG_ROUTINE pfnLog) +{ + *((void * volatile *)&g_Logger) = pfnLog; +} + +/* + * IP configuration API + */ +/* network settings config */ +/** + * Strong referencing operators. Used as a second argument to ComPtr<>/ComObjPtr<>. + */ +template <class C> +class ComStrongRef +{ +protected: + + static void addref (C *p) { p->AddRef(); } + static void release (C *p) { p->Release(); } +}; + + +/** + * Base template for smart COM pointers. Not intended to be used directly. + */ +template <class C, template <class> class RefOps = ComStrongRef> +class ComPtrBase : protected RefOps <C> +{ +public: + + /* special template to disable AddRef()/Release() */ + template <class I> + class NoAddRefRelease : public I + { + private: +#if !defined (VBOX_WITH_XPCOM) + STDMETHOD_(ULONG, AddRef)() = 0; + STDMETHOD_(ULONG, Release)() = 0; +#else /* !defined (VBOX_WITH_XPCOM) */ + NS_IMETHOD_(nsrefcnt) AddRef(void) = 0; + NS_IMETHOD_(nsrefcnt) Release(void) = 0; +#endif /* !defined (VBOX_WITH_XPCOM) */ + }; + +protected: + + ComPtrBase () : p (NULL) {} + ComPtrBase (const ComPtrBase &that) : p (that.p) { addref(); } + ComPtrBase (C *that_p) : p (that_p) { addref(); } + + ~ComPtrBase() { release(); } + + ComPtrBase &operator= (const ComPtrBase &that) + { + safe_assign (that.p); + return *this; + } + + ComPtrBase &operator= (C *that_p) + { + safe_assign (that_p); + return *this; + } + +public: + + void setNull() + { + release(); + p = NULL; + } + + bool isNull() const + { + return (p == NULL); + } + + bool operator! () const { return isNull(); } + + bool operator< (C* that_p) const { return p < that_p; } + bool operator== (C* that_p) const { return p == that_p; } + + template <class I> + bool equalsTo (I *aThat) const + { + return ComPtrEquals (p, aThat); + } + + template <class OC> + bool equalsTo (const ComPtrBase <OC> &oc) const + { + return equalsTo ((OC *) oc); + } + + /** Intended to pass instances as in parameters to interface methods */ + operator C* () const { return p; } + + /** + * Dereferences the instance (redirects the -> operator to the managed + * pointer). + */ + NoAddRefRelease <C> *operator-> () const + { + AssertMsg (p, ("Managed pointer must not be null\n")); + return (NoAddRefRelease <C> *) p; + } + + template <class I> + HRESULT queryInterfaceTo (I **pp) const + { + if (pp) + { + if (p) + { + return p->QueryInterface (COM_IIDOF (I), (void **) pp); + } + else + { + *pp = NULL; + return S_OK; + } + } + + return E_INVALIDARG; + } + + /** Intended to pass instances as out parameters to interface methods */ + C **asOutParam() + { + setNull(); + return &p; + } + +private: + + void addref() + { + if (p) + RefOps <C>::addref (p); + } + + void release() + { + if (p) + RefOps <C>::release (p); + } + + void safe_assign (C *that_p) + { + /* be aware of self-assignment */ + if (that_p) + RefOps <C>::addref (that_p); + release(); + p = that_p; + } + + C *p; +}; + +/** + * Smart COM pointer wrapper that automatically manages refcounting of + * interface pointers. + * + * @param I COM interface class + */ +template <class I, template <class> class RefOps = ComStrongRef> +class ComPtr : public ComPtrBase <I, RefOps> +{ + typedef ComPtrBase <I, RefOps> Base; + +public: + + ComPtr () : Base() {} + ComPtr (const ComPtr &that) : Base(that) {} + ComPtr &operator= (const ComPtr &that) + { + Base::operator= (that); + return *this; + } + + template <class OI> + ComPtr (OI *that_p) : Base () { operator= (that_p); } + + /* specialization for I */ + ComPtr (I *that_p) : Base (that_p) {} + + template <class OC> + ComPtr (const ComPtr <OC, RefOps> &oc) : Base () { operator= ((OC *) oc); } + + template <class OI> + ComPtr &operator= (OI *that_p) + { + if (that_p) + that_p->QueryInterface (COM_IIDOF (I), (void **) Base::asOutParam()); + else + Base::setNull(); + return *this; + } + + /* specialization for I */ + ComPtr &operator=(I *that_p) + { + Base::operator= (that_p); + return *this; + } + + template <class OC> + ComPtr &operator= (const ComPtr <OC, RefOps> &oc) + { + return operator= ((OC *) oc); + } +}; + +static HRESULT netIfWinFindAdapterClassById(IWbemServices * pSvc, const GUID * pGuid, IWbemClassObject **pAdapterConfig) +{ + HRESULT hr; + WCHAR aQueryString[256]; + WCHAR GuidString[50]; + + int length = StringFromGUID2(*pGuid, GuidString, sizeof(GuidString)/sizeof(GuidString[0])); + if (length) + { + swprintf(aQueryString, L"SELECT * FROM Win32_NetworkAdapterConfiguration WHERE SettingID = \"%s\"", GuidString); + IEnumWbemClassObject* pEnumerator = NULL; + hr = pSvc->ExecQuery(bstr_t("WQL"), bstr_t(aQueryString), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator); + if (SUCCEEDED(hr)) + { + IWbemClassObject *pclsObj; + ULONG uReturn = 0; + + if (pEnumerator) + { + HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); + + if (SUCCEEDED(hr)) + { + if (uReturn) + { + pEnumerator->Release(); + *pAdapterConfig = pclsObj; + hr = S_OK; + return hr; + } + else + { + hr = S_FALSE; + } + } + + pEnumerator->Release(); + } + } + else + LogFlow(("ExecQuery failed (0x%x)\n", hr)); + } + else + { + DWORD winEr = GetLastError(); + LogFlow(("StringFromGUID2 failed winEr (%d)\n", winEr)); + hr = HRESULT_FROM_WIN32( winEr ); + } + + return hr; +} + +static HRESULT netIfWinIsHostOnly(IWbemClassObject * pAdapterConfig, BOOL * pbIsHostOnly) +{ + VARIANT vtServiceName; + BOOL bIsHostOnly = FALSE; + VariantInit(&vtServiceName); + + HRESULT hr = pAdapterConfig->Get(L"ServiceName", 0, &vtServiceName, 0, 0); + if (SUCCEEDED(hr)) + { + *pbIsHostOnly = (bstr_t(vtServiceName.bstrVal) == bstr_t("VBoxNetAdp")); + + VariantClear(&vtServiceName); + } + + return hr; +} + +static HRESULT netIfWinGetIpSettings(IWbemClassObject * pAdapterConfig, ULONG *pIpv4, ULONG *pMaskv4) +{ + VARIANT vtIp; + HRESULT hr; + VariantInit(&vtIp); + + *pIpv4 = 0; + *pMaskv4 = 0; + + hr = pAdapterConfig->Get(L"IPAddress", 0, &vtIp, 0, 0); + if (SUCCEEDED(hr)) + { + if (vtIp.vt == (VT_ARRAY | VT_BSTR)) + { + VARIANT vtMask; + VariantInit(&vtMask); + hr = pAdapterConfig->Get(L"IPSubnet", 0, &vtMask, 0, 0); + if (SUCCEEDED(hr)) + { + if (vtMask.vt == (VT_ARRAY | VT_BSTR)) + { + SAFEARRAY * pIpArray = vtIp.parray; + SAFEARRAY * pMaskArray = vtMask.parray; + if (pIpArray && pMaskArray) + { + BSTR pCurIp; + BSTR pCurMask; + for (LONG i = 0; + SafeArrayGetElement(pIpArray, &i, (PVOID)&pCurIp) == S_OK + && SafeArrayGetElement(pMaskArray, &i, (PVOID)&pCurMask) == S_OK; + i++) + { + bstr_t ip(pCurIp); + + ULONG Ipv4 = inet_addr((char*)(ip)); + if (Ipv4 != INADDR_NONE) + { + *pIpv4 = Ipv4; + bstr_t mask(pCurMask); + *pMaskv4 = inet_addr((char*)(mask)); + break; + } + } + } + } + else + { + *pIpv4 = 0; + *pMaskv4 = 0; + } + + VariantClear(&vtMask); + } + } + else + { + *pIpv4 = 0; + *pMaskv4 = 0; + } + + VariantClear(&vtIp); + } + + return hr; +} + + +static HRESULT netIfWinHasIpSettings(IWbemClassObject * pAdapterConfig, SAFEARRAY * pCheckIp, SAFEARRAY * pCheckMask, bool *pFound) +{ + VARIANT vtIp; + HRESULT hr; + VariantInit(&vtIp); + + *pFound = false; + + hr = pAdapterConfig->Get(L"IPAddress", 0, &vtIp, 0, 0); + if (SUCCEEDED(hr)) + { + VARIANT vtMask; + VariantInit(&vtMask); + hr = pAdapterConfig->Get(L"IPSubnet", 0, &vtMask, 0, 0); + if (SUCCEEDED(hr)) + { + SAFEARRAY * pIpArray = vtIp.parray; + SAFEARRAY * pMaskArray = vtMask.parray; + if (pIpArray && pMaskArray) + { + BSTR pIp, pMask; + for (LONG k = 0; + SafeArrayGetElement(pCheckIp, &k, (PVOID)&pIp) == S_OK + && SafeArrayGetElement(pCheckMask, &k, (PVOID)&pMask) == S_OK; + k++) + { + BSTR pCurIp; + BSTR pCurMask; + for (LONG i = 0; + SafeArrayGetElement(pIpArray, &i, (PVOID)&pCurIp) == S_OK + && SafeArrayGetElement(pMaskArray, &i, (PVOID)&pCurMask) == S_OK; + i++) + { + if (!wcsicmp(pCurIp, pIp)) + { + if (!wcsicmp(pCurMask, pMask)) + *pFound = true; + break; + } + } + } + } + + + VariantClear(&vtMask); + } + + VariantClear(&vtIp); + } + + return hr; +} + +static HRESULT netIfWinWaitIpSettings(IWbemServices *pSvc, const GUID * pGuid, SAFEARRAY * pCheckIp, SAFEARRAY * pCheckMask, ULONG sec2Wait, bool *pFound) +{ + /* on Vista we need to wait for the address to get applied */ + /* wait for the address to appear in the list */ + HRESULT hr = S_OK; + ULONG i; + *pFound = false; + ComPtr <IWbemClassObject> pAdapterConfig; + for (i = 0; + (hr = netIfWinFindAdapterClassById(pSvc, pGuid, pAdapterConfig.asOutParam())) == S_OK + && (hr = netIfWinHasIpSettings(pAdapterConfig, pCheckIp, pCheckMask, pFound)) == S_OK + && !(*pFound) + && i < sec2Wait/6; + i++) + { + Sleep(6000); + } + + return hr; +} + +static HRESULT netIfWinCreateIWbemServices(IWbemServices ** ppSvc) +{ + IWbemLocator *pLoc = NULL; + HRESULT hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc); + if (SUCCEEDED(hr)) + { + IWbemServices *pSvc = NULL; + hr = pLoc->ConnectServer(bstr_t(L"ROOT\\CIMV2"), /* [in] const BSTR strNetworkResource */ + NULL, /* [in] const BSTR strUser */ + NULL, /* [in] const BSTR strPassword */ + 0, /* [in] const BSTR strLocale */ + NULL, /* [in] LONG lSecurityFlags */ + 0, /* [in] const BSTR strAuthority */ + 0, /* [in] IWbemContext* pCtx */ + &pSvc /* [out] IWbemServices** ppNamespace */); + if (SUCCEEDED(hr)) + { + hr = CoSetProxyBlanket(pSvc, /* IUnknown * pProxy */ + RPC_C_AUTHN_WINNT, /* DWORD dwAuthnSvc */ + RPC_C_AUTHZ_NONE, /* DWORD dwAuthzSvc */ + NULL, /* WCHAR * pServerPrincName */ + RPC_C_AUTHN_LEVEL_CALL, /* DWORD dwAuthnLevel */ + RPC_C_IMP_LEVEL_IMPERSONATE, /* DWORD dwImpLevel */ + NULL, /* RPC_AUTH_IDENTITY_HANDLE pAuthInfo */ + EOAC_NONE /* DWORD dwCapabilities */ + ); + if (SUCCEEDED(hr)) + { + *ppSvc = pSvc; + /* do not need it any more */ + pLoc->Release(); + return hr; + } + else + LogFlow(("CoSetProxyBlanket failed, hr (0x%x)\n", hr)); + + pSvc->Release(); + } + else + LogFlow(("ConnectServer failed, hr (0x%x)\n", hr)); + pLoc->Release(); + } + else + LogFlow(("CoCreateInstance failed, hr (0x%x)\n", hr)); + return hr; +} + +static HRESULT netIfWinAdapterConfigPath(IWbemClassObject *pObj, BSTR * pStr) +{ + VARIANT index; + HRESULT hr = pObj->Get(L"Index", 0, &index, 0, 0); + if (SUCCEEDED(hr)) + { + WCHAR strIndex[8]; + swprintf(strIndex, L"%u", index.uintVal); + *pStr = (bstr_t(L"Win32_NetworkAdapterConfiguration.Index='") + strIndex + "'").copy(); + } + else + LogFlow(("Get failed, hr (0x%x)\n", hr)); + return hr; +} + +static HRESULT netIfExecMethod(IWbemServices * pSvc, IWbemClassObject *pClass, BSTR ObjPath, + BSTR MethodName, LPWSTR *pArgNames, LPVARIANT *pArgs, UINT cArgs, + IWbemClassObject** ppOutParams + ) +{ + HRESULT hr = S_OK; + ComPtr<IWbemClassObject> pInParamsDefinition; + ComPtr<IWbemClassObject> pClassInstance; + + if (cArgs) + { + hr = pClass->GetMethod(MethodName, 0, pInParamsDefinition.asOutParam(), NULL); + if (SUCCEEDED(hr)) + { + hr = pInParamsDefinition->SpawnInstance(0, pClassInstance.asOutParam()); + if (SUCCEEDED(hr)) + { + for (UINT i = 0; i < cArgs; i++) + { + hr = pClassInstance->Put(pArgNames[i], 0, + pArgs[i], 0); + if (FAILED(hr)) + break; + } + } + } + } + + if (SUCCEEDED(hr)) + { + IWbemClassObject* pOutParams = NULL; + hr = pSvc->ExecMethod(ObjPath, MethodName, 0, NULL, pClassInstance, &pOutParams, NULL); + if (SUCCEEDED(hr)) + { + *ppOutParams = pOutParams; + } + } + + return hr; +} + +static HRESULT netIfWinCreateIpArray(SAFEARRAY **ppArray, in_addr* aIp, UINT cIp) +{ + HRESULT hr; + SAFEARRAY * pIpArray = SafeArrayCreateVector(VT_BSTR, 0, cIp); + if (pIpArray) + { + for (UINT i = 0; i < cIp; i++) + { + char* addr = inet_ntoa(aIp[i]); + BSTR val = bstr_t(addr).copy(); + long aIndex[1]; + aIndex[0] = i; + hr = SafeArrayPutElement(pIpArray, aIndex, val); + if (FAILED(hr)) + { + SysFreeString(val); + SafeArrayDestroy(pIpArray); + break; + } + } + + if (SUCCEEDED(hr)) + { + *ppArray = pIpArray; + } + } + else + hr = HRESULT_FROM_WIN32(GetLastError()); + + return hr; +} + +static HRESULT netIfWinCreateIpArrayV4V6(SAFEARRAY **ppArray, BSTR Ip) +{ + HRESULT hr; + SAFEARRAY *pIpArray = SafeArrayCreateVector(VT_BSTR, 0, 1); + if (pIpArray) + { + BSTR val = bstr_t(Ip, false).copy(); + long aIndex[1]; + aIndex[0] = 0; + hr = SafeArrayPutElement(pIpArray, aIndex, val); + if (FAILED(hr)) + { + SysFreeString(val); + SafeArrayDestroy(pIpArray); + } + + if (SUCCEEDED(hr)) + { + *ppArray = pIpArray; + } + } + else + hr = HRESULT_FROM_WIN32(GetLastError()); + + return hr; +} + + +static HRESULT netIfWinCreateIpArrayVariantV4(VARIANT * pIpAddresses, in_addr* aIp, UINT cIp) +{ + HRESULT hr; + VariantInit(pIpAddresses); + pIpAddresses->vt = VT_ARRAY | VT_BSTR; + SAFEARRAY *pIpArray; + hr = netIfWinCreateIpArray(&pIpArray, aIp, cIp); + if (SUCCEEDED(hr)) + { + pIpAddresses->parray = pIpArray; + } + return hr; +} + +static HRESULT netIfWinCreateIpArrayVariantV4V6(VARIANT * pIpAddresses, BSTR Ip) +{ + HRESULT hr; + VariantInit(pIpAddresses); + pIpAddresses->vt = VT_ARRAY | VT_BSTR; + SAFEARRAY *pIpArray; + hr = netIfWinCreateIpArrayV4V6(&pIpArray, Ip); + if (SUCCEEDED(hr)) + { + pIpAddresses->parray = pIpArray; + } + return hr; +} + +static HRESULT netIfWinEnableStatic(IWbemServices * pSvc, const GUID * pGuid, BSTR ObjPath, VARIANT * pIp, VARIANT * pMask) +{ + ComPtr<IWbemClassObject> pClass; + BSTR ClassName = SysAllocString(L"Win32_NetworkAdapterConfiguration"); + HRESULT hr; + if (ClassName) + { + hr = pSvc->GetObject(ClassName, 0, NULL, pClass.asOutParam(), NULL); + if (SUCCEEDED(hr)) + { + LPWSTR argNames[] = {L"IPAddress", L"SubnetMask"}; + LPVARIANT args[] = {pIp, pMask}; + ComPtr<IWbemClassObject> pOutParams; + + hr = netIfExecMethod(pSvc, pClass, ObjPath, bstr_t(L"EnableStatic"), argNames, args, 2, pOutParams.asOutParam()); + if (SUCCEEDED(hr)) + { + VARIANT varReturnValue; + hr = pOutParams->Get(bstr_t(L"ReturnValue"), 0, + &varReturnValue, NULL, 0); + Assert(SUCCEEDED(hr)); + if (SUCCEEDED(hr)) + { +// Assert(varReturnValue.vt == VT_UINT); + int winEr = varReturnValue.uintVal; + switch (winEr) + { + case 0: + { + hr = S_OK; +// bool bFound; +// HRESULT tmpHr = netIfWinWaitIpSettings(pSvc, pGuid, pIp->parray, pMask->parray, 180, &bFound); + } + break; + default: + hr = HRESULT_FROM_WIN32( winEr ); + break; + } + } + } + } + SysFreeString(ClassName); + } + else + hr = HRESULT_FROM_WIN32(GetLastError()); + + return hr; +} + + +static HRESULT netIfWinEnableStaticV4(IWbemServices * pSvc, const GUID * pGuid, BSTR ObjPath, in_addr* aIp, in_addr * aMask, UINT cIp) +{ + VARIANT ipAddresses; + HRESULT hr = netIfWinCreateIpArrayVariantV4(&ipAddresses, aIp, cIp); + if (SUCCEEDED(hr)) + { + VARIANT ipMasks; + hr = netIfWinCreateIpArrayVariantV4(&ipMasks, aMask, cIp); + if (SUCCEEDED(hr)) + { + hr = netIfWinEnableStatic(pSvc, pGuid, ObjPath, &ipAddresses, &ipMasks); + VariantClear(&ipMasks); + } + VariantClear(&ipAddresses); + } + return hr; +} + +static HRESULT netIfWinEnableStaticV4V6(IWbemServices * pSvc, const GUID * pGuid, BSTR ObjPath, BSTR Ip, BSTR Mask) +{ + VARIANT ipAddresses; + HRESULT hr = netIfWinCreateIpArrayVariantV4V6(&ipAddresses, Ip); + if (SUCCEEDED(hr)) + { + VARIANT ipMasks; + hr = netIfWinCreateIpArrayVariantV4V6(&ipMasks, Mask); + if (SUCCEEDED(hr)) + { + hr = netIfWinEnableStatic(pSvc, pGuid, ObjPath, &ipAddresses, &ipMasks); + VariantClear(&ipMasks); + } + VariantClear(&ipAddresses); + } + return hr; +} + +/* win API allows to set gw metrics as well, we are not setting them */ +static HRESULT netIfWinSetGateways(IWbemServices * pSvc, BSTR ObjPath, VARIANT * pGw) +{ + ComPtr<IWbemClassObject> pClass; + BSTR ClassName = SysAllocString(L"Win32_NetworkAdapterConfiguration"); + HRESULT hr; + if (ClassName) + { + hr = pSvc->GetObject(ClassName, 0, NULL, pClass.asOutParam(), NULL); + if (SUCCEEDED(hr)) + { + LPWSTR argNames[] = {L"DefaultIPGateway"}; + LPVARIANT args[] = {pGw}; + ComPtr<IWbemClassObject> pOutParams; + + hr = netIfExecMethod(pSvc, pClass, ObjPath, bstr_t(L"SetGateways"), argNames, args, 1, pOutParams.asOutParam()); + if (SUCCEEDED(hr)) + { + VARIANT varReturnValue; + hr = pOutParams->Get(bstr_t(L"ReturnValue"), 0, &varReturnValue, NULL, 0); + Assert(SUCCEEDED(hr)); + if (SUCCEEDED(hr)) + { +// Assert(varReturnValue.vt == VT_UINT); + int winEr = varReturnValue.uintVal; + switch (winEr) + { + case 0: + hr = S_OK; + break; + default: + hr = HRESULT_FROM_WIN32( winEr ); + break; + } + } + } + } + SysFreeString(ClassName); + } + else + hr = HRESULT_FROM_WIN32(GetLastError()); + + return hr; +} + +/* win API allows to set gw metrics as well, we are not setting them */ +static HRESULT netIfWinSetGatewaysV4(IWbemServices * pSvc, BSTR ObjPath, in_addr* aGw, UINT cGw) +{ + VARIANT gwais; + HRESULT hr = netIfWinCreateIpArrayVariantV4(&gwais, aGw, cGw); + if (SUCCEEDED(hr)) + { + netIfWinSetGateways(pSvc, ObjPath, &gwais); + VariantClear(&gwais); + } + return hr; +} + +/* win API allows to set gw metrics as well, we are not setting them */ +static HRESULT netIfWinSetGatewaysV4V6(IWbemServices * pSvc, BSTR ObjPath, BSTR Gw) +{ + VARIANT vGw; + HRESULT hr = netIfWinCreateIpArrayVariantV4V6(&vGw, Gw); + if (SUCCEEDED(hr)) + { + netIfWinSetGateways(pSvc, ObjPath, &vGw); + VariantClear(&vGw); + } + return hr; +} + +static HRESULT netIfWinEnableDHCP(IWbemServices * pSvc, BSTR ObjPath) +{ + ComPtr<IWbemClassObject> pClass; + BSTR ClassName = SysAllocString(L"Win32_NetworkAdapterConfiguration"); + HRESULT hr; + if (ClassName) + { + hr = pSvc->GetObject(ClassName, 0, NULL, pClass.asOutParam(), NULL); + if (SUCCEEDED(hr)) + { + ComPtr<IWbemClassObject> pOutParams; + + hr = netIfExecMethod(pSvc, pClass, ObjPath, bstr_t(L"EnableDHCP"), NULL, NULL, 0, pOutParams.asOutParam()); + if (SUCCEEDED(hr)) + { + VARIANT varReturnValue; + hr = pOutParams->Get(bstr_t(L"ReturnValue"), 0, + &varReturnValue, NULL, 0); + Assert(SUCCEEDED(hr)); + if (SUCCEEDED(hr)) + { +// Assert(varReturnValue.vt == VT_UINT); + int winEr = varReturnValue.uintVal; + switch (winEr) + { + case 0: + hr = S_OK; + break; + default: + hr = HRESULT_FROM_WIN32( winEr ); + break; + } + } + } + } + SysFreeString(ClassName); + } + else + hr = HRESULT_FROM_WIN32(GetLastError()); + + return hr; +} + +static HRESULT netIfWinDhcpRediscover(IWbemServices * pSvc, BSTR ObjPath) +{ + ComPtr<IWbemClassObject> pClass; + BSTR ClassName = SysAllocString(L"Win32_NetworkAdapterConfiguration"); + HRESULT hr; + if (ClassName) + { + hr = pSvc->GetObject(ClassName, 0, NULL, pClass.asOutParam(), NULL); + if (SUCCEEDED(hr)) + { + ComPtr<IWbemClassObject> pOutParams; + + hr = netIfExecMethod(pSvc, pClass, ObjPath, bstr_t(L"ReleaseDHCPLease"), NULL, NULL, 0, pOutParams.asOutParam()); + if (SUCCEEDED(hr)) + { + VARIANT varReturnValue; + hr = pOutParams->Get(bstr_t(L"ReturnValue"), 0, &varReturnValue, NULL, 0); + Assert(SUCCEEDED(hr)); + if (SUCCEEDED(hr)) + { +// Assert(varReturnValue.vt == VT_UINT); + int winEr = varReturnValue.uintVal; + if (winEr == 0) + { + hr = netIfExecMethod(pSvc, pClass, ObjPath, bstr_t(L"RenewDHCPLease"), NULL, NULL, 0, pOutParams.asOutParam()); + if (SUCCEEDED(hr)) + { + VARIANT varReturnValue; + hr = pOutParams->Get(bstr_t(L"ReturnValue"), 0, &varReturnValue, NULL, 0); + Assert(SUCCEEDED(hr)); + if (SUCCEEDED(hr)) + { + // Assert(varReturnValue.vt == VT_UINT); + int winEr = varReturnValue.uintVal; + if (winEr == 0) + hr = S_OK; + else + hr = HRESULT_FROM_WIN32( winEr ); + } + } + } + else + hr = HRESULT_FROM_WIN32( winEr ); + } + } + } + SysFreeString(ClassName); + } + else + hr = HRESULT_FROM_WIN32(GetLastError()); + + return hr; +} + +static HRESULT vboxNetCfgWinIsDhcpEnabled(IWbemClassObject * pAdapterConfig, BOOL *pEnabled) +{ + VARIANT vtEnabled; + HRESULT hr = pAdapterConfig->Get(L"DHCPEnabled", 0, &vtEnabled, 0, 0); + if (SUCCEEDED(hr)) + *pEnabled = vtEnabled.boolVal; + return hr; +} + +VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinGetAdapterSettings(IN const GUID * pGuid, OUT PADAPTER_SETTINGS pSettings) +{ + HRESULT hr; + ComPtr <IWbemServices> pSvc; + hr = netIfWinCreateIWbemServices(pSvc.asOutParam()); + if (SUCCEEDED(hr)) + { + ComPtr <IWbemClassObject> pAdapterConfig; + hr = netIfWinFindAdapterClassById(pSvc, pGuid, pAdapterConfig.asOutParam()); + if (SUCCEEDED(hr)) + { + hr = vboxNetCfgWinIsDhcpEnabled(pAdapterConfig, &pSettings->bDhcp); + if (SUCCEEDED(hr)) + hr = netIfWinGetIpSettings(pAdapterConfig, &pSettings->ip, &pSettings->mask); + } + } + + return hr; +} + +VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinIsDhcpEnabled(const GUID * pGuid, BOOL *pEnabled) +{ + HRESULT hr; + ComPtr <IWbemServices> pSvc; + hr = netIfWinCreateIWbemServices(pSvc.asOutParam()); + if (SUCCEEDED(hr)) + { + ComPtr <IWbemClassObject> pAdapterConfig; + hr = netIfWinFindAdapterClassById(pSvc, pGuid, pAdapterConfig.asOutParam()); + if (SUCCEEDED(hr)) + { + VARIANT vtEnabled; + hr = pAdapterConfig->Get(L"DHCPEnabled", 0, &vtEnabled, 0, 0); + if (SUCCEEDED(hr)) + *pEnabled = vtEnabled.boolVal; + } + } + + return hr; +} + +VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinEnableStaticIpConfig(IN const GUID *pGuid, IN ULONG ip, IN ULONG mask) +{ + HRESULT hr; + ComPtr <IWbemServices> pSvc; + hr = netIfWinCreateIWbemServices(pSvc.asOutParam()); + if (SUCCEEDED(hr)) + { + ComPtr <IWbemClassObject> pAdapterConfig; + hr = netIfWinFindAdapterClassById(pSvc, pGuid, pAdapterConfig.asOutParam()); + if (SUCCEEDED(hr)) + { + BOOL bIsHostOnly; + hr = netIfWinIsHostOnly(pAdapterConfig, &bIsHostOnly); + if (SUCCEEDED(hr)) + { + if (bIsHostOnly) + { + in_addr aIp[1]; + in_addr aMask[1]; + aIp[0].S_un.S_addr = ip; + aMask[0].S_un.S_addr = mask; + + BSTR ObjPath; + hr = netIfWinAdapterConfigPath(pAdapterConfig, &ObjPath); + if (SUCCEEDED(hr)) + { + hr = netIfWinEnableStaticV4(pSvc, pGuid, ObjPath, aIp, aMask, ip != 0 ? 1 : 0); + if (SUCCEEDED(hr)) + { +#if 0 + in_addr aGw[1]; + aGw[0].S_un.S_addr = gw; + hr = netIfWinSetGatewaysV4(pSvc, ObjPath, aGw, 1); + if (SUCCEEDED(hr)) +#endif + { + } + } + SysFreeString(ObjPath); + } + } + else + { + hr = E_FAIL; + } + } + } + } + + return hr; +} + +#if 0 +static HRESULT netIfEnableStaticIpConfigV6(const GUID *pGuid, IN_BSTR aIPV6Address, IN_BSTR aIPV6Mask, IN_BSTR aIPV6DefaultGateway) +{ + HRESULT hr; + ComPtr <IWbemServices> pSvc; + hr = netIfWinCreateIWbemServices(pSvc.asOutParam()); + if (SUCCEEDED(hr)) + { + ComPtr <IWbemClassObject> pAdapterConfig; + hr = netIfWinFindAdapterClassById(pSvc, pGuid, pAdapterConfig.asOutParam()); + if (SUCCEEDED(hr)) + { + BSTR ObjPath; + hr = netIfWinAdapterConfigPath(pAdapterConfig, &ObjPath); + if (SUCCEEDED(hr)) + { + hr = netIfWinEnableStaticV4V6(pSvc, pAdapterConfig, ObjPath, aIPV6Address, aIPV6Mask); + if (SUCCEEDED(hr)) + { + if (aIPV6DefaultGateway) + { + hr = netIfWinSetGatewaysV4V6(pSvc, ObjPath, aIPV6DefaultGateway); + } + if (SUCCEEDED(hr)) + { +// hr = netIfWinUpdateConfig(pIf); + } + } + SysFreeString(ObjPath); + } + } + } + + return SUCCEEDED(hr) ? VINF_SUCCESS : VERR_GENERAL_FAILURE; +} + +static HRESULT netIfEnableStaticIpConfigV6(const GUID *pGuid, IN_BSTR aIPV6Address, ULONG aIPV6MaskPrefixLength) +{ + RTNETADDRIPV6 Mask; + int rc = prefixLength2IPv6Address(aIPV6MaskPrefixLength, &Mask); + if (RT_SUCCESS(rc)) + { + Bstr maskStr = composeIPv6Address(&Mask); + rc = netIfEnableStaticIpConfigV6(pGuid, aIPV6Address, maskStr, NULL); + } + return rc; +} +#endif + +VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinEnableDynamicIpConfig(IN const GUID *pGuid) +{ + HRESULT hr; + ComPtr <IWbemServices> pSvc; + hr = netIfWinCreateIWbemServices(pSvc.asOutParam()); + if (SUCCEEDED(hr)) + { + ComPtr <IWbemClassObject> pAdapterConfig; + hr = netIfWinFindAdapterClassById(pSvc, pGuid, pAdapterConfig.asOutParam()); + if (SUCCEEDED(hr)) + { + BOOL bIsHostOnly; + hr = netIfWinIsHostOnly(pAdapterConfig, &bIsHostOnly); + if (SUCCEEDED(hr)) + { + if (bIsHostOnly) + { + BSTR ObjPath; + hr = netIfWinAdapterConfigPath(pAdapterConfig, &ObjPath); + if (SUCCEEDED(hr)) + { + hr = netIfWinEnableDHCP(pSvc, ObjPath); + if (SUCCEEDED(hr)) + { +// hr = netIfWinUpdateConfig(pIf); + } + SysFreeString(ObjPath); + } + } + else + { + hr = E_FAIL; + } + } + } + } + + + return hr; +} + +VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinDhcpRediscover(IN const GUID *pGuid) +{ + HRESULT hr; + ComPtr <IWbemServices> pSvc; + hr = netIfWinCreateIWbemServices(pSvc.asOutParam()); + if (SUCCEEDED(hr)) + { + ComPtr <IWbemClassObject> pAdapterConfig; + hr = netIfWinFindAdapterClassById(pSvc, pGuid, pAdapterConfig.asOutParam()); + if (SUCCEEDED(hr)) + { + BOOL bIsHostOnly; + hr = netIfWinIsHostOnly(pAdapterConfig, &bIsHostOnly); + if (SUCCEEDED(hr)) + { + if (bIsHostOnly) + { + BSTR ObjPath; + hr = netIfWinAdapterConfigPath(pAdapterConfig, &ObjPath); + if (SUCCEEDED(hr)) + { + hr = netIfWinDhcpRediscover(pSvc, ObjPath); + if (SUCCEEDED(hr)) + { +// hr = netIfWinUpdateConfig(pIf); + } + SysFreeString(ObjPath); + } + } + else + { + hr = E_FAIL; + } + } + } + } + + + return hr; +} + +typedef bool (*PFNVBOXNETCFG_IPSETTINGS_CALLBACK) (ULONG ip, ULONG mask, PVOID pContext); + +static void vboxNetCfgWinEnumIpConfig(PIP_ADAPTER_ADDRESSES pAddresses, PFNVBOXNETCFG_IPSETTINGS_CALLBACK pfnCallback, PVOID pContext) +{ + PIP_ADAPTER_ADDRESSES pAdapter; + for (pAdapter = pAddresses; pAdapter; pAdapter = pAdapter->Next) + { + PIP_ADAPTER_UNICAST_ADDRESS pAddr = pAdapter->FirstUnicastAddress; + PIP_ADAPTER_PREFIX pPrefix = pAdapter->FirstPrefix; + + if (pAddr && pPrefix) + { + do + { + bool fIPFound, fMaskFound; + fIPFound = fMaskFound = false; + ULONG ip, mask; + for (; pAddr && !fIPFound; pAddr = pAddr->Next) + { + switch (pAddr->Address.lpSockaddr->sa_family) + { + case AF_INET: + fIPFound = true; + memcpy(&ip, + &((struct sockaddr_in *)pAddr->Address.lpSockaddr)->sin_addr.s_addr, + sizeof(ip)); + break; +// case AF_INET6: +// break; + } + } + + for (; pPrefix && !fMaskFound; pPrefix = pPrefix->Next) + { + switch (pPrefix->Address.lpSockaddr->sa_family) + { + case AF_INET: + if (!pPrefix->PrefixLength || pPrefix->PrefixLength > 31) /* in case the ip helper API is queried while NetCfg write lock is held */ + break; /* the address values can contain illegal values */ + fMaskFound = true; + mask = (~(((ULONG)~0) >> pPrefix->PrefixLength)); + mask = htonl(mask); + break; +// case AF_INET6: +// break; + } + } + + if (!fIPFound || !fMaskFound) + break; + + if (!pfnCallback(ip, mask, pContext)) + return; + } while (true); + } + } +} + +typedef struct _IPPROBE_CONTEXT +{ + ULONG Prefix; + bool bConflict; +}IPPROBE_CONTEXT, *PIPPROBE_CONTEXT; + +#define IPPROBE_INIT(_pContext, _addr) \ + ((_pContext)->bConflict = false, \ + (_pContext)->Prefix = _addr) + +#define IPPROBE_INIT_STR(_pContext, _straddr) \ + IPROBE_INIT(_pContext, inet_addr(_straddr)) + +static bool vboxNetCfgWinIpProbeCallback (ULONG ip, ULONG mask, PVOID pContext) +{ + PIPPROBE_CONTEXT pProbe = (PIPPROBE_CONTEXT)pContext; + + if ((ip & mask) == (pProbe->Prefix & mask)) + { + pProbe->bConflict = true; + return false; + } + + return true; +} + +VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinGenHostOnlyNetworkNetworkIp(OUT PULONG pNetIp, OUT PULONG pNetMask) +{ + DWORD dwRc; + HRESULT hr = S_OK; + /* + * Most of the hosts probably have less than 10 adapters, + * so we'll mostly succeed from the first attempt. + */ + ULONG uBufLen = sizeof(IP_ADAPTER_ADDRESSES) * 10; + PIP_ADAPTER_ADDRESSES pAddresses = (PIP_ADAPTER_ADDRESSES)malloc(uBufLen); + if (!pAddresses) + return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); + dwRc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &uBufLen); + if (dwRc == ERROR_BUFFER_OVERFLOW) + { + /* Impressive! More than 10 adapters! Get more memory and try again. */ + free(pAddresses); + pAddresses = (PIP_ADAPTER_ADDRESSES)malloc(uBufLen); + if (!pAddresses) + return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); + dwRc = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &uBufLen); + } + if (dwRc == NO_ERROR) + { + IPPROBE_CONTEXT Context; + const ULONG ip192168 = inet_addr("192.168.0.0"); + srand(GetTickCount()); + + *pNetIp = 0; + *pNetMask = 0; + + for (int i = 0; i < 255; i++) + { + ULONG ipProbe = rand()*255/RAND_MAX; + ipProbe = ip192168 | (ipProbe << 16); + IPPROBE_INIT(&Context, ipProbe); + vboxNetCfgWinEnumIpConfig(pAddresses, vboxNetCfgWinIpProbeCallback, &Context); + if (!Context.bConflict) + { + *pNetIp = ipProbe; + *pNetMask = inet_addr("255.255.255.0"); + break; + } + } + if (*pNetIp == 0) + dwRc = ERROR_DHCP_ADDRESS_CONFLICT; + } + else + LogFlow(("GetAdaptersAddresses err (%d)\n", dwRc)); + + if (pAddresses) + free(pAddresses); + + if (dwRc != NO_ERROR) + { + hr = HRESULT_FROM_WIN32(dwRc); + } + + return hr; +} + +/* + * convenience functions to perform netflt/adp manipulations + */ +#define VBOXNETCFGWIN_NETFLT_ID L"sun_VBoxNetFlt" +#define VBOXNETCFGWIN_NETFLT_MP_ID L"sun_VBoxNetFltmp" + +static HRESULT vboxNetCfgWinNetFltUninstall(IN INetCfg *pNc, DWORD InfRmFlags) +{ + INetCfgComponent * pNcc = NULL; + HRESULT hr = pNc->FindComponent(VBOXNETCFGWIN_NETFLT_ID, &pNcc); + if (hr == S_OK) + { + Log("NetFlt is installed currently, uninstalling ...\n"); + + hr = VBoxNetCfgWinUninstallComponent(pNc, pNcc); + + pNcc->Release(); + } + else if (hr == S_FALSE) + { + Log("NetFlt is not installed currently\n"); + hr = S_OK; + } + else + { + LogFlow(("FindComponent failed, hr (0x%x)\n", hr)); + hr = S_OK; + } + + VBoxDrvCfgInfUninstallAllF(L"NetService", VBOXNETCFGWIN_NETFLT_ID, InfRmFlags); + VBoxDrvCfgInfUninstallAllF(L"Net", VBOXNETCFGWIN_NETFLT_MP_ID, InfRmFlags); + + return hr; +} + +VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinNetFltUninstall(IN INetCfg *pNc) +{ + return vboxNetCfgWinNetFltUninstall(pNc, 0); +} + +VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinNetFltInstall(IN INetCfg *pNc, + IN LPCWSTR * apInfFullPaths, IN UINT cInfFullPaths) +{ + HRESULT hr = vboxNetCfgWinNetFltUninstall(pNc, SUOI_FORCEDELETE); + if (SUCCEEDED(hr)) + { + Log("NetFlt will be installed ...\n"); + hr = VBoxNetCfgWinInstallInfAndComponent(pNc, VBOXNETCFGWIN_NETFLT_ID, + &GUID_DEVCLASS_NETSERVICE, + apInfFullPaths, + cInfFullPaths, + NULL); + } + return hr; +} + +#define VBOX_CONNECTION_NAME L"VirtualBox Host-Only Network" +VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinGenHostonlyConnectionName(PCWSTR DevName, WCHAR *pBuf, PULONG pcbBuf) +{ + const WCHAR * pSuffix = wcsrchr( DevName, L'#' ); + ULONG cbSize = sizeof(VBOX_CONNECTION_NAME); + ULONG cbSufSize = 0; + + if (pSuffix) + { + cbSize += (ULONG)wcslen(pSuffix) * 2; + cbSize += 2; /* for space */ + } + + if (*pcbBuf < cbSize) + { + *pcbBuf = cbSize; + return E_FAIL; + } + + wcscpy(pBuf, VBOX_CONNECTION_NAME); + if (pSuffix) + { + wcscat(pBuf, L" "); + wcscat(pBuf, pSuffix); + } + + return S_OK; +} + +static BOOL vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority(IN INetCfg *pNc, IN INetCfgComponent *pNcc, PVOID pContext) +{ + INetCfgComponentBindings *pNetCfgBindings; + GUID *pGuid = (GUID*)pContext; + + /* Get component's binding. */ + HRESULT hr = pNcc->QueryInterface(IID_INetCfgComponentBindings, (PVOID*)&pNetCfgBindings); + if (SUCCEEDED(hr)) + { + /* Get binding path enumerator reference. */ + IEnumNetCfgBindingPath *pEnumNetCfgBindPath; + hr = pNetCfgBindings->EnumBindingPaths(EBP_BELOW, &pEnumNetCfgBindPath); + if (SUCCEEDED(hr)) + { + bool bFoundIface = false; + hr = pEnumNetCfgBindPath->Reset(); + do + { + INetCfgBindingPath *pNetCfgBindPath; + hr = pEnumNetCfgBindPath->Next(1, &pNetCfgBindPath, NULL); + if (hr == S_OK) + { + IEnumNetCfgBindingInterface *pEnumNetCfgBindIface; + hr = pNetCfgBindPath->EnumBindingInterfaces(&pEnumNetCfgBindIface); + if (hr == S_OK) + { + pEnumNetCfgBindIface->Reset(); + do + { + INetCfgBindingInterface *pNetCfgBindIfce; + hr = pEnumNetCfgBindIface->Next(1, &pNetCfgBindIfce, NULL); + if (hr == S_OK) + { + INetCfgComponent *pNetCfgCompo; + hr = pNetCfgBindIfce->GetLowerComponent(&pNetCfgCompo); + if (hr == S_OK) + { + ULONG uComponentStatus; + hr = pNetCfgCompo->GetDeviceStatus(&uComponentStatus); + if (hr == S_OK) + { + GUID guid; + hr = pNetCfgCompo->GetInstanceGuid(&guid); + if ( hr == S_OK + && guid == *pGuid) + { + hr = pNetCfgBindings->MoveAfter(pNetCfgBindPath, NULL); + if (FAILED(hr)) + LogFlow(("Unable to move interface, hr (0x%x)\n", hr)); + bFoundIface = true; + } + } + pNetCfgCompo->Release(); + } + else + LogFlow(("GetLowerComponent failed, hr (0x%x)\n", hr)); + pNetCfgBindIfce->Release(); + } + else + { + if (hr == S_FALSE) /* No more binding interfaces? */ + hr = S_OK; + else + LogFlow(("Next binding interface failed, hr (0x%x)\n", hr)); + break; + } + } while (!bFoundIface); + pEnumNetCfgBindIface->Release(); + } + else + LogFlow(("EnumBindingInterfaces failed, hr (0x%x)\n", hr)); + pNetCfgBindPath->Release(); + } + else + { + if (hr = S_FALSE) /* No more binding paths? */ + hr = S_OK; + else + LogFlow(("Next bind path failed, hr (0x%x)\n", hr)); + break; + } + } while (!bFoundIface); + pEnumNetCfgBindPath->Release(); + } + else + LogFlow(("EnumBindingPaths failed, hr (0x%x)\n", hr)); + pNetCfgBindings->Release(); + } + else + LogFlow(("QueryInterface for IID_INetCfgComponentBindings failed, hr (0x%x)\n", hr)); + return TRUE; +} + +static UINT WINAPI vboxNetCfgWinPspFileCallback( + PVOID Context, + UINT Notification, + UINT_PTR Param1, + UINT_PTR Param2 + ) +{ + switch (Notification) + { + case SPFILENOTIFY_TARGETNEWER: + case SPFILENOTIFY_TARGETEXISTS: + return TRUE; + } + return SetupDefaultQueueCallback(Context, Notification, Param1, Param2); +} + +/* The original source of the VBoxNetAdp adapter creation/destruction code has the following copyright */ +/* + Copyright 2004 by the Massachusetts Institute of Technology + + All rights reserved. + + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee is hereby granted, + provided that the above copyright notice appear in all copies and that + both that copyright notice and this permission notice appear in + supporting documentation, and that the name of the Massachusetts + Institute of Technology (M.I.T.) not be used in advertising or publicity + pertaining to distribution of the software without specific, written + prior permission. + + M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR + ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + SOFTWARE. +*/ + + +#define NETSHELL_LIBRARY _T("netshell.dll") + +/** + * Use the IShellFolder API to rename the connection. + */ +static HRESULT rename_shellfolder (PCWSTR wGuid, PCWSTR wNewName) +{ + /* This is the GUID for the network connections folder. It is constant. + * {7007ACC7-3202-11D1-AAD2-00805FC1270E} */ + const GUID CLSID_NetworkConnections = { + 0x7007ACC7, 0x3202, 0x11D1, { + 0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E + } + }; + + LPITEMIDLIST pidl = NULL; + IShellFolder *pShellFolder = NULL; + HRESULT hr; + + /* Build the display name in the form "::{GUID}". */ + if (wcslen (wGuid) >= MAX_PATH) + return E_INVALIDARG; + WCHAR szAdapterGuid[MAX_PATH + 2] = {0}; + swprintf (szAdapterGuid, L"::%ls", wGuid); + + /* Create an instance of the network connections folder. */ + hr = CoCreateInstance (CLSID_NetworkConnections, NULL, + CLSCTX_INPROC_SERVER, IID_IShellFolder, + reinterpret_cast <LPVOID *> (&pShellFolder)); + /* Parse the display name. */ + if (SUCCEEDED (hr)) + { + hr = pShellFolder->ParseDisplayName (NULL, NULL, szAdapterGuid, NULL, + &pidl, NULL); + } + if (SUCCEEDED (hr)) + { + hr = pShellFolder->SetNameOf (NULL, pidl, wNewName, SHGDN_NORMAL, + &pidl); + } + + CoTaskMemFree (pidl); + + if (pShellFolder) + pShellFolder->Release(); + + return hr; +} + +VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinRenameConnection (LPWSTR pGuid, PCWSTR NewName) +{ + typedef HRESULT (WINAPI *lpHrRenameConnection) (const GUID *, PCWSTR); + lpHrRenameConnection RenameConnectionFunc = NULL; + HRESULT status; + + /* First try the IShellFolder interface, which was unimplemented + * for the network connections folder before XP. */ + status = rename_shellfolder (pGuid, NewName); + if (status == E_NOTIMPL) + { +/** @todo that code doesn't seem to work! */ + /* The IShellFolder interface is not implemented on this platform. + * Try the (undocumented) HrRenameConnection API in the netshell + * library. */ + CLSID clsid; + HINSTANCE hNetShell; + status = CLSIDFromString ((LPOLESTR) pGuid, &clsid); + if (FAILED(status)) + return E_FAIL; + hNetShell = LoadLibrary (NETSHELL_LIBRARY); + if (hNetShell == NULL) + return E_FAIL; + RenameConnectionFunc = + (lpHrRenameConnection) GetProcAddress (hNetShell, + "HrRenameConnection"); + if (RenameConnectionFunc == NULL) + { + FreeLibrary (hNetShell); + return E_FAIL; + } + status = RenameConnectionFunc (&clsid, NewName); + FreeLibrary (hNetShell); + } + if (FAILED (status)) + return status; + + return S_OK; +} + +#define DRIVERHWID _T("sun_VBoxNetAdp") + +#define SetErrBreak(strAndArgs) \ + if (1) { \ + hrc = E_FAIL; \ + Log strAndArgs; \ + break; \ + } else do {} while (0) + +VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinRemoveHostOnlyNetworkInterface(IN const GUID *pGUID, OUT BSTR *pErrMsg) +{ + HRESULT hrc = S_OK; + + do + { + TCHAR lszPnPInstanceId [512] = {0}; + + /* We have to find the device instance ID through a registry search */ + + HKEY hkeyNetwork = 0; + HKEY hkeyConnection = 0; + + do + { + WCHAR strRegLocation [256]; + WCHAR GuidString[50]; + + int length = StringFromGUID2(*pGUID, GuidString, sizeof(GuidString)/sizeof(GuidString[0])); + if (!length) + SetErrBreak(("Failed to create a Guid string")); + + swprintf (strRegLocation, + L"SYSTEM\\CurrentControlSet\\Control\\Network\\" + L"{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s", + GuidString); + + LONG status; + status = RegOpenKeyExW (HKEY_LOCAL_MACHINE, strRegLocation, 0, + KEY_READ, &hkeyNetwork); + if ((status != ERROR_SUCCESS) || !hkeyNetwork) + SetErrBreak (("Host interface network is not found in registry (%S) [1]", + strRegLocation)); + + status = RegOpenKeyExW (hkeyNetwork, L"Connection", 0, + KEY_READ, &hkeyConnection); + if ((status != ERROR_SUCCESS) || !hkeyConnection) + SetErrBreak (("Host interface network is not found in registry (%S) [2]", + strRegLocation)); + + DWORD len = sizeof (lszPnPInstanceId); + DWORD dwKeyType; + status = RegQueryValueExW (hkeyConnection, L"PnPInstanceID", NULL, + &dwKeyType, (LPBYTE) lszPnPInstanceId, &len); + if ((status != ERROR_SUCCESS) || (dwKeyType != REG_SZ)) + SetErrBreak (("Host interface network is not found in registry (%S) [3]", + strRegLocation)); + } + while (0); + + if (hkeyConnection) + RegCloseKey (hkeyConnection); + if (hkeyNetwork) + RegCloseKey (hkeyNetwork); + + if (FAILED (hrc)) + break; + + /* + * Now we are going to enumerate all network devices and + * wait until we encounter the right device instance ID + */ + + HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE; + + do + { + BOOL ok; + DWORD ret = 0; + GUID netGuid; + SP_DEVINFO_DATA DeviceInfoData; + DWORD index = 0; + BOOL found = FALSE; + DWORD size = 0; + + /* initialize the structure size */ + DeviceInfoData.cbSize = sizeof (SP_DEVINFO_DATA); + + /* copy the net class GUID */ + memcpy (&netGuid, &GUID_DEVCLASS_NET, sizeof (GUID_DEVCLASS_NET)); + + /* return a device info set contains all installed devices of the Net class */ + hDeviceInfo = SetupDiGetClassDevs (&netGuid, NULL, NULL, DIGCF_PRESENT); + + if (hDeviceInfo == INVALID_HANDLE_VALUE) + SetErrBreak (("SetupDiGetClassDevs failed (0x%08X)", GetLastError())); + + /* enumerate the driver info list */ + while (TRUE) + { + TCHAR *deviceHwid; + + ok = SetupDiEnumDeviceInfo (hDeviceInfo, index, &DeviceInfoData); + + if (!ok) + { + if (GetLastError() == ERROR_NO_MORE_ITEMS) + break; + else + { + index++; + continue; + } + } + + /* try to get the hardware ID registry property */ + ok = SetupDiGetDeviceRegistryProperty (hDeviceInfo, + &DeviceInfoData, + SPDRP_HARDWAREID, + NULL, + NULL, + 0, + &size); + if (!ok) + { + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) + { + index++; + continue; + } + + deviceHwid = (TCHAR *) malloc (size); + ok = SetupDiGetDeviceRegistryProperty (hDeviceInfo, + &DeviceInfoData, + SPDRP_HARDWAREID, + NULL, + (PBYTE)deviceHwid, + size, + NULL); + if (!ok) + { + free (deviceHwid); + deviceHwid = NULL; + index++; + continue; + } + } + else + { + /* something is wrong. This shouldn't have worked with a NULL buffer */ + index++; + continue; + } + + for (TCHAR *t = deviceHwid; + t && *t && t < &deviceHwid[size / sizeof(TCHAR)]; + t += _tcslen (t) + 1) + { + if (!_tcsicmp (DRIVERHWID, t)) + { + /* get the device instance ID */ + TCHAR devID [MAX_DEVICE_ID_LEN]; + if (CM_Get_Device_ID(DeviceInfoData.DevInst, + devID, MAX_DEVICE_ID_LEN, 0) == CR_SUCCESS) + { + /* compare to what we determined before */ + if (wcscmp(devID, lszPnPInstanceId) == 0) + { + found = TRUE; + break; + } + } + } + } + + if (deviceHwid) + { + free (deviceHwid); + deviceHwid = NULL; + } + + if (found) + break; + + index++; + } + + if (found == FALSE) + SetErrBreak (("Host Interface Network driver not found (0x%08X)", + GetLastError())); + + ok = SetupDiSetSelectedDevice (hDeviceInfo, &DeviceInfoData); + if (!ok) + SetErrBreak (("SetupDiSetSelectedDevice failed (0x%08X)", + GetLastError())); + + ok = SetupDiCallClassInstaller (DIF_REMOVE, hDeviceInfo, &DeviceInfoData); + if (!ok) + SetErrBreak (("SetupDiCallClassInstaller (DIF_REMOVE) failed (0x%08X)", + GetLastError())); + } + while (0); + + /* clean up the device info set */ + if (hDeviceInfo != INVALID_HANDLE_VALUE) + SetupDiDestroyDeviceInfoList (hDeviceInfo); + + if (FAILED (hrc)) + break; + } + while (0); + + return hrc; +} + +VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinCreateHostOnlyNetworkInterface(IN LPCWSTR pInfPath, IN bool bIsInfPathFile, + OUT GUID *pGuid, OUT BSTR *lppszName, OUT BSTR *pErrMsg) +{ + HRESULT hrc = S_OK; + + HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE; + SP_DEVINFO_DATA DeviceInfoData; + PVOID pQueueCallbackContext = NULL; + DWORD ret = 0; + BOOL found = FALSE; + BOOL registered = FALSE; + BOOL destroyList = FALSE; + WCHAR pWCfgGuidString [50]; + WCHAR DevName[256]; + + do + { + GUID netGuid; + SP_DRVINFO_DATA DriverInfoData; + SP_DEVINSTALL_PARAMS DeviceInstallParams; + TCHAR className [MAX_PATH]; + DWORD index = 0; + PSP_DRVINFO_DETAIL_DATA pDriverInfoDetail; + /* for our purposes, 2k buffer is more + * than enough to obtain the hardware ID + * of the VBoxNetAdp driver. */ + DWORD detailBuf [2048]; + + HKEY hkey = NULL; + DWORD cbSize; + DWORD dwValueType; + + /* initialize the structure size */ + DeviceInfoData.cbSize = sizeof (SP_DEVINFO_DATA); + DriverInfoData.cbSize = sizeof (SP_DRVINFO_DATA); + + /* copy the net class GUID */ + memcpy(&netGuid, &GUID_DEVCLASS_NET, sizeof(GUID_DEVCLASS_NET)); + + /* create an empty device info set associated with the net class GUID */ + hDeviceInfo = SetupDiCreateDeviceInfoList(&netGuid, NULL); + if (hDeviceInfo == INVALID_HANDLE_VALUE) + SetErrBreak (("SetupDiCreateDeviceInfoList failed (0x%08X)", + GetLastError())); + + /* get the class name from GUID */ + BOOL fResult = SetupDiClassNameFromGuid (&netGuid, className, MAX_PATH, NULL); + if (!fResult) + SetErrBreak (("SetupDiClassNameFromGuid failed (0x%08X)", + GetLastError())); + + /* create a device info element and add the new device instance + * key to registry */ + fResult = SetupDiCreateDeviceInfo (hDeviceInfo, className, &netGuid, NULL, NULL, + DICD_GENERATE_ID, &DeviceInfoData); + if (!fResult) + SetErrBreak (("SetupDiCreateDeviceInfo failed (0x%08X)", + GetLastError())); + + /* select the newly created device info to be the currently + selected member */ + fResult = SetupDiSetSelectedDevice (hDeviceInfo, &DeviceInfoData); + if (!fResult) + SetErrBreak (("SetupDiSetSelectedDevice failed (0x%08X)", + GetLastError())); + + if (pInfPath) + { + /* get the device install parameters and disable filecopy */ + DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); + fResult = SetupDiGetDeviceInstallParams (hDeviceInfo, &DeviceInfoData, + &DeviceInstallParams); + if (fResult) + { + memset(DeviceInstallParams.DriverPath, 0, sizeof(DeviceInstallParams.DriverPath)); + size_t pathLenght = wcslen(pInfPath) + 1/* null terminator */; + if (pathLenght < sizeof(DeviceInstallParams.DriverPath)/sizeof(DeviceInstallParams.DriverPath[0])) + { + memcpy(DeviceInstallParams.DriverPath, pInfPath, pathLenght*sizeof(DeviceInstallParams.DriverPath[0])); + + if (bIsInfPathFile) + { + DeviceInstallParams.Flags |= DI_ENUMSINGLEINF; + } + + fResult = SetupDiSetDeviceInstallParams(hDeviceInfo, &DeviceInfoData, + &DeviceInstallParams); + if (!fResult) + { + DWORD winEr = GetLastError(); + LogFlow(("SetupDiSetDeviceInstallParams failed, winEr (%d)\n", winEr)); + break; + } + } + else + { + LogFlow(("SetupDiSetDeviceInstallParams faileed: INF path is too long\n")); + break; + } + } + else + { + DWORD winEr = GetLastError(); + LogFlow(("SetupDiGetDeviceInstallParams failed, winEr (%d)\n", winEr)); + } + } + + /* build a list of class drivers */ + fResult = SetupDiBuildDriverInfoList (hDeviceInfo, &DeviceInfoData, + SPDIT_CLASSDRIVER); + if (!fResult) + SetErrBreak (("SetupDiBuildDriverInfoList failed (0x%08X)", + GetLastError())); + + destroyList = TRUE; + + /* enumerate the driver info list */ + while (TRUE) + { + BOOL ret; + + ret = SetupDiEnumDriverInfo (hDeviceInfo, &DeviceInfoData, + SPDIT_CLASSDRIVER, index, &DriverInfoData); + + /* if the function failed and GetLastError() returned + * ERROR_NO_MORE_ITEMS, then we have reached the end of the + * list. Otherwise there was something wrong with this + * particular driver. */ + if (!ret) + { + if (GetLastError() == ERROR_NO_MORE_ITEMS) + break; + else + { + index++; + continue; + } + } + + pDriverInfoDetail = (PSP_DRVINFO_DETAIL_DATA) detailBuf; + pDriverInfoDetail->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA); + + /* if we successfully find the hardware ID and it turns out to + * be the one for the loopback driver, then we are done. */ + if (SetupDiGetDriverInfoDetail (hDeviceInfo, + &DeviceInfoData, + &DriverInfoData, + pDriverInfoDetail, + sizeof (detailBuf), + NULL)) + { + TCHAR * t; + + /* pDriverInfoDetail->HardwareID is a MULTISZ string. Go through the + * whole list and see if there is a match somewhere. */ + t = pDriverInfoDetail->HardwareID; + while (t && *t && t < (TCHAR *) &detailBuf [RT_ELEMENTS(detailBuf)]) + { + if (!_tcsicmp(t, DRIVERHWID)) + break; + + t += _tcslen(t) + 1; + } + + if (t && *t && t < (TCHAR *) &detailBuf [RT_ELEMENTS(detailBuf)]) + { + found = TRUE; + break; + } + } + + index ++; + } + + if (!found) + SetErrBreak(("Could not find Host Interface Networking driver! Please reinstall")); + + /* set the loopback driver to be the currently selected */ + fResult = SetupDiSetSelectedDriver (hDeviceInfo, &DeviceInfoData, + &DriverInfoData); + if (!fResult) + SetErrBreak(("SetupDiSetSelectedDriver failed (0x%08X)", + GetLastError())); + + /* register the phantom device to prepare for install */ + fResult = SetupDiCallClassInstaller (DIF_REGISTERDEVICE, hDeviceInfo, + &DeviceInfoData); + if (!fResult) + { + DWORD err = GetLastError(); + SetErrBreak (("SetupDiCallClassInstaller failed (0x%08X)", + err)); + } + + /* registered, but remove if errors occur in the following code */ + registered = TRUE; + + /* ask the installer if we can install the device */ + fResult = SetupDiCallClassInstaller (DIF_ALLOW_INSTALL, hDeviceInfo, + &DeviceInfoData); + if (!fResult) + { + if (GetLastError() != ERROR_DI_DO_DEFAULT) + SetErrBreak (("SetupDiCallClassInstaller (DIF_ALLOW_INSTALL) failed (0x%08X)", + GetLastError())); + /* that's fine */ + } + + /* get the device install parameters and disable filecopy */ + DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); + fResult = SetupDiGetDeviceInstallParams (hDeviceInfo, &DeviceInfoData, + &DeviceInstallParams); + if (fResult) + { + pQueueCallbackContext = SetupInitDefaultQueueCallback(NULL); + if (pQueueCallbackContext) + { + DeviceInstallParams.InstallMsgHandlerContext = pQueueCallbackContext; + DeviceInstallParams.InstallMsgHandler = (PSP_FILE_CALLBACK)vboxNetCfgWinPspFileCallback; + fResult = SetupDiSetDeviceInstallParams (hDeviceInfo, &DeviceInfoData, + &DeviceInstallParams); + if (!fResult) + { + DWORD winEr = GetLastError(); + LogFlow(("SetupDiSetDeviceInstallParams failed, winEr (%d)\n", winEr)); + } + Assert(fResult); + } + else + { + DWORD winEr = GetLastError(); + LogFlow(("SetupInitDefaultQueueCallback failed, winEr (%d)\n", winEr)); + } + } + else + { + DWORD winEr = GetLastError(); + LogFlow(("SetupDiGetDeviceInstallParams failed, winEr (%d)\n", winEr)); + } + + /* install the files first */ + fResult = SetupDiCallClassInstaller (DIF_INSTALLDEVICEFILES, hDeviceInfo, + &DeviceInfoData); + if (!fResult) + SetErrBreak (("SetupDiCallClassInstaller (DIF_INSTALLDEVICEFILES) failed (0x%08X)", + GetLastError())); + /* get the device install parameters and disable filecopy */ + DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); + fResult = SetupDiGetDeviceInstallParams (hDeviceInfo, &DeviceInfoData, + &DeviceInstallParams); + if (fResult) + { + DeviceInstallParams.Flags |= DI_NOFILECOPY; + fResult = SetupDiSetDeviceInstallParams(hDeviceInfo, &DeviceInfoData, + &DeviceInstallParams); + if (!fResult) + SetErrBreak (("SetupDiSetDeviceInstallParams failed (0x%08X)", + GetLastError())); + } + + /* + * Register any device-specific co-installers for this device, + */ + fResult = SetupDiCallClassInstaller(DIF_REGISTER_COINSTALLERS, + hDeviceInfo, + &DeviceInfoData); + if (!fResult) + SetErrBreak (("SetupDiCallClassInstaller (DIF_REGISTER_COINSTALLERS) failed (0x%08X)", + GetLastError())); + + /* + * install any installer-specified interfaces. + * and then do the real install + */ + fResult = SetupDiCallClassInstaller(DIF_INSTALLINTERFACES, + hDeviceInfo, + &DeviceInfoData); + if (!fResult) + SetErrBreak (("SetupDiCallClassInstaller (DIF_INSTALLINTERFACES) failed (0x%08X)", + GetLastError())); + + fResult = SetupDiCallClassInstaller(DIF_INSTALLDEVICE, + hDeviceInfo, + &DeviceInfoData); + if (!fResult) + SetErrBreak (("SetupDiCallClassInstaller (DIF_INSTALLDEVICE) failed (0x%08X)", + GetLastError())); + + /* Figure out NetCfgInstanceId */ + hkey = SetupDiOpenDevRegKey(hDeviceInfo, + &DeviceInfoData, + DICS_FLAG_GLOBAL, + 0, + DIREG_DRV, + KEY_READ); + if (hkey == INVALID_HANDLE_VALUE) + SetErrBreak (("SetupDiOpenDevRegKey failed (0x%08X)", + GetLastError())); + + cbSize = sizeof (pWCfgGuidString); + DWORD ret; + ret = RegQueryValueExW (hkey, L"NetCfgInstanceId", NULL, + &dwValueType, (LPBYTE) pWCfgGuidString, &cbSize); + + RegCloseKey (hkey); + + if (!SetupDiGetDeviceRegistryPropertyW(hDeviceInfo, &DeviceInfoData, + SPDRP_FRIENDLYNAME , /* IN DWORD Property,*/ + NULL, /*OUT PDWORD PropertyRegDataType, OPTIONAL*/ + (PBYTE)DevName, /*OUT PBYTE PropertyBuffer,*/ + sizeof(DevName), /* IN DWORD PropertyBufferSize,*/ + NULL /*OUT PDWORD RequiredSize OPTIONAL*/)) + { + int err = GetLastError(); + if (err != ERROR_INVALID_DATA) + { + SetErrBreak (("SetupDiGetDeviceRegistryProperty failed (0x%08X)", + err)); + } + + if (!SetupDiGetDeviceRegistryPropertyW(hDeviceInfo, &DeviceInfoData, + SPDRP_DEVICEDESC, /* IN DWORD Property,*/ + NULL, /*OUT PDWORD PropertyRegDataType, OPTIONAL*/ + (PBYTE)DevName, /*OUT PBYTE PropertyBuffer,*/ + sizeof(DevName), /* IN DWORD PropertyBufferSize,*/ + NULL /*OUT PDWORD RequiredSize OPTIONAL*/ + )) + { + err = GetLastError(); + SetErrBreak (("SetupDiGetDeviceRegistryProperty failed (0x%08X)", + err)); + } + } + } + while (0); + + /* + * cleanup + */ + if (pQueueCallbackContext) + SetupTermDefaultQueueCallback(pQueueCallbackContext); + + if (hDeviceInfo != INVALID_HANDLE_VALUE) + { + /* an error has occurred, but the device is registered, we must remove it */ + if (ret != 0 && registered) + SetupDiCallClassInstaller(DIF_REMOVE, hDeviceInfo, &DeviceInfoData); + + found = SetupDiDeleteDeviceInfo(hDeviceInfo, &DeviceInfoData); + + /* destroy the driver info list */ + if (destroyList) + SetupDiDestroyDriverInfoList(hDeviceInfo, &DeviceInfoData, + SPDIT_CLASSDRIVER); + /* clean up the device info set */ + SetupDiDestroyDeviceInfoList (hDeviceInfo); + } + + /* return the network connection GUID on success */ + if (SUCCEEDED(hrc)) + { + WCHAR ConnectoinName[128]; + ULONG cbName = sizeof(ConnectoinName); + + HRESULT hr = VBoxNetCfgWinGenHostonlyConnectionName(DevName, ConnectoinName, &cbName); + if (SUCCEEDED(hr)) + hr = VBoxNetCfgWinRenameConnection(pWCfgGuidString, ConnectoinName); + + if (lppszName) + { + *lppszName = ::SysAllocString((const OLECHAR *) DevName); + if (!*lppszName) + { + LogFlow(("SysAllocString failed\n")); + hrc = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); + } + } + + if (pGuid) + { + hrc = CLSIDFromString(pWCfgGuidString, (LPCLSID)pGuid); + if (FAILED(hrc)) + LogFlow(("CLSIDFromString failed, hrc (0x%x)\n", hrc)); + } + + INetCfg *pNetCfg = NULL; + LPWSTR lpszApp = NULL; + hr = VBoxNetCfgWinQueryINetCfg(&pNetCfg, TRUE, L"VirtualBox Host-Only Creation", + 30 * 1000, /* on Vista we often get 6to4svc.dll holding the lock, wait for 30 sec. */ + /* TODO: special handling for 6to4svc.dll ???, i.e. several retrieves */ + &lpszApp); + if (hr == S_OK) + { + hr = vboxNetCfgWinEnumNetCfgComponents(pNetCfg, + &GUID_DEVCLASS_NETSERVICE, + vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority, + pGuid); + if (SUCCEEDED(hr)) + { + hr = vboxNetCfgWinEnumNetCfgComponents(pNetCfg, + &GUID_DEVCLASS_NETTRANS, + vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority, + pGuid); + if (SUCCEEDED(hr)) + hr = vboxNetCfgWinEnumNetCfgComponents(pNetCfg, + &GUID_DEVCLASS_NETCLIENT, + vboxNetCfgWinAdjustHostOnlyNetworkInterfacePriority, + pGuid); + } + + if (SUCCEEDED(hr)) + { + hr = pNetCfg->Apply(); + } + else + LogFlow(("Enumeration failed, hr 0x%x\n", hr)); + VBoxNetCfgWinReleaseINetCfg(pNetCfg, TRUE); + } + else if (hr == NETCFG_E_NO_WRITE_LOCK && lpszApp) + { + LogFlow(("Application %ws is holding the lock, failed\n", lpszApp)); + CoTaskMemFree(lpszApp); + } + else + LogFlow(("VBoxNetCfgWinQueryINetCfg failed, hr 0x%x\n", hr)); + } + return hrc; +} + +#undef SetErrBreak + diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/drv/Makefile.kup b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/Makefile.kup new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/Makefile.kup diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetAdp.inf b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetAdp.inf index 7b62e000f..b7d2702c8 100644 --- a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetAdp.inf +++ b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetAdp.inf @@ -1,9 +1,9 @@ +; $Id: VBoxNetAdp.inf 36184 2011-03-07 10:57:04Z vboxsync $ +; @file +; VBoxNetAdp.inf - VirtualBox Host-Only Driver inf file ; -; VirtualBox Network Adapter ; - -; -; Copyright (C) 2008 Oracle Corporation +; Copyright (C) 2011 Oracle Corporation ; ; This file is part of VirtualBox Open Source Edition (OSE), as ; available from http://www.virtualbox.org. This file is free software; @@ -14,11 +14,6 @@ ; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. ; -; -; Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample. -; Copyright (c) 1993-1999, Microsoft Corporation -; - [Version] signature = "$Windows NT$" ;cat CatalogFile = VBoxNetAdp.cat @@ -45,11 +40,9 @@ VBoxNetAdp.Files.Sys = 12 ; %windir%\System32\drivers [Manufacturer] %Provider% = VBox,NTx86,NTia64,NTamd64 -; For Win2K [VBox] %VBoxNetAdp_Desc% = VBoxNetAdp.ndi, sun_VBoxNetAdp -; For XP and later [VBox.NTx86] %VBoxNetAdp_Desc% = VBoxNetAdp.ndi, sun_VBoxNetAdp @@ -71,7 +64,6 @@ VBoxNetAdp.sys,,,2 [VBoxNetAdp.ndi.Services] AddService = VBoxNetAdp,0x2, VBoxNetAdp.AddService - [VBoxNetAdp.AddService] DisplayName = %VBoxNetAdp_Desc% ServiceType = 1 ;SERVICE_KERNEL_DRIVER @@ -87,12 +79,6 @@ HKR, Ndi\Interfaces, UpperRange, 0, "ndis5" HKR, Ndi\Interfaces, LowerRange, 0, "ethernet" [VBoxNetAdp.AddService] -; ---------------------------------------------------------------------- -; Add any miniport-specific parameters here. These are params that your -; [filter] device is going to use. -; -;HKR, Parameters, ParameterName, 0x10000, "MultiSz", "Parameter", "Value" -;HKR, Parameters, ParameterName2, 0x10001, 4 [Strings] Provider = "Oracle Corporation" diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.rc b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFlt-win.rc index 1af3c0cbb..41da1c3ea 100644 --- a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.rc +++ b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFlt-win.rc @@ -1,10 +1,9 @@ -/* $Id: VBoxNetFlt-win.rc $ */ +/* $Id: VBoxNetFlt-win.rc 36184 2011-03-07 10:57:04Z vboxsync $ */ /** @file * VBoxNetFlt - Resource file containing version info and icon. */ - /* - * Copyright (C) 2009-2010 Oracle Corporation + * Copyright (C) 2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt.inf b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFlt.inf index de3dfc82b..8745ae884 100644 --- a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt.inf +++ b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFlt.inf @@ -1,9 +1,10 @@ +; $Id: VBoxNetFlt.inf 36184 2011-03-07 10:57:04Z vboxsync $ +; @file +; VBoxNetFlt.inf - VirtualBox Bridged Networking Driver inf file +; Protocol edge ; -; VirtualBox Bridged Networking Driver ; - -; -; Copyright (C) 2008 Oracle Corporation +; Copyright (C) 2011 Oracle Corporation ; ; This file is part of VirtualBox Open Source Edition (OSE), as ; available from http://www.virtualbox.org. This file is free software; @@ -14,11 +15,6 @@ ; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. ; -; -; Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample. -; Copyright (c) 1993-1999, Microsoft Corporation -; - [Version] Signature = "$Windows NT$" ;cat CatalogFile = VBoxNetFlt.cat @@ -31,33 +27,24 @@ Provider = %Provider% [Manufacturer] -%Provider% = VBox,NTx86,NTia64,NTamd64 +%Provider% = VBox,NTx86,NTamd64 [ControlFlags] -;========================================================================= -; -;========================================================================= - -; For Win2K [VBox] %VBoxNetFlt_Desc% = VBoxNetFlt.ndi, sun_VBoxNetFlt -; For XP and later [VBox.NTx86] %VBoxNetFlt_Desc% = VBoxNetFlt.ndi, sun_VBoxNetFlt -[VBox.NTia64] -%VBoxNetFlt_Desc% = VBoxNetFlt.ndi, sun_VBoxNetFlt - [VBox.NTamd64] %VBoxNetFlt_Desc% = VBoxNetFlt.ndi, sun_VBoxNetFlt [VBoxNetFlt.ndi] AddReg = VBoxNetFlt.ndi.AddReg, VBoxNetFlt.AddReg -Characteristics = 0x4410 ; NCF_FILTER | NCF_NDIS_PROTOCOL !--Filter Specific--!! +Characteristics = 0x4410 ; NCF_FILTER | NCF_NDIS_PROTOCOL CopyFiles = VBoxNetFlt.Files.DLL, VBoxNetFlt.Files.Sys -CopyInf = VBoxNetFlt_m.inf +CopyInf = VBoxNetFltM.inf [VBoxNetFlt.ndi.Remove] DelFiles = VBoxNetFlt.Files.DLL, VBoxNetFlt.Files.Sys @@ -76,23 +63,13 @@ AddReg = VBoxNetFlt.AddService.AddReg [VBoxNetFlt.AddService.AddReg] -; ---------------------------------------------------------------------- -; Add any miniport-specific parameters here. These are params that your -; filter device is going to use. -; -;HKR, Parameters, ParameterName, 0x10000, "MultiSz", "Parameter", "Value" -;HKR, Parameters, ParameterName2, 0x10001, 4 - -; ---------------------------------------------------------------------- -; File copy -; [SourceDisksNames] 1=%DiskDescription%,"",, [SourceDisksFiles] VBoxNetFlt.sys=1 -VBoxNetFltNotify.dll=1 +VBoxNetFltNobj.dll=1 [DestinationDirs] DefaultDestDir = 12 @@ -103,29 +80,12 @@ VBoxNetFlt.Files.Sys = 12 ; %windir%\System32\drivers VBoxNetFlt.sys,,,2 [VBoxNetFlt.Files.DLL] -VBoxNetFltNotify.dll,,,2 - -; ---------------------------------------------------------------------- -; Filter Install -; +VBoxNetFltNobj.dll,,,2 [VBoxNetFlt.ndi.AddReg] HKR, Ndi, HelpText, , %VBoxNetFlt_HELP% - -; ---------------------------------------------------------------------- -; !!--Filter Specific--!! -; -; Note: -; 1. Other components may also have UpperRange/LowerRange but for filters -; the value of both of them must be noupper/nolower -; 2. The value FilterClass is required. -; 3. The value Service is required -; 4. FilterDeviceInfId is the InfId of the filter device (miniport) that will -; be installed for each filtered adapter. -; In this case this is sun_VBoxNetFltmp (refer to VBoxNetFlt_m.inf) -; -HKR, Ndi, ClsID, 0, {c631480a-acbe-4add-bb1d-3ed8aa52b5d9} -HKR, Ndi, ComponentDll, , VBoxNetFltNotify.dll +HKR, Ndi, ClsID, 0, {f374d1a0-bf08-4bdc-9cb2-c15ddaeef955} +HKR, Ndi, ComponentDll, , VBoxNetFltNobj.dll HKR, Ndi, FilterClass, , failover HKR, Ndi, FilterDeviceInfId, , sun_VBoxNetFltmp HKR, Ndi, Service, , VBoxNetFlt @@ -134,18 +94,11 @@ HKR, Ndi\Interfaces, LowerRange, , nolower HKR, Ndi\Interfaces, FilterMediaTypes, , "ethernet, nolower" [VBoxNetFlt.AddReg] -; The following key is Required -; The following key is VBoxNetFlt specific HKR, Parameters, Param1, 0, 4 -; ---------------------------------------------------------------------- [Strings] Provider = "Oracle Corporation" DiskDescription = "VirtualBox Bridged Networking Driver" - VBoxNetFlt_Desc = "VirtualBox Bridged Networking Driver" -VBoxNetFlt_HELP = "VBoxNetFlt Driver" -VBoxNetFltService_Desc = "VBoxNetFlt Service" - - - +VBoxNetFlt_HELP = "VirtualBox Bridged Networking Driver" +VBoxNetFltService_Desc = "VirtualBox Bridged Networking Service" diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltCmn-win.h b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltCmn-win.h new file mode 100644 index 000000000..9d89ededd --- /dev/null +++ b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltCmn-win.h @@ -0,0 +1,544 @@ +/* $Id: VBoxNetFltCmn-win.h 36184 2011-03-07 10:57:04Z vboxsync $ */ +/** @file + * VBoxNetFltCmn-win.h - Bridged Networking Driver, Windows Specific Code. + * Common header with configuration defines and global defs + */ +/* + * Copyright (C) 2011 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + */ +#ifndef ___VBoxNetFltCmn_win_h___ +#define ___VBoxNetFltCmn_win_h___ + +#define LOG_GROUP LOG_GROUP_NET_FLT_DRV + +/* debugging flags */ +#ifdef DEBUG +//# define DEBUG_NETFLT_PACKETS +# ifndef DEBUG_misha +# define DEBUG_NETFLT_NOASSERT +# endif +/* # define DEBUG_NETFLT_LOOPBACK */ +/* receive logic has several branches */ +/* the DEBUG_NETFLT_RECV* macros used to debug the ProtocolReceive callback + * which is typically not used in case the underlying miniport indicates the packets with NdisMIndicateReceivePacket + * the best way to debug the ProtocolReceive (which in turn has several branches) is to enable the DEBUG_NETFLT_RECV + * one by one in the below order, i.e. + * first DEBUG_NETFLT_RECV + * then DEBUG_NETFLT_RECV + DEBUG_NETFLT_RECV_NOPACKET */ +//# define DEBUG_NETFLT_RECV +//# define DEBUG_NETFLT_RECV_NOPACKET +//# define DEBUG_NETFLT_RECV_TRANSFERDATA +/* use ExAllocatePoolWithTag instead of NdisAllocateMemoryWithTag */ +// #define DEBUG_NETFLT_USE_EXALLOC +#endif + +#include <VBox/intnet.h> +#include <VBox/log.h> +#include <VBox/err.h> +#include <VBox/version.h> +#include <iprt/initterm.h> +#include <iprt/assert.h> +#include <iprt/spinlock.h> +#include <iprt/semaphore.h> +#include <iprt/process.h> +#include <iprt/alloc.h> +#include <iprt/alloca.h> +#include <iprt/time.h> +#include <iprt/net.h> + +RT_C_DECLS_BEGIN +/* ntddk.h has a missing #pragma pack(), work around it + * see #ifdef VBOX_WITH_WORKAROUND_MISSING_PACK below for detail */ +#define VBOX_WITH_WORKAROUND_MISSING_PACK +#if (_MSC_VER >= 1400) && !defined(VBOX_WITH_PATCHED_DDK) +# define _InterlockedExchange _InterlockedExchange_StupidDDKVsCompilerCrap +# define _InterlockedExchangeAdd _InterlockedExchangeAdd_StupidDDKVsCompilerCrap +# define _InterlockedCompareExchange _InterlockedCompareExchange_StupidDDKVsCompilerCrap +# define _InterlockedAddLargeStatistic _InterlockedAddLargeStatistic_StupidDDKVsCompilerCrap +# define _interlockedbittestandset _interlockedbittestandset_StupidDDKVsCompilerCrap +# define _interlockedbittestandreset _interlockedbittestandreset_StupidDDKVsCompilerCrap +# define _interlockedbittestandset64 _interlockedbittestandset64_StupidDDKVsCompilerCrap +# define _interlockedbittestandreset64 _interlockedbittestandreset64_StupidDDKVsCompilerCrap +# pragma warning(disable : 4163) +# ifdef VBOX_WITH_WORKAROUND_MISSING_PACK +# pragma warning(disable : 4103) +# endif +# include <ntddk.h> +# pragma warning(default : 4163) +# ifdef VBOX_WITH_WORKAROUND_MISSING_PACK +# pragma pack() +# pragma warning(default : 4103) +# endif +# undef _InterlockedExchange +# undef _InterlockedExchangeAdd +# undef _InterlockedCompareExchange +# undef _InterlockedAddLargeStatistic +# undef _interlockedbittestandset +# undef _interlockedbittestandreset +# undef _interlockedbittestandset64 +# undef _interlockedbittestandreset64 +# include <ndis.h> +#else +//# include <ntddk.h> +/* can include ndis.h right away */ +# include <ndis.h> +#endif +RT_C_DECLS_END + +#define VBOXNETFLT_OS_SPECFIC 1 + +/** version + * NOTE: we are NOT using NDIS 5.1 features now */ +#ifdef NDIS51_MINIPORT +# define VBOXNETFLT_VERSION_MP_NDIS_MAJOR 5 +# define VBOXNETFLT_VERSION_MP_NDIS_MINOR 1 +#else +# define VBOXNETFLT_VERSION_MP_NDIS_MAJOR 5 +# define VBOXNETFLT_VERSION_MP_NDIS_MINOR 0 +#endif + +#ifndef VBOXNETADP +#ifdef NDIS51 +# define VBOXNETFLT_VERSION_PT_NDIS_MAJOR 5 +# define VBOXNETFLT_VERSION_PT_NDIS_MINOR 1 /* todo: use 0 here as well ? */ +#else +# define VBOXNETFLT_VERSION_PT_NDIS_MAJOR 5 +# define VBOXNETFLT_VERSION_PT_NDIS_MINOR 0 +#endif + +# define VBOXNETFLT_NAME_PROTOCOL L"VBoxNetFlt" +/** device to be used to prevent the driver unload & ioctl interface (if necessary in the future) */ +# define VBOXNETFLT_NAME_LINK L"\\DosDevices\\Global\\VBoxNetFlt" +# define VBOXNETFLT_NAME_DEVICE L"\\Device\\VBoxNetFlt" +#else +# define VBOXNETFLT_NAME_LINK L"\\DosDevices\\Global\\VBoxNetAdp" +# define VBOXNETFLT_NAME_DEVICE L"\\Device\\VBoxNetAdp" +#endif + +typedef struct VBOXNETFLTINS *PVBOXNETFLTINS; + +/** configuration */ + +/** Ndis Packet pool settings + * these are applied to both receive and send packet pools */ +/* number of packets for normal used */ +#define VBOXNETFLT_PACKET_POOL_SIZE_NORMAL 0x000000FF +/* number of additional overflow packets */ +#define VBOXNETFLT_PACKET_POOL_SIZE_OVERFLOW 0x0000FF00 + +/** packet queue size used when the driver is working in the "active" mode */ +#define VBOXNETFLT_PACKET_INFO_POOL_SIZE 0x0000FFFF + +#ifndef VBOXNETADP +/** memory tag used for memory allocations + * (VBNF stands for VBox NetFlt) */ +# define VBOXNETFLT_MEM_TAG 'FNBV' +#else +/** memory tag used for memory allocations + * (VBNA stands for VBox NetAdp) */ +# define VBOXNETFLT_MEM_TAG 'ANBV' +#endif + +/** receive and transmit Ndis buffer pool size */ +#define VBOXNETFLT_BUFFER_POOL_SIZE_TX 128 +#define VBOXNETFLT_BUFFER_POOL_SIZE_RX 128 + +#define VBOXNETFLT_PACKET_ETHEADER_SIZE 14 +#define VBOXNETFLT_PACKET_HEADER_MATCH_SIZE 24 +#define VBOXNETFLT_PACKET_QUEUE_SG_SEGS_ALLOC 32 + + +#if defined(DEBUG_NETFLT_PACKETS) || !defined(VBOX_LOOPBACK_USEFLAGS) +# define VBOXNETFLT_PACKETMATCH_LENGTH (VBOXNETFLT_PACKET_ETHEADER_SIZE + 2) +#endif + +#ifdef VBOXNETADP +#define VBOXNETADP_HEADER_SIZE 14 +#define VBOXNETADP_MAX_DATA_SIZE 1500 +#define VBOXNETADP_MAX_PACKET_SIZE (VBOXNETADP_HEADER_SIZE + VBOXNETADP_MAX_DATA_SIZE) +#define VBOXNETADP_MIN_PACKET_SIZE 60 +/* link speed 100Mbps (measured in 100 bps) */ +#define VBOXNETADP_LINK_SPEED 1000000 +#define VBOXNETADP_MAX_LOOKAHEAD_SIZE VBOXNETADP_MAX_DATA_SIZE +#define VBOXNETADP_VENDOR_ID 0x080027 +#define VBOXNETADP_VENDOR_DRIVER_VERSION 0x00010000 +#define VBOXNETADP_VENDOR_DESC "Sun" +#define VBOXNETADP_MAX_MCAST_LIST 32 +#define VBOXNETADP_ETH_ADDRESS_LENGTH 6 + +//#define VBOXNETADP_REPORT_DISCONNECTED +#endif +/* type defs */ + +/** Flag specifying that the type of enqueued packet + * if set the info contains the PINTNETSG packet + * if clear the packet info contains the PNDIS_PACKET packet + * Typically the packet queue we are maintaining contains PNDIS_PACKETs only, + * however in case the underlying miniport indicates a packet with the NDIS_STATUS_RESOURCES status + * we MUST return the packet back to the miniport immediately + * this is why we are creating the INTNETSG, copying the ndis packet info there and enqueueing it */ +#define VBOXNETFLT_PACKET_SG 0x00000001 + +/** the flag specifying that the packet source + * if set the packet comes from the host (upperlying protocol) + * if clear the packet comes from the wire (underlying miniport) */ +#define VBOXNETFLT_PACKET_SRC_HOST 0x00000002 + +#ifndef VBOXNETFLT_NO_PACKET_QUEUE +/** flag specifying the packet was originated by our driver + * i.e. we could use it on our needs and should not return it + * we are enqueueing "our" packets on ProtocolReceive call-back when + * Ndis does not give us a receive packet (the driver below us has called NdisM..IndicateReceive) + * this is supported for Ndis Packet only */ +#define VBOXNETFLT_PACKET_MINE 0x00000004 + +/** flag passed to vboxNetFltWinQuEnqueuePacket specifying that the packet should be copied + * this is supported for Ndis Packet only */ +#define VBOXNETFLT_PACKET_COPY 0x00000008 +#endif + +/** packet queue element containing the packet info */ +typedef struct VBOXNETFLT_PACKET_INFO +{ + /** list entry used for enqueueing the info */ + LIST_ENTRY ListEntry; + /** pointer to the pool containing this packet info */ + struct VBOXNETFLT_PACKET_INFO_POOL *pPool; + /** flags describing the referenced packet. Contains PACKET_xxx flags (i.e. PACKET_SG, PACKET_SRC_HOST) */ + uint32_t fFlags; + /** pointer to the packet this info represents */ + PVOID pPacket; +} VBOXNETFLT_PACKET_INFO, *PVBOXNETFLT_PACKET_INFO; + +/* paranoid check to make sure the elements in the packet info array are properly aligned */ +AssertCompile((sizeof(VBOXNETFLT_PACKET_INFO) & (sizeof(PVOID) - 1)) == 0); + +/** represents the packet queue */ +typedef LIST_ENTRY PVBOXNETFLT_ACKET_QUEUE, *PVBOXNETFLT_PACKET_QUEUE; + +/* + * we are using non-interlocked versions of LIST_ENTRY-related operations macros and synchronize + * access to the queue and its elements by acquiring/releasing a spinlock using Ndis[Acquire,Release]Spinlock + * + * we are NOT using interlocked versions of insert/remove head/tail list functions because we need to iterate though + * the queue elements as well as remove elements from the midle of the queue + * + * * @todo: it seems that we can switch to using interlocked versions of list-entry functions + * since we have removed all functionality (mentioned above, i.e. queue elements iteration, etc.) that might prevent us from doing this + */ +typedef struct VBOXNETFLT_INTERLOCKED_PACKET_QUEUE +{ + /** queue */ + PVBOXNETFLT_ACKET_QUEUE Queue; + /** queue lock */ + NDIS_SPIN_LOCK Lock; +} VBOXNETFLT_INTERLOCKED_PACKET_QUEUE, *PVBOXNETFLT_INTERLOCKED_PACKET_QUEUE; + +typedef struct VBOXNETFLT_SINGLE_LIST +{ + /** queue */ + SINGLE_LIST_ENTRY Head; + /** pointer to the list tail. used to enqueue elements to the tail of the list */ + PSINGLE_LIST_ENTRY pTail; +} VBOXNETFLT_SINGLE_LIST, *PVBOXNETFLT_SINGLE_LIST; + +typedef struct VBOXNETFLT_INTERLOCKED_SINGLE_LIST +{ + /** queue */ + VBOXNETFLT_SINGLE_LIST List; + /** queue lock */ + NDIS_SPIN_LOCK Lock; +} VBOXNETFLT_INTERLOCKED_SINGLE_LIST, *PVBOXNETFLT_INTERLOCKED_SINGLE_LIST; + +/** packet info pool contains free packet info elements to be used for the packet queue + * we are using the pool mechanism to allocate packet queue elements + * the pool mechanism is pretty simple now, we are allocating a bunch of memory + * for maintaining VBOXNETFLT_PACKET_INFO_POOL_SIZE queue elements and just returning null when the pool is exhausted + * This mechanism seems to be enough for now since we are using VBOXNETFLT_PACKET_INFO_POOL_SIZE = 0xffff which is + * the maximum size of packets the ndis packet pool supports */ +typedef struct VBOXNETFLT_PACKET_INFO_POOL +{ + /** free packet info queue */ + VBOXNETFLT_INTERLOCKED_PACKET_QUEUE Queue; + /** memory bugger used by the pool */ + PVOID pBuffer; +} VBOXNETFLT_PACKET_INFO_POOL, *PVBOXNETFLT_PACKET_INFO_POOL; + +typedef enum VBOXNETDEVOPSTATE +{ + kVBoxNetDevOpState_InvalidValue = 0, + kVBoxNetDevOpState_Initializing, + kVBoxNetDevOpState_Initialized, + kVBoxNetDevOpState_Deinitializing, + kVBoxNetDevOpState_Deinitialized, + +} VBOXNETDEVOPSTATE; + +typedef enum VBOXNETFLT_WINIFSTATE +{ + /** The usual invalid state. */ + kVBoxWinIfState_Invalid = 0, + /** Initialization. */ + kVBoxWinIfState_Connecting, + /** Connected fuly functional state */ + kVBoxWinIfState_Connected, + /** Disconnecting */ + kVBoxWinIfState_Disconnecting, + /** Disconnected */ + kVBoxWinIfState_Disconnected, +} VBOXNETFLT_WINIFSTATE; + +/** structure used to maintain the state and reference count of the miniport and protocol */ +typedef struct VBOXNETFLT_WINIF_DEVICE +{ + /** initialize state */ + VBOXNETDEVOPSTATE OpState; + /** ndis power state */ + NDIS_DEVICE_POWER_STATE PowerState; + /** reference count */ + uint32_t cReferences; +} VBOXNETFLT_WINIF_DEVICE, *PVBOXNETFLT_WINIF_DEVICE; + +#define VBOXNDISREQUEST_INPROGRESS 1 +#define VBOXNDISREQUEST_QUEUED 2 + +typedef struct VBOXNETFLTWIN_STATE +{ + union + { + struct + { + UINT fRequestInfo : 2; + UINT fInterfaceClosing : 1; + UINT fStandBy : 1; + UINT fProcessingPacketFilter : 1; + UINT fPPFNetFlt : 1; + UINT fUpperProtSetFilterInitialized : 1; + UINT Reserved : 25; + }; + UINT Value; + }; +} VBOXNETFLTWIN_STATE, *PVBOXNETFLTWIN_STATE; + +DECLINLINE(VBOXNETFLTWIN_STATE) vboxNetFltWinAtomicUoReadWinState(VBOXNETFLTWIN_STATE State) +{ + UINT fValue = ASMAtomicUoReadU32((volatile uint32_t *)&State.Value); + return *((PVBOXNETFLTWIN_STATE)((void*)&fValue)); +} + +/* miniport layer globals */ +typedef struct VBOXNETFLTGLOBALS_MP +{ + /** our miniport handle */ + NDIS_HANDLE hMiniport; + /** ddis wrapper handle */ + NDIS_HANDLE hNdisWrapper; +} VBOXNETFLTGLOBALS_MP, *PVBOXNETFLTGLOBALS_MP; + +#ifndef VBOXNETADP +/* protocol layer globals */ +typedef struct VBOXNETFLTGLOBALS_PT +{ + /** our protocol handle */ + NDIS_HANDLE hProtocol; +} VBOXNETFLTGLOBALS_PT, *PVBOXNETFLTGLOBALS_PT; +#endif /* #ifndef VBOXNETADP */ + +typedef struct VBOXNETFLTGLOBALS_WIN +{ + /** synch event used for device creation synchronization */ + KEVENT SynchEvent; + /** Device reference count */ + int cDeviceRefs; + /** ndis device */ + NDIS_HANDLE hDevice; + /** device object */ + PDEVICE_OBJECT pDevObj; + /* loopback flags */ + /* ndis packet flags to disable packet loopback */ + UINT fPacketDontLoopBack; + /* ndis packet flags specifying whether the packet is looped back */ + UINT fPacketIsLoopedBack; + /* Minport info */ + VBOXNETFLTGLOBALS_MP Mp; +#ifndef VBOXNETADP + /* Protocol info */ + VBOXNETFLTGLOBALS_PT Pt; +#endif +} VBOXNETFLTGLOBALS_WIN, *PVBOXNETFLTGLOBALS_WIN; + +extern VBOXNETFLTGLOBALS_WIN g_VBoxNetFltGlobalsWin; + +/** represents filter driver device context*/ +typedef struct VBOXNETFLTWIN +{ + /** handle used by miniport edge for ndis calls */ + NDIS_HANDLE hMiniport; + /** miniport edge state */ + VBOXNETFLT_WINIF_DEVICE MpState; + /** ndis packet pool used for receives */ + NDIS_HANDLE hRecvPacketPool; + /** ndis buffer pool used for receives */ + NDIS_HANDLE hRecvBufferPool; + /** driver bind adapter state. */ + VBOXNETFLT_WINIFSTATE enmState; +#ifndef VBOXNETADP + /* misc state flags */ + VBOXNETFLTWIN_STATE StateFlags; + /** handle used by protocol edge for ndis calls */ + NDIS_HANDLE hBinding; + /** protocol edge state */ + VBOXNETFLT_WINIF_DEVICE PtState; + /** ndis packet pool used for receives */ + NDIS_HANDLE hSendPacketPool; + /** ndis buffer pool used for receives */ + NDIS_HANDLE hSendBufferPool; + /** used for maintaining the pending send packets for handling packet loopback */ + VBOXNETFLT_INTERLOCKED_SINGLE_LIST SendPacketQueue; + /** used for serializing calls to the NdisRequest in the vboxNetFltWinSynchNdisRequest */ + RTSEMFASTMUTEX hSynchRequestMutex; + /** event used to synchronize with the Ndis Request completion in the vboxNetFltWinSynchNdisRequest */ + KEVENT hSynchCompletionEvent; + /** status of the Ndis Request initiated by the vboxNetFltWinSynchNdisRequest */ + NDIS_STATUS volatile SynchCompletionStatus; + /** pointer to the Ndis Request being executed by the vboxNetFltWinSynchNdisRequest */ + PNDIS_REQUEST volatile pSynchRequest; + /** open/close adapter status. + * Since ndis adapter open and close requests may complete asynchronously, + * we are using event mechanism to wait for open/close completion + * the status field is being set by the completion call-back */ + NDIS_STATUS OpenCloseStatus; + /** open/close adaptor completion event */ + NDIS_EVENT OpenCloseEvent; + /** medium we are attached to */ + NDIS_MEDIUM enmMedium; + /** + * Passdown request info + */ + /** ndis request we pass down to the miniport below */ + NDIS_REQUEST PassDownRequest; + /** Ndis pass down request bytes read or written original pointer */ + PULONG pcPDRBytesRW; + /** Ndis pass down request bytes needed original pointer */ + PULONG pcPDRBytesNeeded; + /** true if we should indicate the receive complete used by the ProtocolReceive mechanism. + * We need to indicate it only with the ProtocolReceive + NdisMEthIndicateReceive path. + * Note: we're using KeGetCurrentProcessorNumber, which is not entirely correct in case + * we're running on 64bit win7+, which can handle > 64 CPUs, however since KeGetCurrentProcessorNumber + * always returns the number < than the number of CPUs in the first group, we're guaranteed to have CPU index < 64 + * @todo: use KeGetCurrentProcessorNumberEx for Win7+ 64 and dynamically extended array */ + bool abIndicateRxComplete[64]; + /** Pending transfer data packet queue (i.e. packets that were indicated as pending on NdisTransferData call */ + VBOXNETFLT_INTERLOCKED_SINGLE_LIST TransferDataList; + /* mac options initialized on OID_GEN_MAC_OPTIONS */ + ULONG fMacOptions; + /** our miniport devuice name */ + NDIS_STRING MpDeviceName; + /** synchronize with unbind with Miniport initialization */ + NDIS_EVENT MpInitCompleteEvent; + /** media connect status that we indicated */ + NDIS_STATUS MpIndicatedMediaStatus; + /** media connect status pending to indicate */ + NDIS_STATUS MpUnindicatedMediaStatus; + /** packet filter flags set by the upper protocols */ + ULONG fUpperProtocolSetFilter; + /** packet filter flags set by the upper protocols */ + ULONG fSetFilterBuffer; + /** packet filter flags set by us */ + ULONG fOurSetFilter; +#else + volatile ULONG cTxSuccess; + volatile ULONG cRxSuccess; + volatile ULONG cTxError; + volatile ULONG cRxError; +#endif +} VBOXNETFLTWIN, *PVBOXNETFLTWIN; + +typedef struct VBOXNETFLT_PACKET_QUEUE_WORKER +{ + /** this event is used to initiate a packet queue worker thread kill */ + KEVENT KillEvent; + /** this event is used to notify a worker thread that the packets are added to the queue */ + KEVENT NotifyEvent; + /** pointer to the packet queue worker thread object */ + PKTHREAD pThread; + /** pointer to the SG used by the packet queue for IntNet receive notifications */ + PINTNETSG pSG; + /** Packet queue */ + VBOXNETFLT_INTERLOCKED_PACKET_QUEUE PacketQueue; + /** Packet info pool, i.e. the pool for the packet queue elements */ + VBOXNETFLT_PACKET_INFO_POOL PacketInfoPool; +} VBOXNETFLT_PACKET_QUEUE_WORKER, *PVBOXNETFLT_PACKET_QUEUE_WORKER; + +/* protocol reserved data held in ndis packet */ +typedef struct VBOXNETFLT_PKTRSVD_PT +{ + /** original packet received from the upperlying protocol + * can be null if the packet was originated by intnet */ + PNDIS_PACKET pOrigPacket; + /** pointer to the buffer to be freed on send completion + * can be null if no buffer is to be freed */ + PVOID pBufToFree; +#if !defined(VBOX_LOOPBACK_USEFLAGS) || defined(DEBUG_NETFLT_PACKETS) + SINGLE_LIST_ENTRY ListEntry; + /* true if the packet is from IntNet */ + bool bFromIntNet; +#endif +} VBOXNETFLT_PKTRSVD_PT, *PVBOXNETFLT_PKTRSVD_PT; + +/** miniport reserved data held in ndis packet */ +typedef struct VBOXNETFLT_PKTRSVD_MP +{ + /** original packet received from the underling miniport + * can be null if the packet was originated by intnet */ + PNDIS_PACKET pOrigPacket; + /** pointer to the buffer to be freed on receive completion + * can be null if no buffer is to be freed */ + PVOID pBufToFree; +} VBOXNETFLT_PKTRSVD_MP, *PVBOXNETFLT_PKTRSVD_MP; + +/** represents the data stored in the protocol reserved field of ndis packet on NdisTransferData processing */ +typedef struct VBOXNETFLT_PKTRSVD_TRANSFERDATA_PT +{ + /** next packet in a list */ + SINGLE_LIST_ENTRY ListEntry; + /* packet buffer start */ + PNDIS_BUFFER pOrigBuffer; +} VBOXNETFLT_PKTRSVD_TRANSFERDATA_PT, *PVBOXNETFLT_PKTRSVD_TRANSFERDATA_PT; + +/* VBOXNETFLT_PKTRSVD_TRANSFERDATA_PT should fit into PROTOCOL_RESERVED_SIZE_IN_PACKET because we use protocol reserved part + * of our miniport edge on transfer data processing for honding our own info */ +AssertCompile(sizeof (VBOXNETFLT_PKTRSVD_TRANSFERDATA_PT) <= PROTOCOL_RESERVED_SIZE_IN_PACKET); +/* this should fit in MiniportReserved */ +AssertCompile(sizeof (VBOXNETFLT_PKTRSVD_MP) <= RT_SIZEOFMEMB(NDIS_PACKET, MiniportReserved)); +/* we use RTAsmAtomic*U32 for those, make sure we're correct */ +AssertCompile(sizeof (NDIS_DEVICE_POWER_STATE) == sizeof (uint32_t)); +AssertCompile(sizeof (UINT) == sizeof (uint32_t)); + + +#define NDIS_FLAGS_SKIP_LOOPBACK_W2K 0x400 + +#include "../../VBoxNetFltInternal.h" +#include "VBoxNetFltRt-win.h" +#ifndef VBOXNETADP +#include "VBoxNetFltP-win.h" +#endif +# include "VBoxNetFltM-win.h" + +#ifdef DEBUG_NETFLT_NOASSERT +# ifdef Assert +# undef Assert +# endif + +# define Assert(_expr) do {} while (0) +#endif /* #ifdef DEBUG_NETFLT_NOASSERT */ + +#endif /* #ifndef ___VBoxNetFltCmn_win_h___ */ diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltM-win.cpp b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltM-win.cpp new file mode 100644 index 000000000..897dc09c2 --- /dev/null +++ b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltM-win.cpp @@ -0,0 +1,1552 @@ +/* $Id: VBoxNetFltM-win.cpp 36184 2011-03-07 10:57:04Z vboxsync $ */ +/** @file + * VBoxNetFltM-win.cpp - Bridged Networking Driver, Windows Specific Code. + * Miniport edge + */ +/* + * Copyright (C) 2011 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + */ +#include "VBoxNetFltCmn-win.h" + +static const char* vboxNetFltWinMpDumpOid(ULONG oid); + +#ifndef VBOXNETADP +static NDIS_STATUS vboxNetFltWinMpInitialize(OUT PNDIS_STATUS OpenErrorStatus, + OUT PUINT SelectedMediumIndex, + IN PNDIS_MEDIUM MediumArray, + IN UINT MediumArraySize, + IN NDIS_HANDLE MiniportAdapterHandle, + IN NDIS_HANDLE WrapperConfigurationContext) +{ + PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)NdisIMGetDeviceContext(MiniportAdapterHandle); + NDIS_STATUS Status = NDIS_STATUS_FAILURE; + + LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p)\n", pNetFlt)); + + pNetFlt->u.s.WinIf.hMiniport = MiniportAdapterHandle; + Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Initializing); + /* the MP state should be already set to kVBoxNetDevOpState_Initializing, just a paranoia + * in case NDIS for some reason calls us in some irregular way */ + vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Initializing); + + NDIS_MEDIUM enmMedium = pNetFlt->u.s.WinIf.enmMedium; + if (enmMedium == NdisMediumWan) + enmMedium = NdisMedium802_3; + + UINT i = 0; + for (; i < MediumArraySize; i++) + { + if (MediumArray[i] == enmMedium) + { + *SelectedMediumIndex = i; + break; + } + } + + do + { + if (i != MediumArraySize) + { + NdisMSetAttributesEx(MiniportAdapterHandle, pNetFlt, 0, + NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT | + NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT| + NDIS_ATTRIBUTE_INTERMEDIATE_DRIVER | + NDIS_ATTRIBUTE_DESERIALIZE | + NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND, + NdisInterfaceInternal /* 0 */); + + pNetFlt->u.s.WinIf.MpIndicatedMediaStatus = NDIS_STATUS_MEDIA_CONNECT; + Assert(vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.MpState) == NdisDeviceStateD3); + vboxNetFltWinSetPowerState(&pNetFlt->u.s.WinIf.MpState, NdisDeviceStateD0); + Assert(pNetFlt->u.s.WinIf.MpState.OpState == kVBoxNetDevOpState_Initializing); + vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Initialized); + + Status = NDIS_STATUS_SUCCESS; + break; + } + else + { + Status = NDIS_STATUS_UNSUPPORTED_MEDIA; + } + + Assert(Status != NDIS_STATUS_SUCCESS); + Assert(vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.MpState) == NdisDeviceStateD3); + Assert(pNetFlt->u.s.WinIf.MpState.OpState == kVBoxNetDevOpState_Initializing); + vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized); + } while (0); + + NdisSetEvent(&pNetFlt->u.s.WinIf.MpInitCompleteEvent); + + LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), Status (0x%x)\n", pNetFlt, Status)); + + *OpenErrorStatus = Status; + + return Status; +} + +/** + * process the packet send in a "passthru" mode + */ +static NDIS_STATUS vboxNetFltWinSendPassThru(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket +#ifdef VBOXNETFLT_NO_PACKET_QUEUE + , bool bNetFltActive +#endif + ) +{ + PNDIS_PACKET pMyPacket; + NDIS_STATUS Status = vboxNetFltWinPrepareSendPacket(pNetFlt, pPacket, &pMyPacket); + Assert(Status == NDIS_STATUS_SUCCESS); + if (Status == NDIS_STATUS_SUCCESS) + { +#if !defined(VBOX_LOOPBACK_USEFLAGS) /* || defined(DEBUG_NETFLT_PACKETS) */ +# ifdef VBOXNETFLT_NO_PACKET_QUEUE + if (bNetFltActive) + vboxNetFltWinLbPutSendPacket(pNetFlt, pMyPacket, false /* bFromIntNet */); +# else + /* no need for the loop enqueue & check in a passthru mode , ndis will do everything for us */ +# endif +#endif + NdisSend(&Status, pNetFlt->u.s.WinIf.hBinding, pMyPacket); + if (Status != NDIS_STATUS_PENDING) + { + NdisIMCopySendCompletePerPacketInfo(pPacket, pMyPacket); +#if defined(VBOXNETFLT_NO_PACKET_QUEUE) && !defined(VBOX_LOOPBACK_USEFLAGS) + if (bNetFltActive) + vboxNetFltWinLbRemoveSendPacket(pNetFlt, pMyPacket); +#endif + NdisFreePacket(pMyPacket); + } + } + return Status; +} + +#else /* defined VBOXNETADP */ +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpDoDeinitialization(PVBOXNETFLTINS pNetFlt) +{ + RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; + uint64_t NanoTS = RTTimeSystemNanoTS(); + + Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Initialized); + + RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp); + ASMAtomicUoWriteBool(&pNetFlt->fDisconnectedFromHost, true); + ASMAtomicUoWriteBool(&pNetFlt->fRediscoveryPending, false); + ASMAtomicUoWriteU64(&pNetFlt->NanoTSLastRediscovery, NanoTS); + + vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitializing); + + RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); + + vboxNetFltWinWaitDereference(&pNetFlt->u.s.WinIf.MpState); + + /* check packet pool is empty */ + int cPPUsage = NdisPacketPoolUsage(pNetFlt->u.s.WinIf.hRecvPacketPool); + Assert(cPPUsage == 0); + /* for debugging only, ignore the err in release */ + NOREF(cPPUsage); + + vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized); + + return NDIS_STATUS_SUCCESS; +} + +static NDIS_STATUS vboxNetFltWinMpReadApplyConfig(PVBOXNETFLTINS pThis, NDIS_HANDLE hMiniportAdapter, NDIS_HANDLE hWrapperConfigurationContext) +{ + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + NDIS_HANDLE hConfiguration; + PNDIS_CONFIGURATION_PARAMETER pParameterValue; + NDIS_STRING strMAC = NDIS_STRING_CONST("MAC"); + RTMAC mac; + + NdisOpenConfiguration( + &Status, + &hConfiguration, + hWrapperConfigurationContext); + Assert(Status == NDIS_STATUS_SUCCESS); + if (Status == NDIS_STATUS_SUCCESS) + { + do + { + int rc; + NDIS_CONFIGURATION_PARAMETER param; + WCHAR MacBuf[13]; + + NdisReadConfiguration(&Status, + &pParameterValue, + hConfiguration, + &strMAC, + NdisParameterString); +// Assert(Status == NDIS_STATUS_SUCCESS); + if (Status == NDIS_STATUS_SUCCESS) + { + + rc = vboxNetFltWinMACFromNdisString(&mac, &pParameterValue->ParameterData.StringData); + AssertRC(rc); + if (RT_SUCCESS(rc)) + { + break; + } + } + + vboxNetFltWinGenerateMACAddress(&mac); + param.ParameterType = NdisParameterString; + param.ParameterData.StringData.Buffer = MacBuf; + param.ParameterData.StringData.MaximumLength = sizeof(MacBuf); + + rc = vboxNetFltWinMAC2NdisString(&mac, ¶m.ParameterData.StringData); + Assert(RT_SUCCESS(rc)); + if (RT_SUCCESS(rc)) + { + NdisWriteConfiguration(&Status, + hConfiguration, + &strMAC, + ¶m); + Assert(Status == NDIS_STATUS_SUCCESS); + if (Status != NDIS_STATUS_SUCCESS) + { + /* ignore the failure */ + Status = NDIS_STATUS_SUCCESS; + } + } + } while (0); + + NdisCloseConfiguration(hConfiguration); + } + else + { + vboxNetFltWinGenerateMACAddress(&mac); + } + + pThis->u.s.MacAddr = mac; + + return NDIS_STATUS_SUCCESS; +} + +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpDoInitialization(PVBOXNETFLTINS pNetFlt, NDIS_HANDLE hMiniportAdapter, NDIS_HANDLE hWrapperConfigurationContext) +{ + NDIS_STATUS Status; + pNetFlt->u.s.WinIf.hMiniport = hMiniportAdapter; + + LogFlow(("==>"__FUNCTION__" : pNetFlt 0x%p\n", pNetFlt)); + + Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized); + vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Initializing); + + vboxNetFltWinMpReadApplyConfig(pNetFlt, hMiniportAdapter, hWrapperConfigurationContext); + + NdisMSetAttributesEx(hMiniportAdapter, pNetFlt, + 0, /* CheckForHangTimeInSeconds */ + NDIS_ATTRIBUTE_DESERIALIZE | + NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND, + NdisInterfaceInternal/* 0 */); + + Assert(vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.MpState) == NdisDeviceStateD3); + vboxNetFltWinSetPowerState(&pNetFlt->u.s.WinIf.MpState, NdisDeviceStateD0); + Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Initializing); + vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Initialized); + + Status = NDIS_STATUS_SUCCESS; + + LogFlow(("<=="__FUNCTION__" : pNetFlt 0x%p, Status 0x%x\n", pNetFlt, Status)); + + return Status; +} + +static NDIS_STATUS vboxNetFltWinMpInitialize(OUT PNDIS_STATUS OpenErrorStatus, + OUT PUINT SelectedMediumIndex, + IN PNDIS_MEDIUM MediumArray, + IN UINT MediumArraySize, + IN NDIS_HANDLE MiniportAdapterHandle, + IN NDIS_HANDLE WrapperConfigurationContext) +{ + + NDIS_STATUS Status = NDIS_STATUS_FAILURE; + UINT i = 0; + + LogFlow(("==>"__FUNCTION__"\n")); + + for (; i < MediumArraySize; i++) + { + if (MediumArray[i] == NdisMedium802_3) + { + *SelectedMediumIndex = i; + break; + } + } + + if (i != MediumArraySize) + { + PDEVICE_OBJECT pPdo, pFdo; +#define KEY_PREFIX L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\" + UCHAR Buf[512]; + PUCHAR pSuffix; + ULONG cbBuf; + NDIS_STRING RtlStr; + + wcscpy((WCHAR*)Buf, KEY_PREFIX); + pSuffix = Buf + (sizeof(KEY_PREFIX)-2); + + NdisMGetDeviceProperty(MiniportAdapterHandle, + &pPdo, + &pFdo, + NULL, //Next Device Object + NULL, + NULL); + + Status = IoGetDeviceProperty (pPdo, + DevicePropertyDriverKeyName, + sizeof(Buf) - (sizeof(KEY_PREFIX)-2), + pSuffix, + &cbBuf); + if (Status == STATUS_SUCCESS) + { + OBJECT_ATTRIBUTES ObjAttr; + HANDLE hDrvKey; + RtlStr.Buffer=(WCHAR*)Buf; + RtlStr.Length=(USHORT)cbBuf - 2 + sizeof(KEY_PREFIX) - 2; + RtlStr.MaximumLength=sizeof(Buf); + + InitializeObjectAttributes(&ObjAttr, &RtlStr, OBJ_CASE_INSENSITIVE, NULL, NULL); + + Status = ZwOpenKey(&hDrvKey, KEY_READ, &ObjAttr); + if (Status == STATUS_SUCCESS) + { + static UNICODE_STRING NetCfgInstanceIdValue = NDIS_STRING_CONST("NetCfgInstanceId"); +// UCHAR valBuf[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + RTUUID_STR_LENGTH*2 + 10]; +// ULONG cLength = sizeof(valBuf); +#define NAME_PREFIX L"\\DEVICE\\" + PKEY_VALUE_PARTIAL_INFORMATION pInfo = (PKEY_VALUE_PARTIAL_INFORMATION)Buf; + Status = ZwQueryValueKey(hDrvKey, + &NetCfgInstanceIdValue, + KeyValuePartialInformation, + pInfo, + sizeof(Buf), + &cbBuf); + if (Status == STATUS_SUCCESS) + { + if (pInfo->Type == REG_SZ && pInfo->DataLength > 2) + { + WCHAR *pName; + Status = vboxNetFltWinMemAlloc((PVOID*)&pName, pInfo->DataLength + sizeof(NAME_PREFIX)); + if (Status == STATUS_SUCCESS) + { + PVBOXNETFLTINS pNetFlt; + wcscpy(pName, NAME_PREFIX); + wcscpy(pName+(sizeof(NAME_PREFIX)-2)/2, (WCHAR*)pInfo->Data); + RtlStr.Buffer=pName; + RtlStr.Length = (USHORT)pInfo->DataLength - 2 + sizeof(NAME_PREFIX) - 2; + RtlStr.MaximumLength = (USHORT)pInfo->DataLength + sizeof(NAME_PREFIX); + + Status = vboxNetFltWinPtInitBind(&pNetFlt, MiniportAdapterHandle, &RtlStr, WrapperConfigurationContext); + + if (Status == STATUS_SUCCESS) + { + Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Initialized); + vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Initialized); +#if 0 + NdisMIndicateStatus(pNetFlt->u.s.WinIf.hMiniport, + NDIS_STATUS_MEDIA_CONNECT, + (PVOID)NULL, + 0); +#endif + } + else + { + Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized); + vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized); + } + + vboxNetFltWinMemFree(pName); + + } + } + else + { + Status = NDIS_STATUS_FAILURE; + } + } + } + } + } + else + { + Status = NDIS_STATUS_UNSUPPORTED_MEDIA; + } + + /* TODO: */ + *OpenErrorStatus = Status; + + LogFlow(("<=="__FUNCTION__": Status (0x%x)\n", Status)); + + return Status; +} +#endif + +static VOID vboxNetFltWinMpSendPackets(IN NDIS_HANDLE hMiniportAdapterContext, + IN PPNDIS_PACKET pPacketArray, + IN UINT cNumberOfPackets) +{ + PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hMiniportAdapterContext; + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + bool bNetFltActive; + + LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p)\n", pNetFlt)); + + Assert(cNumberOfPackets); + + if (vboxNetFltWinIncReferenceWinIfNetFlt(pNetFlt, cNumberOfPackets, &bNetFltActive)) + { + uint32_t cAdaptRefs = cNumberOfPackets; + uint32_t cNetFltRefs; + uint32_t cPassThruRefs; + if (bNetFltActive) + { + cNetFltRefs = cNumberOfPackets; + cPassThruRefs = 0; + } + else + { + cPassThruRefs = cNumberOfPackets; + cNetFltRefs = 0; + } + + for (UINT i = 0; i < cNumberOfPackets; i++) + { + PNDIS_PACKET pPacket; + + pPacket = pPacketArray[i]; + + if (!cNetFltRefs +#ifdef VBOXNETFLT_NO_PACKET_QUEUE + || !vboxNetFltWinPostIntnet(pNetFlt, pPacket, VBOXNETFLT_PACKET_SRC_HOST) +#else + || (fStatus = vboxNetFltWinQuEnqueuePacket(pNetFlt, pPacket, VBOXNETFLT_PACKET_SRC_HOST)) != NDIS_STATUS_SUCCESS +#endif + ) + { +#ifndef VBOXNETADP + Status = vboxNetFltWinSendPassThru(pNetFlt, pPacket +#ifdef VBOXNETFLT_NO_PACKET_QUEUE + , !!cNetFltRefs +#endif + ); +#else + if (!cNetFltRefs) + { +# ifdef VBOXNETADP_REPORT_DISCONNECTED + Status = NDIS_STATUS_MEDIA_DISCONNECT; + STATISTIC_INCREASE(pNetFlt->u.s.WinIf.cTxError); +# else + Status = NDIS_STATUS_SUCCESS; +# endif + } +#endif + + if (Status != NDIS_STATUS_PENDING) + { + NdisMSendComplete(pNetFlt->u.s.WinIf.hMiniport, pPacket, Status); + } + else + { + cAdaptRefs--; + } + } + else + { +#ifdef VBOXNETFLT_NO_PACKET_QUEUE + NdisMSendComplete(pNetFlt->u.s.WinIf.hMiniport, pPacket, NDIS_STATUS_SUCCESS); +#else + cAdaptRefs--; + cNetFltRefs--; +#endif + } + } + + if (cNetFltRefs) + { + vboxNetFltWinDecReferenceNetFlt(pNetFlt, cNetFltRefs); + } + else if (cPassThruRefs) + { + vboxNetFltWinDecReferenceModePassThru(pNetFlt, cPassThruRefs); + } + if (cAdaptRefs) + { + vboxNetFltWinDecReferenceWinIf(pNetFlt, cAdaptRefs); + } + } + else + { + NDIS_HANDLE h = pNetFlt->u.s.WinIf.hMiniport; + Assert(0); + if (h) + { + for (UINT i = 0; i < cNumberOfPackets; i++) + { + PNDIS_PACKET pPacket; + pPacket = pPacketArray[i]; + NdisMSendComplete(h, pPacket, NDIS_STATUS_FAILURE); + } + } + } + + LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p)\n", pNetFlt)); +} + +#ifndef VBOXNETADP +static UINT vboxNetFltWinMpRequestStatePrep(PVBOXNETFLTINS pNetFlt, NDIS_STATUS *pStatus) +{ + RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; + + Assert(!pNetFlt->u.s.WinIf.StateFlags.fRequestInfo); + + if (vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.PtState) > kVBoxNetDevOpState_Initialized /* protocol unbind in progress */ + || vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.MpState) > NdisDeviceStateD0) + { + *pStatus = NDIS_STATUS_FAILURE; + return 0; + } + + RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp); + Assert(!pNetFlt->u.s.WinIf.StateFlags.fRequestInfo); + if (vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.PtState) > kVBoxNetDevOpState_Initialized /* protocol unbind in progress */ + || vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.MpState) > NdisDeviceStateD0) + { + RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); + *pStatus = NDIS_STATUS_FAILURE; + return 0; + } + + if ((vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.PtState) > NdisDeviceStateD0) + && !pNetFlt->u.s.WinIf.StateFlags.fStandBy) + { + pNetFlt->u.s.WinIf.StateFlags.fRequestInfo = VBOXNDISREQUEST_INPROGRESS | VBOXNDISREQUEST_QUEUED; + RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); + *pStatus = NDIS_STATUS_PENDING; + return VBOXNDISREQUEST_INPROGRESS | VBOXNDISREQUEST_QUEUED; + } + + if (pNetFlt->u.s.WinIf.StateFlags.fStandBy) + { + RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); + *pStatus = NDIS_STATUS_FAILURE; + return 0; + } + + pNetFlt->u.s.WinIf.StateFlags.fRequestInfo = VBOXNDISREQUEST_INPROGRESS; + + RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); + + *pStatus = NDIS_STATUS_SUCCESS; + return VBOXNDISREQUEST_INPROGRESS; +} + +static NDIS_STATUS vboxNetFltWinMpRequestPostQuery(PVBOXNETFLTINS pNetFlt) +{ + if (pNetFlt->u.s.WinIf.PassDownRequest.DATA.QUERY_INFORMATION.Oid == OID_GEN_CURRENT_PACKET_FILTER && VBOXNETFLT_PROMISCUOUS_SUPPORTED(pNetFlt)) + { + bool fNetFltActive; + const bool fWinIfActive = vboxNetFltWinReferenceWinIfNetFlt(pNetFlt, &fNetFltActive); + + Assert(pNetFlt->u.s.WinIf.PassDownRequest.DATA.QUERY_INFORMATION.InformationBuffer); + Assert(!pNetFlt->u.s.WinIf.StateFlags.fProcessingPacketFilter); + + if (fNetFltActive) + { + /* netflt is active, simply return the cached value */ + *((PULONG)pNetFlt->u.s.WinIf.PassDownRequest.DATA.QUERY_INFORMATION.InformationBuffer) = pNetFlt->u.s.WinIf.fUpperProtocolSetFilter; + + /* we've intercepted the query and completed it */ + vboxNetFltWinMpRequestStateComplete(pNetFlt); + + vboxNetFltWinDereferenceNetFlt(pNetFlt); + vboxNetFltWinDereferenceWinIf(pNetFlt); + + return NDIS_STATUS_SUCCESS; + } + else if (fWinIfActive) + { + pNetFlt->u.s.WinIf.StateFlags.fProcessingPacketFilter = 1; + pNetFlt->u.s.WinIf.StateFlags.fPPFNetFlt = 0; + /* we're cleaning it in RequestComplete */ + } + } + + NDIS_STATUS Status; + /* issue the request */ + NdisRequest(&Status, pNetFlt->u.s.WinIf.hBinding, &pNetFlt->u.s.WinIf.PassDownRequest); + if (Status != NDIS_STATUS_PENDING) + { + vboxNetFltWinPtRequestComplete(pNetFlt, &pNetFlt->u.s.WinIf.PassDownRequest, Status); + Status = NDIS_STATUS_PENDING; + } + + return Status; +} + +static NDIS_STATUS vboxNetFltWinMpQueryInformation(IN NDIS_HANDLE MiniportAdapterContext, + IN NDIS_OID Oid, + IN PVOID InformationBuffer, + IN ULONG InformationBufferLength, + OUT PULONG BytesWritten, + OUT PULONG BytesNeeded) +{ + PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)MiniportAdapterContext; + NDIS_STATUS Status = NDIS_STATUS_FAILURE; + + LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p), Oid (%s)\n", pNetFlt, vboxNetFltWinMpDumpOid(Oid))); + + /* fist check if this is the oid we want to pass down */ + switch (Oid) + { + case OID_PNP_QUERY_POWER: + Status = NDIS_STATUS_SUCCESS; + break; + case OID_TCP_TASK_OFFLOAD: + case OID_GEN_SUPPORTED_GUIDS: + Status = NDIS_STATUS_NOT_SUPPORTED; + break; + default: + { + /* the oid is to be passed down, + * check the device state if we can do it + * and update device state accordingly */ + UINT uOp = vboxNetFltWinMpRequestStatePrep(pNetFlt, &Status); + if (uOp) + { + /* save the request info */ + pNetFlt->u.s.WinIf.PassDownRequest.RequestType = NdisRequestQueryInformation; + pNetFlt->u.s.WinIf.PassDownRequest.DATA.QUERY_INFORMATION.Oid = Oid; + pNetFlt->u.s.WinIf.PassDownRequest.DATA.QUERY_INFORMATION.InformationBuffer = InformationBuffer; + pNetFlt->u.s.WinIf.PassDownRequest.DATA.QUERY_INFORMATION.InformationBufferLength = InformationBufferLength; + pNetFlt->u.s.WinIf.pcPDRBytesNeeded = BytesNeeded; + pNetFlt->u.s.WinIf.pcPDRBytesRW = BytesWritten; + + /* the oid can be processed */ + if (!(uOp & VBOXNDISREQUEST_QUEUED)) + { + Status = vboxNetFltWinMpRequestPostQuery(pNetFlt); + } + } + break; + } + } + + LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), Oid (%s), Status (0x%x)\n", pNetFlt, vboxNetFltWinMpDumpOid(Oid), Status)); + + return Status; +} + +#endif /* ifndef VBOXNETADP*/ + +static NDIS_STATUS vboxNetFltWinMpHandlePowerState(PVBOXNETFLTINS pNetFlt, NDIS_DEVICE_POWER_STATE enmState) +{ + if (vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.MpState) > NdisDeviceStateD0 + && enmState != NdisDeviceStateD0) + { + /* invalid state transformation */ + Assert(0); + return NDIS_STATUS_FAILURE; + } + +#ifndef VBOXNETADP + if (vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.MpState) == NdisDeviceStateD0 + && enmState > NdisDeviceStateD0) + { + pNetFlt->u.s.WinIf.StateFlags.fStandBy = TRUE; + } + + if (vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.MpState) > NdisDeviceStateD0 + && enmState == NdisDeviceStateD0) + { + pNetFlt->u.s.WinIf.StateFlags.fStandBy = FALSE; + } +#endif + + vboxNetFltWinSetPowerState(&pNetFlt->u.s.WinIf.MpState, enmState); + +#ifndef VBOXNETADP + if (pNetFlt->u.s.WinIf.StateFlags.fStandBy == FALSE) + { + if (pNetFlt->u.s.WinIf.MpIndicatedMediaStatus != pNetFlt->u.s.WinIf.MpUnindicatedMediaStatus) + { + NdisMIndicateStatus(pNetFlt->u.s.WinIf.hMiniport, pNetFlt->u.s.WinIf.MpUnindicatedMediaStatus, NULL, 0); + NdisMIndicateStatusComplete(pNetFlt->u.s.WinIf.hMiniport); + pNetFlt->u.s.WinIf.MpIndicatedMediaStatus = pNetFlt->u.s.WinIf.MpUnindicatedMediaStatus; + } + } + else + { + pNetFlt->u.s.WinIf.MpUnindicatedMediaStatus = pNetFlt->u.s.WinIf.MpIndicatedMediaStatus; + } +#endif + + return NDIS_STATUS_SUCCESS; +} + +#ifndef VBOXNETADP +static NDIS_STATUS vboxNetFltWinMpRequestPostSet(PVBOXNETFLTINS pNetFlt) +{ + if (pNetFlt->u.s.WinIf.PassDownRequest.DATA.SET_INFORMATION.Oid == OID_GEN_CURRENT_PACKET_FILTER && VBOXNETFLT_PROMISCUOUS_SUPPORTED(pNetFlt)) + { + /* need to disable cleaning promiscuous here ?? */ + bool fNetFltActive; + const bool fWinIfActive = vboxNetFltWinReferenceWinIfNetFlt(pNetFlt, &fNetFltActive); + + Assert(pNetFlt->u.s.WinIf.PassDownRequest.DATA.SET_INFORMATION.InformationBuffer); + Assert(!pNetFlt->u.s.WinIf.StateFlags.fProcessingPacketFilter); + + if (fNetFltActive) + { + Assert(fWinIfActive); + + /* netflt is active, update the cached value */ + /* TODO: in case we are are not in promiscuous now, we are issuing a request. + * what should we do in case of a failure? + * i.e. should we update the fUpperProtocolSetFilter in completion routine in this case? etc. */ + pNetFlt->u.s.WinIf.fUpperProtocolSetFilter = *((PULONG)pNetFlt->u.s.WinIf.PassDownRequest.DATA.SET_INFORMATION.InformationBuffer); + pNetFlt->u.s.WinIf.StateFlags.fUpperProtSetFilterInitialized = TRUE; + + if (!(pNetFlt->u.s.WinIf.fOurSetFilter & NDIS_PACKET_TYPE_PROMISCUOUS)) + { + pNetFlt->u.s.WinIf.fSetFilterBuffer = NDIS_PACKET_TYPE_PROMISCUOUS; + pNetFlt->u.s.WinIf.PassDownRequest.DATA.SET_INFORMATION.InformationBuffer = &pNetFlt->u.s.WinIf.fSetFilterBuffer; + pNetFlt->u.s.WinIf.PassDownRequest.DATA.SET_INFORMATION.InformationBufferLength = sizeof (pNetFlt->u.s.WinIf.fSetFilterBuffer); + pNetFlt->u.s.WinIf.StateFlags.fProcessingPacketFilter = 1; + pNetFlt->u.s.WinIf.StateFlags.fPPFNetFlt = 1; + /* we'll do dereferencing in request complete */ + } + else + { + vboxNetFltWinDereferenceNetFlt(pNetFlt); + vboxNetFltWinDereferenceWinIf(pNetFlt); + + /* we've intercepted the query and completed it */ + vboxNetFltWinMpRequestStateComplete(pNetFlt); + return NDIS_STATUS_SUCCESS; + } + } + else if (fWinIfActive) + { + pNetFlt->u.s.WinIf.StateFlags.fProcessingPacketFilter = 1; + pNetFlt->u.s.WinIf.StateFlags.fPPFNetFlt = 0; + /* dereference on completion */ + } + } + + NDIS_STATUS Status; + + NdisRequest(&Status, pNetFlt->u.s.WinIf.hBinding, &pNetFlt->u.s.WinIf.PassDownRequest); + if (Status != NDIS_STATUS_PENDING) + { + vboxNetFltWinPtRequestComplete(pNetFlt, &pNetFlt->u.s.WinIf.PassDownRequest, Status); + } + + return Status; +} + +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpRequestPost(PVBOXNETFLTINS pNetFlt) +{ + switch (pNetFlt->u.s.WinIf.PassDownRequest.RequestType) + { + case NdisRequestQueryInformation: + return vboxNetFltWinMpRequestPostQuery(pNetFlt); + case NdisRequestSetInformation: + return vboxNetFltWinMpRequestPostSet(pNetFlt); + default: + AssertBreakpoint(); + return NDIS_STATUS_FAILURE; + } +} + +static NDIS_STATUS vboxNetFltWinMpSetInformation(IN NDIS_HANDLE MiniportAdapterContext, + IN NDIS_OID Oid, + IN PVOID InformationBuffer, + IN ULONG InformationBufferLength, + OUT PULONG BytesRead, + OUT PULONG BytesNeeded) +{ + PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)MiniportAdapterContext; + RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; + NDIS_STATUS Status = NDIS_STATUS_FAILURE; + + LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p), Oid (%s)\n", pNetFlt, vboxNetFltWinMpDumpOid(Oid))); + + switch (Oid) + { + case OID_PNP_SET_POWER: + { + if (InformationBufferLength >= sizeof (NDIS_DEVICE_POWER_STATE)) + { + NDIS_DEVICE_POWER_STATE *penmState = (NDIS_DEVICE_POWER_STATE*)InformationBuffer; + Status = vboxNetFltWinMpHandlePowerState(pNetFlt, *penmState); + } + else + { + Status = NDIS_STATUS_INVALID_LENGTH; + } + + if (Status == NDIS_STATUS_SUCCESS) + { + *BytesRead = sizeof (NDIS_DEVICE_POWER_STATE); + *BytesNeeded = 0; + } + else + { + *BytesRead = 0; + *BytesNeeded = sizeof (NDIS_DEVICE_POWER_STATE); + } + break; + } + default: + { + /* the oid is to be passed down, + * check the device state if we can do it + * and update device state accordingly */ + UINT uOp = vboxNetFltWinMpRequestStatePrep(pNetFlt, &Status); + if (uOp) + { + /* save the request info */ + pNetFlt->u.s.WinIf.PassDownRequest.RequestType = NdisRequestSetInformation; + pNetFlt->u.s.WinIf.PassDownRequest.DATA.SET_INFORMATION.Oid = Oid; + pNetFlt->u.s.WinIf.PassDownRequest.DATA.SET_INFORMATION.InformationBuffer = InformationBuffer; + pNetFlt->u.s.WinIf.PassDownRequest.DATA.SET_INFORMATION.InformationBufferLength = InformationBufferLength; + pNetFlt->u.s.WinIf.pcPDRBytesNeeded = BytesNeeded; + pNetFlt->u.s.WinIf.pcPDRBytesRW = BytesRead; + + /* the oid can be processed */ + if (!(uOp & VBOXNDISREQUEST_QUEUED)) + { + Status = vboxNetFltWinMpRequestPostSet(pNetFlt); + } + } + break; + } + } + + LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), Oid (%s), Status (0x%x)\n", pNetFlt, vboxNetFltWinMpDumpOid(Oid), Status)); + + return Status; +} +#else +static NDIS_OID g_vboxNetFltWinMpSupportedOids[] = +{ + OID_GEN_SUPPORTED_LIST, + OID_GEN_HARDWARE_STATUS, + OID_GEN_MEDIA_SUPPORTED, + OID_GEN_MEDIA_IN_USE, + OID_GEN_MAXIMUM_LOOKAHEAD, + OID_GEN_CURRENT_LOOKAHEAD, + OID_GEN_MAXIMUM_FRAME_SIZE, + OID_GEN_MAXIMUM_TOTAL_SIZE, + OID_GEN_TRANSMIT_BLOCK_SIZE, + OID_GEN_RECEIVE_BLOCK_SIZE, + OID_GEN_MAC_OPTIONS, + OID_GEN_LINK_SPEED, + OID_GEN_TRANSMIT_BUFFER_SPACE, + OID_GEN_RECEIVE_BUFFER_SPACE, + OID_GEN_VENDOR_ID, + OID_GEN_VENDOR_DESCRIPTION, + OID_GEN_VENDOR_DRIVER_VERSION, + OID_GEN_DRIVER_VERSION, + OID_GEN_MAXIMUM_SEND_PACKETS, + OID_GEN_MEDIA_CONNECT_STATUS, + OID_GEN_CURRENT_PACKET_FILTER, + OID_PNP_CAPABILITIES, + OID_PNP_QUERY_POWER, + OID_GEN_XMIT_OK, + OID_GEN_RCV_OK, + OID_GEN_XMIT_ERROR, + OID_GEN_RCV_ERROR, + OID_GEN_RCV_NO_BUFFER, + OID_GEN_RCV_CRC_ERROR, + OID_GEN_TRANSMIT_QUEUE_LENGTH, + OID_PNP_SET_POWER, + OID_802_3_PERMANENT_ADDRESS, + OID_802_3_CURRENT_ADDRESS, + OID_802_3_MULTICAST_LIST, + OID_802_3_MAC_OPTIONS, + OID_802_3_MAXIMUM_LIST_SIZE, + OID_802_3_RCV_ERROR_ALIGNMENT, + OID_802_3_XMIT_ONE_COLLISION, + OID_802_3_XMIT_MORE_COLLISIONS, + OID_802_3_XMIT_DEFERRED, + OID_802_3_XMIT_MAX_COLLISIONS, + OID_802_3_RCV_OVERRUN, + OID_802_3_XMIT_UNDERRUN, + OID_802_3_XMIT_HEARTBEAT_FAILURE, + OID_802_3_XMIT_TIMES_CRS_LOST, + OID_802_3_XMIT_LATE_COLLISIONS, +}; + +static NDIS_STATUS vboxNetFltWinMpQueryInformation(IN NDIS_HANDLE MiniportAdapterContext, + IN NDIS_OID Oid, + IN PVOID InformationBuffer, + IN ULONG InformationBufferLength, + OUT PULONG BytesWritten, + OUT PULONG BytesNeeded) +{ + /* static data */ + static const NDIS_HARDWARE_STATUS enmHwStatus = NdisHardwareStatusReady; + static const NDIS_MEDIUM enmMedium = NdisMedium802_3; + static NDIS_PNP_CAPABILITIES PnPCaps = {0}; + static BOOLEAN bPnPCapsInited = FALSE; + + PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)MiniportAdapterContext; + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + ULONG64 u64Info = 0; + ULONG u32Info = 0; + USHORT u16Info = 0; + /* default is 4bytes */ + const void* pvInfo = (void*)&u32Info; + ULONG cbInfo = sizeof (u32Info); + + LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p), Oid (%s)\n", pNetFlt, vboxNetFltWinMpDumpOid(Oid))); + + *BytesWritten = 0; + *BytesNeeded = 0; + + switch (Oid) + { + case OID_GEN_SUPPORTED_LIST: + pvInfo = g_vboxNetFltWinMpSupportedOids; + cbInfo = sizeof (g_vboxNetFltWinMpSupportedOids); + break; + + case OID_GEN_HARDWARE_STATUS: + pvInfo = &enmHwStatus; + cbInfo = sizeof (NDIS_HARDWARE_STATUS); + break; + + case OID_GEN_MEDIA_SUPPORTED: + case OID_GEN_MEDIA_IN_USE: + pvInfo = &enmMedium; + cbInfo = sizeof (NDIS_MEDIUM); + break; + + case OID_GEN_MAXIMUM_LOOKAHEAD: + case OID_GEN_CURRENT_LOOKAHEAD: + u32Info = VBOXNETADP_MAX_LOOKAHEAD_SIZE; + break; + + case OID_GEN_MAXIMUM_FRAME_SIZE: + u32Info = VBOXNETADP_MAX_PACKET_SIZE - VBOXNETADP_HEADER_SIZE; + break; + + case OID_GEN_MAXIMUM_TOTAL_SIZE: + case OID_GEN_TRANSMIT_BLOCK_SIZE: + case OID_GEN_RECEIVE_BLOCK_SIZE: + u32Info = VBOXNETADP_MAX_PACKET_SIZE; + break; + + case OID_GEN_MAC_OPTIONS: + u32Info = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | + NDIS_MAC_OPTION_TRANSFERS_NOT_PEND | + NDIS_MAC_OPTION_NO_LOOPBACK; + break; + + case OID_GEN_LINK_SPEED: + u32Info = VBOXNETADP_LINK_SPEED; + break; + + case OID_GEN_TRANSMIT_BUFFER_SPACE: + case OID_GEN_RECEIVE_BUFFER_SPACE: + u32Info = VBOXNETADP_MAX_PACKET_SIZE * VBOXNETFLT_PACKET_INFO_POOL_SIZE; + break; + + case OID_GEN_VENDOR_ID: + u32Info = VBOXNETADP_VENDOR_ID; + break; + + case OID_GEN_VENDOR_DESCRIPTION: + pvInfo = VBOXNETADP_VENDOR_DESC; + cbInfo = sizeof (VBOXNETADP_VENDOR_DESC); + break; + + case OID_GEN_VENDOR_DRIVER_VERSION: + u32Info = VBOXNETADP_VENDOR_DRIVER_VERSION; + break; + + case OID_GEN_DRIVER_VERSION: + u16Info = (USHORT)((VBOXNETFLT_VERSION_MP_NDIS_MAJOR << 8) + VBOXNETFLT_VERSION_MP_NDIS_MINOR); + pvInfo = (PVOID)&u16Info; + cbInfo = sizeof (USHORT); + break; + + case OID_GEN_MAXIMUM_SEND_PACKETS: + u32Info = VBOXNETFLT_PACKET_INFO_POOL_SIZE; + break; + + case OID_GEN_MEDIA_CONNECT_STATUS: +#ifdef VBOXNETADP_REPORT_DISCONNECTED + { + bool bNetFltActive; + bool bActive = vboxNetFltWinReferenceWinIfNetFltFromAdapt(pNetFlt, bNetFltActive); + if (bActive && bNetFltActive) + { + u32Info = NdisMediaStateConnected; + } + else + { + u32Info = NdisMediaStateDisconnected; + } + + if (bActive) + { + vboxNetFltWinDereferenceWinIf(pNetFlt); + } + if (bNetFltActive) + { + vboxNetFltWinDereferenceNetFlt(pNetFlt); + } + else + { + vboxNetFltWinDereferenceModePassThru(pNetFlt); + } + } +#else + u32Info = NdisMediaStateConnected; +#endif + break; + + case OID_GEN_CURRENT_PACKET_FILTER: + u32Info = NDIS_PACKET_TYPE_BROADCAST + | NDIS_PACKET_TYPE_DIRECTED + | NDIS_PACKET_TYPE_ALL_FUNCTIONAL + | NDIS_PACKET_TYPE_ALL_LOCAL + | NDIS_PACKET_TYPE_GROUP + | NDIS_PACKET_TYPE_MULTICAST; + break; + + case OID_PNP_CAPABILITIES: + if (!bPnPCapsInited) + { + PnPCaps.WakeUpCapabilities.MinMagicPacketWakeUp = NdisDeviceStateUnspecified; + PnPCaps.WakeUpCapabilities.MinPatternWakeUp = NdisDeviceStateUnspecified; + bPnPCapsInited = TRUE; + } + cbInfo = sizeof (NDIS_PNP_CAPABILITIES); + pvInfo = &PnPCaps; + + break; + + case OID_PNP_QUERY_POWER: + Status = NDIS_STATUS_SUCCESS; + break; + + case OID_GEN_XMIT_OK: + u64Info = pNetFlt->u.s.WinIf.cTxSuccess; + pvInfo = &u64Info; + if (InformationBufferLength >= sizeof (ULONG64) || InformationBufferLength == 0) + { + cbInfo = sizeof (ULONG64); + } + else + { + cbInfo = sizeof (ULONG); + } + *BytesNeeded = sizeof (ULONG64); + break; + + case OID_GEN_RCV_OK: + u64Info = pNetFlt->u.s.WinIf.cRxSuccess; + pvInfo = &u64Info; + if (InformationBufferLength >= sizeof (ULONG64) || InformationBufferLength == 0) + { + cbInfo = sizeof (ULONG64); + } + else + { + cbInfo = sizeof (ULONG); + } + *BytesNeeded = sizeof (ULONG64); + break; + + case OID_GEN_XMIT_ERROR: + u32Info = pNetFlt->u.s.WinIf.cTxError; + break; + + case OID_GEN_RCV_ERROR: + u32Info = pNetFlt->u.s.WinIf.cRxError; + break; + + case OID_GEN_RCV_NO_BUFFER: + case OID_GEN_RCV_CRC_ERROR: + u32Info = 0; + break; + + case OID_GEN_TRANSMIT_QUEUE_LENGTH: + u32Info = VBOXNETFLT_PACKET_INFO_POOL_SIZE; + break; + + case OID_802_3_PERMANENT_ADDRESS: + pvInfo = &pNetFlt->u.s.MacAddr; + cbInfo = VBOXNETADP_ETH_ADDRESS_LENGTH; + break; + + case OID_802_3_CURRENT_ADDRESS: + pvInfo = &pNetFlt->u.s.MacAddr; + cbInfo = VBOXNETADP_ETH_ADDRESS_LENGTH; + break; + + case OID_802_3_MAXIMUM_LIST_SIZE: + u32Info = VBOXNETADP_MAX_MCAST_LIST; + break; + + case OID_802_3_MAC_OPTIONS: + case OID_802_3_RCV_ERROR_ALIGNMENT: + case OID_802_3_XMIT_ONE_COLLISION: + case OID_802_3_XMIT_MORE_COLLISIONS: + case OID_802_3_XMIT_DEFERRED: + case OID_802_3_XMIT_MAX_COLLISIONS: + case OID_802_3_RCV_OVERRUN: + case OID_802_3_XMIT_UNDERRUN: + case OID_802_3_XMIT_HEARTBEAT_FAILURE: + case OID_802_3_XMIT_TIMES_CRS_LOST: + case OID_802_3_XMIT_LATE_COLLISIONS: + u32Info = 0; + break; + + default: + Status = NDIS_STATUS_NOT_SUPPORTED; + break; + } + + if (Status == NDIS_STATUS_SUCCESS) + { + if (cbInfo <= InformationBufferLength) + { + *BytesWritten = cbInfo; + if (cbInfo) + NdisMoveMemory(InformationBuffer, pvInfo, cbInfo); + } + else + { + *BytesNeeded = cbInfo; + Status = NDIS_STATUS_INVALID_LENGTH; + } + } + + + LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), Oid (%s), Status (0x%x)\n", pNetFlt, vboxNetFltWinMpDumpOid(Oid), Status)); + + return Status; +} + +static NDIS_STATUS vboxNetFltWinMpSetInformation(IN NDIS_HANDLE MiniportAdapterContext, + IN NDIS_OID Oid, + IN PVOID InformationBuffer, + IN ULONG InformationBufferLength, + OUT PULONG BytesRead, + OUT PULONG BytesNeeded) +{ + PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS) MiniportAdapterContext; + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + + LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p), Oid (%s)\n", pNetFlt, vboxNetFltWinMpDumpOid(Oid))); + + *BytesRead = 0; + *BytesNeeded = 0; + + switch (Oid) + { + case OID_802_3_MULTICAST_LIST: + *BytesRead = InformationBufferLength; + if (InformationBufferLength % VBOXNETADP_ETH_ADDRESS_LENGTH) + { + Status = NDIS_STATUS_INVALID_LENGTH; + break; + } + + if (InformationBufferLength > (VBOXNETADP_MAX_MCAST_LIST * VBOXNETADP_ETH_ADDRESS_LENGTH)) + { + Status = NDIS_STATUS_MULTICAST_FULL; + *BytesNeeded = VBOXNETADP_MAX_MCAST_LIST * VBOXNETADP_ETH_ADDRESS_LENGTH; + break; + } + break; + + case OID_GEN_CURRENT_PACKET_FILTER: + if (InformationBufferLength != sizeof (ULONG)) + { + *BytesNeeded = sizeof (ULONG); + Status = NDIS_STATUS_INVALID_LENGTH; + break; + } + + *BytesRead = InformationBufferLength; + + break; + + case OID_GEN_CURRENT_LOOKAHEAD: + if (InformationBufferLength != sizeof (ULONG)){ + *BytesNeeded = sizeof(ULONG); + Status = NDIS_STATUS_INVALID_LENGTH; + break; + } + + break; + + case OID_PNP_SET_POWER: + if (InformationBufferLength >= sizeof(NDIS_DEVICE_POWER_STATE)) + { + NDIS_DEVICE_POWER_STATE *penmState = (NDIS_DEVICE_POWER_STATE*)InformationBuffer; + Status = vboxNetFltWinMpHandlePowerState(pNetFlt, *penmState); + } + else + { + Status = NDIS_STATUS_INVALID_LENGTH; + } + + if (Status == NDIS_STATUS_SUCCESS) + { + *BytesRead = sizeof (NDIS_DEVICE_POWER_STATE); + *BytesNeeded = 0; + } + else + { + *BytesRead = 0; + *BytesNeeded = sizeof (NDIS_DEVICE_POWER_STATE); + } + break; + + default: + Status = NDIS_STATUS_INVALID_OID; + break; + } + + LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), Oid (%s), Status (0x%x)\n", pNetFlt, vboxNetFltWinMpDumpOid(Oid), Status)); + + return Status; +} + +#endif + +#define VBOXNETFLTDUMP_STRCASE(_t) \ + case _t: return #_t; +#define VBOXNETFLTDUMP_STRCASE_UNKNOWN() \ + default: /*Assert(0);*/ return "Unknown"; + +static const char* vboxNetFltWinMpDumpOid(ULONG oid) +{ + switch (oid) + { + VBOXNETFLTDUMP_STRCASE(OID_GEN_SUPPORTED_LIST) + VBOXNETFLTDUMP_STRCASE(OID_GEN_HARDWARE_STATUS) + VBOXNETFLTDUMP_STRCASE(OID_GEN_MEDIA_SUPPORTED) + VBOXNETFLTDUMP_STRCASE(OID_GEN_MEDIA_IN_USE) + VBOXNETFLTDUMP_STRCASE(OID_GEN_MAXIMUM_LOOKAHEAD) + VBOXNETFLTDUMP_STRCASE(OID_GEN_MAXIMUM_FRAME_SIZE) + VBOXNETFLTDUMP_STRCASE(OID_GEN_LINK_SPEED) + VBOXNETFLTDUMP_STRCASE(OID_GEN_TRANSMIT_BUFFER_SPACE) + VBOXNETFLTDUMP_STRCASE(OID_GEN_RECEIVE_BUFFER_SPACE) + VBOXNETFLTDUMP_STRCASE(OID_GEN_TRANSMIT_BLOCK_SIZE) + VBOXNETFLTDUMP_STRCASE(OID_GEN_RECEIVE_BLOCK_SIZE) + VBOXNETFLTDUMP_STRCASE(OID_GEN_VENDOR_ID) + VBOXNETFLTDUMP_STRCASE(OID_GEN_VENDOR_DESCRIPTION) + VBOXNETFLTDUMP_STRCASE(OID_GEN_CURRENT_PACKET_FILTER) + VBOXNETFLTDUMP_STRCASE(OID_GEN_CURRENT_LOOKAHEAD) + VBOXNETFLTDUMP_STRCASE(OID_GEN_DRIVER_VERSION) + VBOXNETFLTDUMP_STRCASE(OID_GEN_MAXIMUM_TOTAL_SIZE) + VBOXNETFLTDUMP_STRCASE(OID_GEN_PROTOCOL_OPTIONS) + VBOXNETFLTDUMP_STRCASE(OID_GEN_MAC_OPTIONS) + VBOXNETFLTDUMP_STRCASE(OID_GEN_MEDIA_CONNECT_STATUS) + VBOXNETFLTDUMP_STRCASE(OID_GEN_MAXIMUM_SEND_PACKETS) + VBOXNETFLTDUMP_STRCASE(OID_GEN_VENDOR_DRIVER_VERSION) + VBOXNETFLTDUMP_STRCASE(OID_GEN_SUPPORTED_GUIDS) + VBOXNETFLTDUMP_STRCASE(OID_GEN_NETWORK_LAYER_ADDRESSES) + VBOXNETFLTDUMP_STRCASE(OID_GEN_TRANSPORT_HEADER_OFFSET) + VBOXNETFLTDUMP_STRCASE(OID_GEN_MACHINE_NAME) + VBOXNETFLTDUMP_STRCASE(OID_GEN_RNDIS_CONFIG_PARAMETER) + VBOXNETFLTDUMP_STRCASE(OID_GEN_VLAN_ID) + VBOXNETFLTDUMP_STRCASE(OID_GEN_MEDIA_CAPABILITIES) + VBOXNETFLTDUMP_STRCASE(OID_GEN_PHYSICAL_MEDIUM) + VBOXNETFLTDUMP_STRCASE(OID_GEN_XMIT_OK) + VBOXNETFLTDUMP_STRCASE(OID_GEN_RCV_OK) + VBOXNETFLTDUMP_STRCASE(OID_GEN_XMIT_ERROR) + VBOXNETFLTDUMP_STRCASE(OID_GEN_RCV_ERROR) + VBOXNETFLTDUMP_STRCASE(OID_GEN_RCV_NO_BUFFER) + VBOXNETFLTDUMP_STRCASE(OID_GEN_DIRECTED_BYTES_XMIT) + VBOXNETFLTDUMP_STRCASE(OID_GEN_DIRECTED_FRAMES_XMIT) + VBOXNETFLTDUMP_STRCASE(OID_GEN_MULTICAST_BYTES_XMIT) + VBOXNETFLTDUMP_STRCASE(OID_GEN_MULTICAST_FRAMES_XMIT) + VBOXNETFLTDUMP_STRCASE(OID_GEN_BROADCAST_BYTES_XMIT) + VBOXNETFLTDUMP_STRCASE(OID_GEN_BROADCAST_FRAMES_XMIT) + VBOXNETFLTDUMP_STRCASE(OID_GEN_DIRECTED_BYTES_RCV) + VBOXNETFLTDUMP_STRCASE(OID_GEN_DIRECTED_FRAMES_RCV) + VBOXNETFLTDUMP_STRCASE(OID_GEN_MULTICAST_BYTES_RCV) + VBOXNETFLTDUMP_STRCASE(OID_GEN_MULTICAST_FRAMES_RCV) + VBOXNETFLTDUMP_STRCASE(OID_GEN_BROADCAST_BYTES_RCV) + VBOXNETFLTDUMP_STRCASE(OID_GEN_BROADCAST_FRAMES_RCV) + VBOXNETFLTDUMP_STRCASE(OID_GEN_RCV_CRC_ERROR) + VBOXNETFLTDUMP_STRCASE(OID_GEN_TRANSMIT_QUEUE_LENGTH) + VBOXNETFLTDUMP_STRCASE(OID_GEN_GET_TIME_CAPS) + VBOXNETFLTDUMP_STRCASE(OID_GEN_GET_NETCARD_TIME) + VBOXNETFLTDUMP_STRCASE(OID_GEN_NETCARD_LOAD) + VBOXNETFLTDUMP_STRCASE(OID_GEN_DEVICE_PROFILE) + VBOXNETFLTDUMP_STRCASE(OID_GEN_INIT_TIME_MS) + VBOXNETFLTDUMP_STRCASE(OID_GEN_RESET_COUNTS) + VBOXNETFLTDUMP_STRCASE(OID_GEN_MEDIA_SENSE_COUNTS) + VBOXNETFLTDUMP_STRCASE(OID_PNP_CAPABILITIES) + VBOXNETFLTDUMP_STRCASE(OID_PNP_SET_POWER) + VBOXNETFLTDUMP_STRCASE(OID_PNP_QUERY_POWER) + VBOXNETFLTDUMP_STRCASE(OID_PNP_ADD_WAKE_UP_PATTERN) + VBOXNETFLTDUMP_STRCASE(OID_PNP_REMOVE_WAKE_UP_PATTERN) + VBOXNETFLTDUMP_STRCASE(OID_PNP_ENABLE_WAKE_UP) + VBOXNETFLTDUMP_STRCASE(OID_802_3_PERMANENT_ADDRESS) + VBOXNETFLTDUMP_STRCASE(OID_802_3_CURRENT_ADDRESS) + VBOXNETFLTDUMP_STRCASE(OID_802_3_MULTICAST_LIST) + VBOXNETFLTDUMP_STRCASE(OID_802_3_MAXIMUM_LIST_SIZE) + VBOXNETFLTDUMP_STRCASE(OID_802_3_MAC_OPTIONS) + VBOXNETFLTDUMP_STRCASE(OID_802_3_RCV_ERROR_ALIGNMENT) + VBOXNETFLTDUMP_STRCASE(OID_802_3_XMIT_ONE_COLLISION) + VBOXNETFLTDUMP_STRCASE(OID_802_3_XMIT_MORE_COLLISIONS) + VBOXNETFLTDUMP_STRCASE(OID_802_3_XMIT_DEFERRED) + VBOXNETFLTDUMP_STRCASE(OID_802_3_XMIT_MAX_COLLISIONS) + VBOXNETFLTDUMP_STRCASE(OID_802_3_RCV_OVERRUN) + VBOXNETFLTDUMP_STRCASE(OID_802_3_XMIT_UNDERRUN) + VBOXNETFLTDUMP_STRCASE(OID_802_3_XMIT_HEARTBEAT_FAILURE) + VBOXNETFLTDUMP_STRCASE(OID_802_3_XMIT_TIMES_CRS_LOST) + VBOXNETFLTDUMP_STRCASE(OID_802_3_XMIT_LATE_COLLISIONS) + VBOXNETFLTDUMP_STRCASE(OID_TCP_TASK_OFFLOAD) + VBOXNETFLTDUMP_STRCASE(OID_TCP_TASK_IPSEC_ADD_SA) + VBOXNETFLTDUMP_STRCASE(OID_TCP_TASK_IPSEC_DELETE_SA) + VBOXNETFLTDUMP_STRCASE(OID_TCP_SAN_SUPPORT) + VBOXNETFLTDUMP_STRCASE(OID_TCP_TASK_IPSEC_ADD_UDPESP_SA) + VBOXNETFLTDUMP_STRCASE(OID_TCP_TASK_IPSEC_DELETE_UDPESP_SA) + VBOXNETFLTDUMP_STRCASE_UNKNOWN() + } +} + +DECLHIDDEN(VOID) vboxNetFltWinMpReturnPacket(IN NDIS_HANDLE hMiniportAdapterContext, IN PNDIS_PACKET pPacket) +{ + PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hMiniportAdapterContext; + PVBOXNETFLT_PKTRSVD_MP pInfo = (PVBOXNETFLT_PKTRSVD_MP)pPacket->MiniportReserved; + PNDIS_PACKET pOrigPacket = pInfo->pOrigPacket; + PVOID pBufToFree = pInfo->pBufToFree; + + LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p)\n", pNetFlt)); + + if (pOrigPacket) + { + /* the packet was sent from underlying miniport */ + NdisFreePacket(pPacket); + NdisReturnPackets(&pOrigPacket, 1); + } + else + { + /* the packet was sent from IntNet or it is a packet we allocated on PtReceive for TransferData processing */ + vboxNetFltWinFreeSGNdisPacket(pPacket, !pBufToFree /* bFreeMem */); + } + + if (pBufToFree) + { + vboxNetFltWinMemFree(pBufToFree); + } + + vboxNetFltWinDereferenceWinIf(pNetFlt); + + LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p)\n", pNetFlt)); +} + +static NDIS_STATUS vboxNetFltWinMpTransferData(OUT PNDIS_PACKET Packet, + OUT PUINT BytesTransferred, + IN NDIS_HANDLE hContext, + IN NDIS_HANDLE MiniportReceiveContext, + IN UINT ByteOffset, + IN UINT BytesToTransfer) +{ +#ifndef VBOXNETADP + PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hContext; + NDIS_STATUS Status; + + LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p)\n", pNetFlt)); + + if (vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.PtState) != NdisDeviceStateD0 + || vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.MpState) != NdisDeviceStateD0) + { + LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), Status (0x%x)\n", pNetFlt, NDIS_STATUS_FAILURE)); + return NDIS_STATUS_FAILURE; + } + + NdisTransferData(&Status, pNetFlt->u.s.WinIf.hBinding, MiniportReceiveContext, + ByteOffset, BytesToTransfer, Packet, BytesTransferred); + + LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), Status (0x%x)\n", pNetFlt, Status)); + return Status; +#else + LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p)\n", hContext)); + /* should never be here */ + Assert(0); + LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), Status (0x%x)\n", hContext, NDIS_STATUS_FAILURE)); + return NDIS_STATUS_FAILURE; +#endif +} + +static void vboxNetFltWinMpHalt(IN NDIS_HANDLE hContext) +{ + PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hContext; + NDIS_STATUS Status; + + LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p)\n", pNetFlt)); + +#ifndef VBOXNETADP + if (vboxNetFltWinGetWinIfState(pNetFlt) == kVBoxWinIfState_Disconnecting) + { + Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitializing); + vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitializing); + + vboxNetFltWinPtCloseInterface(pNetFlt, &Status); + + Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.PtState) == kVBoxNetDevOpState_Deinitializing); + vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.PtState, kVBoxNetDevOpState_Deinitialized); + vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized); + } + else +#endif + { + /* we're NOT called from protocolUnbinAdapter, perform a full disconnect */ + Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Initialized); +#ifndef VBOXNETADP + AssertBreakpoint(); +#endif + Status = vboxNetFltWinDetachFromInterface(pNetFlt, false); + Assert(Status == NDIS_STATUS_SUCCESS); + } + + LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p)\n", pNetFlt)); +} + +/** + * register the miniport edge + */ +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpRegister(PVBOXNETFLTGLOBALS_MP pGlobalsMp, PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPathStr) +{ + NDIS_MINIPORT_CHARACTERISTICS MpChars; + + NdisMInitializeWrapper(&pGlobalsMp->hNdisWrapper, pDriverObject, pRegistryPathStr, NULL); + + NdisZeroMemory(&MpChars, sizeof (MpChars)); + + MpChars.MajorNdisVersion = VBOXNETFLT_VERSION_MP_NDIS_MAJOR; + MpChars.MinorNdisVersion = VBOXNETFLT_VERSION_MP_NDIS_MINOR; + + MpChars.HaltHandler = vboxNetFltWinMpHalt; + MpChars.InitializeHandler = vboxNetFltWinMpInitialize; + MpChars.QueryInformationHandler = vboxNetFltWinMpQueryInformation; + MpChars.SetInformationHandler = vboxNetFltWinMpSetInformation; + MpChars.TransferDataHandler = vboxNetFltWinMpTransferData; + MpChars.ReturnPacketHandler = vboxNetFltWinMpReturnPacket; + MpChars.SendPacketsHandler = vboxNetFltWinMpSendPackets; + +#ifndef VBOXNETADP + NDIS_STATUS Status = NdisIMRegisterLayeredMiniport(pGlobalsMp->hNdisWrapper, &MpChars, sizeof (MpChars), &pGlobalsMp->hMiniport); +#else + NDIS_STATUS Status = NdisMRegisterMiniport(pGlobalsMp->hNdisWrapper, &MpChars, sizeof (MpChars)); +#endif + Assert(Status == NDIS_STATUS_SUCCESS); + if (Status == NDIS_STATUS_SUCCESS) + { + NdisMRegisterUnloadHandler(pGlobalsMp->hNdisWrapper, vboxNetFltWinUnload); + } + + return Status; +} + +/** + * deregister the miniport edge + */ +DECLHIDDEN(VOID) vboxNetFltWinMpDeregister(PVBOXNETFLTGLOBALS_MP pGlobalsMp) +{ +#ifndef VBOXNETADP + NdisIMDeregisterLayeredMiniport(pGlobalsMp->hMiniport); +#endif + NdisTerminateWrapper(pGlobalsMp->hNdisWrapper, NULL); + + NdisZeroMemory(pGlobalsMp, sizeof (*pGlobalsMp)); +} + +#ifndef VBOXNETADP + +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpInitializeDevideInstance(PVBOXNETFLTINS pThis) +{ + NDIS_STATUS Status; + Assert(vboxNetFltWinGetOpState(&pThis->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized); + vboxNetFltWinSetOpState(&pThis->u.s.WinIf.MpState, kVBoxNetDevOpState_Initializing); + + Status = NdisIMInitializeDeviceInstanceEx(g_VBoxNetFltGlobalsWin.Mp.hMiniport, + &pThis->u.s.WinIf.MpDeviceName, + pThis); + if (Status == NDIS_STATUS_SUCCESS) + { + if (pThis->u.s.WinIf.OpenCloseStatus == NDIS_STATUS_SUCCESS) + { + return NDIS_STATUS_SUCCESS; + } + AssertBreakpoint(); + vboxNetFltWinMpDeInitializeDeviceInstance(pThis, &Status); + Assert(vboxNetFltWinGetOpState(&pThis->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized); + vboxNetFltWinSetOpState(&pThis->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized); + return pThis->u.s.WinIf.OpenCloseStatus; + } + + Assert(vboxNetFltWinGetOpState(&pThis->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized); + vboxNetFltWinSetOpState(&pThis->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized); + + return Status; +} + +DECLHIDDEN(bool) vboxNetFltWinMpDeInitializeDeviceInstance(PVBOXNETFLTINS pThis, PNDIS_STATUS pStatus) +{ + NDIS_STATUS Status; + + if (vboxNetFltWinGetOpState(&pThis->u.s.WinIf.MpState) == kVBoxNetDevOpState_Initializing) + { + Status = NdisIMCancelInitializeDeviceInstance(g_VBoxNetFltGlobalsWin.Mp.hMiniport, &pThis->u.s.WinIf.MpDeviceName); + + if (Status == NDIS_STATUS_SUCCESS) + { + /* we've canceled the initialization successfully */ + Assert(pThis->u.s.WinIf.hMiniport == NULL); + Assert(vboxNetFltWinGetOpState(&pThis->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized); + vboxNetFltWinSetOpState(&pThis->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized); + } + else + { + NdisWaitEvent(&pThis->u.s.WinIf.MpInitCompleteEvent, 0); + } + } + + Assert(vboxNetFltWinGetOpState(&pThis->u.s.WinIf.MpState) == kVBoxNetDevOpState_Initialized + || vboxNetFltWinGetOpState(&pThis->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized); + if (vboxNetFltWinGetOpState(&pThis->u.s.WinIf.MpState) == kVBoxNetDevOpState_Initialized) + { + vboxNetFltWinSetOpState(&pThis->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitializing); + + Status = NdisIMDeInitializeDeviceInstance(pThis->u.s.WinIf.hMiniport); + + vboxNetFltWinSetOpState(&pThis->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized); + if (Status != NDIS_STATUS_SUCCESS) + { + Status = NDIS_STATUS_FAILURE; + } + + *pStatus = Status; + return true; + } + + Assert(vboxNetFltWinGetOpState(&pThis->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized); + vboxNetFltWinSetOpState(&pThis->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized); + + *pStatus = Status; + return false; +} +#endif diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltM-win.h b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltM-win.h new file mode 100644 index 000000000..958deb4cb --- /dev/null +++ b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltM-win.h @@ -0,0 +1,42 @@ +/* $Id: VBoxNetFltM-win.h 36207 2011-03-08 17:12:10Z vboxsync $ */ +/** @file + * VBoxNetFltM-win.h - Bridged Networking Driver, Windows Specific Code - Miniport edge API + */ + +/* + * Copyright (C) 2011 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + */ + +#ifndef ___VBoxNetFltM_win_h___ +#define ___VBoxNetFltM_win_h___ + +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpRegister(PVBOXNETFLTGLOBALS_MP pGlobalsMp, PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPathStr); +DECLHIDDEN(VOID) vboxNetFltWinMpDeregister(PVBOXNETFLTGLOBALS_MP pGlobalsMp); +DECLHIDDEN(VOID) vboxNetFltWinMpReturnPacket(IN NDIS_HANDLE hMiniportAdapterContext, IN PNDIS_PACKET pPacket); + +#ifdef VBOXNETADP +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpDoInitialization(PVBOXNETFLTINS pThis, NDIS_HANDLE hMiniportAdapter, NDIS_HANDLE hWrapperConfigurationContext); +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpDoDeinitialization(PVBOXNETFLTINS pThis); +#else +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpInitializeDevideInstance(PVBOXNETFLTINS pThis); +DECLHIDDEN(bool) vboxNetFltWinMpDeInitializeDeviceInstance(PVBOXNETFLTINS pThis, PNDIS_STATUS pStatus); +DECLINLINE(VOID) vboxNetFltWinMpRequestStateComplete(PVBOXNETFLTINS pNetFlt) +{ + RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; + RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp); + pNetFlt->u.s.WinIf.StateFlags.fRequestInfo = 0; + RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); +} +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpRequestPost(PVBOXNETFLTINS pNetFlt); +#endif + +#endif /* !___VBoxNetFltM_win_h___ */ + diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt_m.inf b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltM.inf index 0a1b4a874..25748e10d 100644 --- a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt_m.inf +++ b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltM.inf @@ -1,9 +1,10 @@ +; $Id: VBoxNetFltM.inf 36184 2011-03-07 10:57:04Z vboxsync $ +; @file +; VBoxNetFltM.inf - VirtualBox Bridged Networking Driver inf file +; Miniport edge ; -; VirtualBox Bridged Networking Driver ; - -; -; Copyright (C) 2008 Oracle Corporation +; Copyright (C) 2011 Oracle Corporation ; ; This file is part of VirtualBox Open Source Edition (OSE), as ; available from http://www.virtualbox.org. This file is free software; @@ -14,11 +15,6 @@ ; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. ; -; -; Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample. -; Copyright (c) 1993-1999, Microsoft Corporation -; - [Version] signature = "$Windows NT$" ;cat CatalogFile = VBoxNetFlt.cat @@ -37,19 +33,14 @@ DefaultDestDir=12 ; No files to copy [Manufacturer] -%Provider% = VBox,NTx86,NTia64,NTamd64 +%Provider% = VBox,NTx86,NTamd64 -; For Win2K [VBox] %VBoxNetFltMP_Desc% = VBoxNetFltMP.ndi, sun_VBoxNetFltmp -; For XP and later [VBox.NTx86] %VBoxNetFltMP_Desc% = VBoxNetFltMP.ndi, sun_VBoxNetFltmp -[VBox.NTia64] -%VBoxNetFltMP_Desc% = VBoxNetFltMP.ndi, sun_VBoxNetFltmp - [VBox.NTamd64] %VBoxNetFltMP_Desc% = VBoxNetFltMP.ndi, sun_VBoxNetFltmp @@ -60,31 +51,21 @@ CopyFiles = [VBoxNetFltMP.ndi.Services] AddService = VBoxNetFlt,0x2, VBoxNetFltMP.AddService - [VBoxNetFltMP.AddService] ServiceType = 1 ;SERVICE_KERNEL_DRIVER StartType = 3 ;SERVICE_DEMAND_START ErrorControl = 1 ;SERVICE_ERROR_NORMAL ServiceBinary = %12%\VBoxNetFlt.sys - [VBoxNetFltMP.AddService.AddReg] -; ---------------------------------------------------------------------- -; Add any miniport-specific parameters here. These are params that your -; filter device is going to use. -; -;HKR, Parameters, ParameterName, 0x10000, "MultiSz", "Parameter", "Value" -;HKR, Parameters, ParameterName2, 0x10001, 4 [Strings] Provider = "Oracle Corporation" VBoxNetFltMP_Desc = "VirtualBox Bridged Networking Driver Miniport" [SourceDisksNames] -;None [SourceDisksFiles] -;None diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltP-win.cpp b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltP-win.cpp new file mode 100644 index 000000000..bba6ba40d --- /dev/null +++ b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltP-win.cpp @@ -0,0 +1,1580 @@ +/* $Id: VBoxNetFltP-win.cpp 36184 2011-03-07 10:57:04Z vboxsync $ */ +/** @file + * VBoxNetFltP-win.cpp - Bridged Networking Driver, Windows Specific Code. + * Protocol edge + */ +/* + * Copyright (C) 2011 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + */ +#include "VBoxNetFltCmn-win.h" + +#ifdef VBOXNETADP +# error "No protocol edge" +#endif + +#define VBOXNETFLT_PT_STATUS_IS_FILTERED(_s) (\ + (_s) == NDIS_STATUS_MEDIA_CONNECT \ + || (_s) == NDIS_STATUS_MEDIA_DISCONNECT \ + ) + +/** + * performs binding to the given adapter + */ +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtDoBinding(PVBOXNETFLTINS pThis, PNDIS_STRING pOurDeviceName, PNDIS_STRING pBindToDeviceName) +{ + Assert(pThis->u.s.WinIf.PtState.PowerState == NdisDeviceStateD3); + Assert(pThis->u.s.WinIf.PtState.OpState == kVBoxNetDevOpState_Deinitialized); + Assert(KeGetCurrentIrql() == PASSIVE_LEVEL); + + vboxNetFltWinSetOpState(&pThis->u.s.WinIf.PtState, kVBoxNetDevOpState_Initializing); + + NDIS_STATUS Status = vboxNetFltWinCopyString(&pThis->u.s.WinIf.MpDeviceName, pOurDeviceName); + Assert (Status == NDIS_STATUS_SUCCESS); + if (Status == NDIS_STATUS_SUCCESS) + { + vboxNetFltWinSetPowerState(&pThis->u.s.WinIf.PtState, NdisDeviceStateD0); + pThis->u.s.WinIf.OpenCloseStatus = NDIS_STATUS_SUCCESS; + + UINT iMedium; + NDIS_STATUS TmpStatus; + NDIS_MEDIUM aenmNdisMedium[] = + { + /* Ethernet */ + NdisMedium802_3, + /* Wan */ + NdisMediumWan + }; + + NdisResetEvent(&pThis->u.s.WinIf.OpenCloseEvent); + + NdisOpenAdapter(&Status, &TmpStatus, &pThis->u.s.WinIf.hBinding, &iMedium, + aenmNdisMedium, RT_ELEMENTS(aenmNdisMedium), + g_VBoxNetFltGlobalsWin.Pt.hProtocol, + pThis, + pBindToDeviceName, + 0, /* IN UINT OpenOptions, (reserved, should be NULL) */ + NULL /* IN PSTRING AddressingInformation OPTIONAL */ + ); + Assert(Status == NDIS_STATUS_PENDING || Status == STATUS_SUCCESS); + if (Status == NDIS_STATUS_PENDING) + { + NdisWaitEvent(&pThis->u.s.WinIf.OpenCloseEvent, 0); + Status = pThis->u.s.WinIf.OpenCloseStatus; + } + + Assert(Status == NDIS_STATUS_SUCCESS); + if (Status == NDIS_STATUS_SUCCESS) + { + Assert(pThis->u.s.WinIf.hBinding); + pThis->u.s.WinIf.enmMedium = aenmNdisMedium[iMedium]; + vboxNetFltWinSetOpState(&pThis->u.s.WinIf.PtState, kVBoxNetDevOpState_Initialized); + + Status = vboxNetFltWinMpInitializeDevideInstance(pThis); + Assert(Status == NDIS_STATUS_SUCCESS); + if (Status == NDIS_STATUS_SUCCESS) + { + return NDIS_STATUS_SUCCESS; + } + else + { + LogRel((__FUNCTION__": vboxNetFltWinMpInitializeDevideInstance failed, Status 0x%x\n", Status)); + } + + vboxNetFltWinSetOpState(&pThis->u.s.WinIf.PtState, kVBoxNetDevOpState_Deinitializing); + vboxNetFltWinPtCloseInterface(pThis, &TmpStatus); + Assert(TmpStatus == NDIS_STATUS_SUCCESS); + vboxNetFltWinSetOpState(&pThis->u.s.WinIf.PtState, kVBoxNetDevOpState_Deinitialized); + } + else + { + LogRel((__FUNCTION__"NdisOpenAdapter failed, Status (0x%x)", Status)); + } + + vboxNetFltWinSetOpState(&pThis->u.s.WinIf.PtState, kVBoxNetDevOpState_Deinitialized); + pThis->u.s.WinIf.hBinding = NULL; + } + + return Status; +} + +static VOID vboxNetFltWinPtBindAdapter(OUT PNDIS_STATUS pStatus, + IN NDIS_HANDLE hBindContext, + IN PNDIS_STRING pDeviceNameStr, + IN PVOID pvSystemSpecific1, + IN PVOID pvSystemSpecific2) +{ + LogFlow(("==>"__FUNCTION__"\n")); + + NDIS_STATUS Status; + NDIS_HANDLE hConfig = NULL; + + NdisOpenProtocolConfiguration(&Status, &hConfig, (PNDIS_STRING)pvSystemSpecific1); + Assert(Status == NDIS_STATUS_SUCCESS); + if (Status == NDIS_STATUS_SUCCESS) + { + PNDIS_CONFIGURATION_PARAMETER pParam; + NDIS_STRING UppedBindStr = NDIS_STRING_CONST("UpperBindings"); + NdisReadConfiguration(&Status, &pParam, hConfig, &UppedBindStr, NdisParameterString); + Assert(Status == NDIS_STATUS_SUCCESS); + if (Status == NDIS_STATUS_SUCCESS) + { + PVBOXNETFLTINS pNetFlt; + Status = vboxNetFltWinPtInitBind(&pNetFlt, &pParam->ParameterData.StringData, pDeviceNameStr); + Assert(Status == NDIS_STATUS_SUCCESS); + } + + NdisCloseConfiguration(hConfig); + } + + *pStatus = Status; + + LogFlow(("<=="__FUNCTION__": Status 0x%x\n", Status)); +} + +static VOID vboxNetFltWinPtOpenAdapterComplete(IN NDIS_HANDLE hProtocolBindingContext, IN NDIS_STATUS Status, IN NDIS_STATUS OpenErrorStatus) +{ + PVBOXNETFLTINS pNetFlt =(PVBOXNETFLTINS)hProtocolBindingContext; + + LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p), Status (0x%x), OpenErrorStatus(0x%x)\n", pNetFlt, Status, OpenErrorStatus)); + Assert(pNetFlt->u.s.WinIf.OpenCloseStatus == NDIS_STATUS_SUCCESS); + Assert(Status == NDIS_STATUS_SUCCESS); + if (pNetFlt->u.s.WinIf.OpenCloseStatus == NDIS_STATUS_SUCCESS) + { + pNetFlt->u.s.WinIf.OpenCloseStatus = Status; + Assert(Status == NDIS_STATUS_SUCCESS); + if (Status != NDIS_STATUS_SUCCESS) + LogRel((__FUNCTION__" : Open Complete status is 0x%x", Status)); + } + else + LogRel((__FUNCTION__" : Adapter maintained status is 0x%x", pNetFlt->u.s.WinIf.OpenCloseStatus)); + NdisSetEvent(&pNetFlt->u.s.WinIf.OpenCloseEvent); + LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), Status (0x%x), OpenErrorStatus(0x%x)\n", pNetFlt, Status, OpenErrorStatus)); +} + +static void vboxNetFltWinPtRequestsWaitComplete(PVBOXNETFLTINS pNetFlt) +{ + RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; + + /* wait for request to complete */ + while (vboxNetFltWinAtomicUoReadWinState(pNetFlt->u.s.WinIf.StateFlags).fRequestInfo == VBOXNDISREQUEST_INPROGRESS) + { + vboxNetFltWinSleep(2); + } + + /* + * If the below miniport is going to low power state, complete the queued request + */ + RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp); + if (pNetFlt->u.s.WinIf.StateFlags.fRequestInfo & VBOXNDISREQUEST_QUEUED) + { + /* mark the request as InProgress before posting it to RequestComplete */ + pNetFlt->u.s.WinIf.StateFlags.fRequestInfo = VBOXNDISREQUEST_INPROGRESS; + RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); + vboxNetFltWinPtRequestComplete(pNetFlt, &pNetFlt->u.s.WinIf.PassDownRequest, NDIS_STATUS_FAILURE); + } + else + { + RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); + } +} + +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtDoUnbinding(PVBOXNETFLTINS pNetFlt, bool bOnUnbind) +{ + NDIS_STATUS Status; + RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; + uint64_t NanoTS = RTTimeSystemNanoTS(); + int cPPUsage; + + LogFlow(("==>"__FUNCTION__": pNetFlt 0x%p\n", pNetFlt)); + + Assert(KeGetCurrentIrql() == PASSIVE_LEVEL); + + Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.PtState) == kVBoxNetDevOpState_Initialized); + + RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp); + + ASMAtomicUoWriteBool(&pNetFlt->fDisconnectedFromHost, true); + ASMAtomicUoWriteBool(&pNetFlt->fRediscoveryPending, false); + ASMAtomicUoWriteU64(&pNetFlt->NanoTSLastRediscovery, NanoTS); + + vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.PtState, kVBoxNetDevOpState_Deinitializing); + if (!bOnUnbind) + { + vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitializing); + } + + RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); + + vboxNetFltWinPtRequestsWaitComplete(pNetFlt); + + vboxNetFltWinWaitDereference(&pNetFlt->u.s.WinIf.MpState); + vboxNetFltWinWaitDereference(&pNetFlt->u.s.WinIf.PtState); + + /* check packet pool is empty */ + cPPUsage = NdisPacketPoolUsage(pNetFlt->u.s.WinIf.hSendPacketPool); + Assert(cPPUsage == 0); + cPPUsage = NdisPacketPoolUsage(pNetFlt->u.s.WinIf.hRecvPacketPool); + Assert(cPPUsage == 0); + /* for debugging only, ignore the err in release */ + NOREF(cPPUsage); + + if (!bOnUnbind || !vboxNetFltWinMpDeInitializeDeviceInstance(pNetFlt, &Status)) + { + vboxNetFltWinPtCloseInterface(pNetFlt, &Status); + vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.PtState, kVBoxNetDevOpState_Deinitialized); + + if (!bOnUnbind) + { + Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitializing); + vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized); + } + else + { + Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized); + } + } + else + { + Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized); + } + + LogFlow(("<=="__FUNCTION__": pNetFlt 0x%p\n", pNetFlt)); + + return Status; +} + +static VOID vboxNetFltWinPtUnbindAdapter(OUT PNDIS_STATUS pStatus, + IN NDIS_HANDLE hContext, + IN NDIS_HANDLE hUnbindContext) +{ + PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hContext; + + LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p)\n", pNetFlt)); + + *pStatus = vboxNetFltWinDetachFromInterface(pNetFlt, true); + Assert(*pStatus == NDIS_STATUS_SUCCESS); + + LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p)\n", pNetFlt)); +} + +static VOID vboxNetFltWinPtUnloadProtocol() +{ + LogFlow(("==>"__FUNCTION__"\n")); + NDIS_STATUS Status = vboxNetFltWinPtDeregister(&g_VBoxNetFltGlobalsWin.Pt); + Assert(Status == NDIS_STATUS_SUCCESS); + LogFlow(("<=="__FUNCTION__": PtDeregister Status (0x%x)\n", Status)); +} + + +static VOID vboxNetFltWinPtCloseAdapterComplete(IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status) +{ + PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)ProtocolBindingContext; + + LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p), Status (0x%x)\n", pNetFlt, Status)); + Assert(pNetFlt->u.s.WinIf.OpenCloseStatus == NDIS_STATUS_SUCCESS); + Assert(Status == NDIS_STATUS_SUCCESS); + Assert(pNetFlt->u.s.WinIf.OpenCloseStatus == NDIS_STATUS_SUCCESS); + if (pNetFlt->u.s.WinIf.OpenCloseStatus == NDIS_STATUS_SUCCESS) + { + pNetFlt->u.s.WinIf.OpenCloseStatus = Status; + } + NdisSetEvent(&pNetFlt->u.s.WinIf.OpenCloseEvent); + LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p), Status (0x%x)\n", pNetFlt, Status)); +} + +static VOID vboxNetFltWinPtResetComplete(IN NDIS_HANDLE hProtocolBindingContext, IN NDIS_STATUS Status) +{ + LogFlow(("==>"__FUNCTION__" : pNetFlt 0x%p, Status 0x%x\n", hProtocolBindingContext, Status)); + /* + * should never be here + */ + Assert(0); + LogFlow(("<=="__FUNCTION__" : pNetFlt 0x%p, Status 0x%x\n", hProtocolBindingContext, Status)); +} + +static NDIS_STATUS vboxNetFltWinPtHandleQueryInfoComplete(PVBOXNETFLTINS pNetFlt, NDIS_STATUS Status) +{ + PNDIS_REQUEST pRequest = &pNetFlt->u.s.WinIf.PassDownRequest; + + switch (pRequest->DATA.QUERY_INFORMATION.Oid) + { + case OID_PNP_CAPABILITIES: + { + if (Status == NDIS_STATUS_SUCCESS) + { + if (pRequest->DATA.QUERY_INFORMATION.InformationBufferLength >= sizeof (NDIS_PNP_CAPABILITIES)) + { + PNDIS_PNP_CAPABILITIES pPnPCaps = (PNDIS_PNP_CAPABILITIES)(pRequest->DATA.QUERY_INFORMATION.InformationBuffer); + PNDIS_PM_WAKE_UP_CAPABILITIES pPmWuCaps = &pPnPCaps->WakeUpCapabilities; + pPmWuCaps->MinMagicPacketWakeUp = NdisDeviceStateUnspecified; + pPmWuCaps->MinPatternWakeUp = NdisDeviceStateUnspecified; + pPmWuCaps->MinLinkChangeWakeUp = NdisDeviceStateUnspecified; + *pNetFlt->u.s.WinIf.pcPDRBytesRW = sizeof (NDIS_PNP_CAPABILITIES); + *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = 0; + Status = NDIS_STATUS_SUCCESS; + } + else + { + Assert(0); + *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = sizeof(NDIS_PNP_CAPABILITIES); + Status = NDIS_STATUS_RESOURCES; + } + } + break; + } + + case OID_GEN_MAC_OPTIONS: + { + if (Status == NDIS_STATUS_SUCCESS) + { + if (pRequest->DATA.QUERY_INFORMATION.InformationBufferLength >= sizeof (ULONG)) + { + pNetFlt->u.s.WinIf.fMacOptions = *(PULONG)pRequest->DATA.QUERY_INFORMATION.InformationBuffer; +#ifndef VBOX_LOOPBACK_USEFLAGS + /* clearing this flag tells ndis we'll handle loopback ourselves + * the ndis layer or nic driver below us would loopback packets as necessary */ + *(PULONG)pRequest->DATA.QUERY_INFORMATION.InformationBuffer &= ~NDIS_MAC_OPTION_NO_LOOPBACK; +#else + /* we have to catch loopbacks from the underlying driver, so no duplications will occur, + * just indicate NDIS to handle loopbacks for the packets coming from the protocol */ + *(PULONG)pRequest->DATA.QUERY_INFORMATION.InformationBuffer |= NDIS_MAC_OPTION_NO_LOOPBACK; +#endif + } + else + { + Assert(0); + *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = sizeof (ULONG); + Status = NDIS_STATUS_RESOURCES; + } + } + break; + } + + case OID_GEN_CURRENT_PACKET_FILTER: + { + if (VBOXNETFLT_PROMISCUOUS_SUPPORTED(pNetFlt)) + { + /* we're here _ONLY_ in the passthru mode */ + Assert(pNetFlt->u.s.WinIf.StateFlags.fProcessingPacketFilter && !pNetFlt->u.s.WinIf.StateFlags.fPPFNetFlt); + if (pNetFlt->u.s.WinIf.StateFlags.fProcessingPacketFilter && !pNetFlt->u.s.WinIf.StateFlags.fPPFNetFlt) + { + Assert(pNetFlt->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE); + vboxNetFltWinDereferenceModePassThru(pNetFlt); + vboxNetFltWinDereferenceWinIf(pNetFlt); + } + + if (Status == NDIS_STATUS_SUCCESS) + { + if (pRequest->DATA.QUERY_INFORMATION.InformationBufferLength >= sizeof (ULONG)) + { + /* the filter request is issued below only in case netflt is not active, + * simply update the cache here */ + /* cache the filter used by upper protocols */ + pNetFlt->u.s.WinIf.fUpperProtocolSetFilter = *(PULONG)pRequest->DATA.QUERY_INFORMATION.InformationBuffer; + pNetFlt->u.s.WinIf.StateFlags.fUpperProtSetFilterInitialized = TRUE; + } + else + { + Assert(0); + *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = sizeof (ULONG); + Status = NDIS_STATUS_RESOURCES; + } + } + } + break; + } + + default: + Assert(pRequest->DATA.QUERY_INFORMATION.Oid != OID_PNP_QUERY_POWER); + break; + } + + *pNetFlt->u.s.WinIf.pcPDRBytesRW = pRequest->DATA.QUERY_INFORMATION.BytesWritten; + *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = pRequest->DATA.QUERY_INFORMATION.BytesNeeded; + + return Status; +} + +static NDIS_STATUS vboxNetFltWinPtHandleSetInfoComplete(PVBOXNETFLTINS pNetFlt, NDIS_STATUS Status) +{ + PNDIS_REQUEST pRequest = &pNetFlt->u.s.WinIf.PassDownRequest; + + switch (pRequest->DATA.SET_INFORMATION.Oid) + { + case OID_GEN_CURRENT_PACKET_FILTER: + { + if (VBOXNETFLT_PROMISCUOUS_SUPPORTED(pNetFlt)) + { + Assert(Status == NDIS_STATUS_SUCCESS); + if (pNetFlt->u.s.WinIf.StateFlags.fProcessingPacketFilter) + { + if (pNetFlt->u.s.WinIf.StateFlags.fPPFNetFlt) + { + Assert(pNetFlt->enmTrunkState == INTNETTRUNKIFSTATE_ACTIVE); + pNetFlt->u.s.WinIf.StateFlags.fPPFNetFlt = 0; + if (Status == NDIS_STATUS_SUCCESS) + { + if (pRequest->DATA.SET_INFORMATION.InformationBufferLength >= sizeof (ULONG)) + { + pNetFlt->u.s.WinIf.fOurSetFilter = *((PULONG)pRequest->DATA.SET_INFORMATION.InformationBuffer); + Assert(pNetFlt->u.s.WinIf.fOurSetFilter == NDIS_PACKET_TYPE_PROMISCUOUS); + } + else + { + Assert(0); + *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = sizeof (ULONG); + Status = NDIS_STATUS_RESOURCES; + } + } + vboxNetFltWinDereferenceNetFlt(pNetFlt); + } + else + { + Assert(pNetFlt->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE); + + if (Status == NDIS_STATUS_SUCCESS) + { + if (pRequest->DATA.SET_INFORMATION.InformationBufferLength >= sizeof (ULONG)) + { + /* the request was issued when the netflt was not active, simply update the cache here */ + pNetFlt->u.s.WinIf.fUpperProtocolSetFilter = *((PULONG)pRequest->DATA.SET_INFORMATION.InformationBuffer); + pNetFlt->u.s.WinIf.StateFlags.fUpperProtSetFilterInitialized = TRUE; + } + else + { + Assert(0); + *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = sizeof (ULONG); + Status = NDIS_STATUS_RESOURCES; + } + } + vboxNetFltWinDereferenceModePassThru(pNetFlt); + } + + pNetFlt->u.s.WinIf.StateFlags.fProcessingPacketFilter = 0; + vboxNetFltWinDereferenceWinIf(pNetFlt); + } +#ifdef DEBUG_misha + else + { + Assert(0); + } +#endif + } + break; + } + + default: + Assert(pRequest->DATA.SET_INFORMATION.Oid != OID_PNP_SET_POWER); + break; + } + + *pNetFlt->u.s.WinIf.pcPDRBytesRW = pRequest->DATA.SET_INFORMATION.BytesRead; + *pNetFlt->u.s.WinIf.pcPDRBytesNeeded = pRequest->DATA.SET_INFORMATION.BytesNeeded; + + return Status; +} + +DECLHIDDEN(VOID) vboxNetFltWinPtRequestComplete(NDIS_HANDLE hContext, PNDIS_REQUEST pNdisRequest, NDIS_STATUS Status) +{ + PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hContext; + PNDIS_REQUEST pSynchRequest = pNetFlt->u.s.WinIf.pSynchRequest; + NDIS_OID Oid = pNetFlt->u.s.WinIf.PassDownRequest.DATA.SET_INFORMATION.Oid; + + LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p), pNdisRequest (0x%p), Status (0x%x)\n", pNetFlt, pNdisRequest, Status)); + + if (pSynchRequest == pNdisRequest) + { + /* asynchronous completion of our sync request */ + /*1.set the status */ + pNetFlt->u.s.WinIf.SynchCompletionStatus = Status; + /* 2. set event */ + KeSetEvent(&pNetFlt->u.s.WinIf.hSynchCompletionEvent, 0, FALSE); + /* 3. return; */ + + LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p), pNdisRequest (0x%p), Status (0x%x)\n", pNetFlt, pNdisRequest, Status)); + return; + } + + Assert(&pNetFlt->u.s.WinIf.PassDownRequest == pNdisRequest); + Assert(pNetFlt->u.s.WinIf.StateFlags.fRequestInfo == VBOXNDISREQUEST_INPROGRESS); + vboxNetFltWinMpRequestStateComplete(pNetFlt); + + switch (pNdisRequest->RequestType) + { + case NdisRequestQueryInformation: + Status = vboxNetFltWinPtHandleQueryInfoComplete(pNetFlt, Status); + NdisMQueryInformationComplete(pNetFlt->u.s.WinIf.hMiniport, Status); + break; + + case NdisRequestSetInformation: + Status = vboxNetFltWinPtHandleSetInfoComplete(pNetFlt, Status); + NdisMSetInformationComplete(pNetFlt->u.s.WinIf.hMiniport, Status); + break; + + default: + Assert(0); + break; + } + + LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p), pNdisRequest (0x%p), Status (0x%x)\n", pNetFlt, pNdisRequest, Status)); +} + +static VOID vboxNetFltWinPtStatus(IN NDIS_HANDLE hProtocolBindingContext, IN NDIS_STATUS GeneralStatus, IN PVOID pvStatusBuffer, IN UINT cbStatusBuffer) +{ + PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext; + + LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p), GeneralStatus (0x%x)\n", pNetFlt, GeneralStatus)); + + if (vboxNetFltWinReferenceWinIf(pNetFlt)) + { + Assert(pNetFlt->u.s.WinIf.hMiniport); + + if (VBOXNETFLT_PT_STATUS_IS_FILTERED(GeneralStatus)) + { + pNetFlt->u.s.WinIf.MpIndicatedMediaStatus = GeneralStatus; + } + NdisMIndicateStatus(pNetFlt->u.s.WinIf.hMiniport, + GeneralStatus, + pvStatusBuffer, + cbStatusBuffer); + + vboxNetFltWinDereferenceWinIf(pNetFlt); + } + else + { + if (pNetFlt->u.s.WinIf.hMiniport != NULL + && VBOXNETFLT_PT_STATUS_IS_FILTERED(GeneralStatus) + ) + { + pNetFlt->u.s.WinIf.MpUnindicatedMediaStatus = GeneralStatus; + } + } + + LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p), GeneralStatus (0x%x)\n", pNetFlt, GeneralStatus)); +} + + +static VOID vboxNetFltWinPtStatusComplete(IN NDIS_HANDLE hProtocolBindingContext) +{ + PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext; + + LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt)); + + if (vboxNetFltWinReferenceWinIf(pNetFlt)) + { + NdisMIndicateStatusComplete(pNetFlt->u.s.WinIf.hMiniport); + + vboxNetFltWinDereferenceWinIf(pNetFlt); + } + + LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt)); +} + +static VOID vboxNetFltWinPtSendComplete(IN NDIS_HANDLE hProtocolBindingContext, IN PNDIS_PACKET pPacket, IN NDIS_STATUS Status) +{ + PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext; + PVBOXNETFLT_PKTRSVD_PT pSendInfo = (PVBOXNETFLT_PKTRSVD_PT)pPacket->ProtocolReserved; + PNDIS_PACKET pOrigPacket = pSendInfo->pOrigPacket; + PVOID pBufToFree = pSendInfo->pBufToFree; + LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p), pPacket (0x%p), Status (0x%x)\n", pNetFlt, pPacket, Status)); + +#if defined(DEBUG_NETFLT_PACKETS) || !defined(VBOX_LOOPBACK_USEFLAGS) + /* @todo: for optimization we could check only for netflt-mode packets + * do it for all for now */ + vboxNetFltWinLbRemoveSendPacket(pNetFlt, pPacket); +#endif + + if (pOrigPacket) + { + NdisIMCopySendCompletePerPacketInfo(pOrigPacket, pPacket); + NdisFreePacket(pPacket); + /* the ptk was posted from the upperlying protocol */ + NdisMSendComplete(pNetFlt->u.s.WinIf.hMiniport, pOrigPacket, Status); + } + else + { + /* if the pOrigPacket is zero - the ptk was originated by netFlt send/receive + * need to free packet buffers */ + vboxNetFltWinFreeSGNdisPacket(pPacket, !pBufToFree); + } + + if (pBufToFree) + { + vboxNetFltWinMemFree(pBufToFree); + } + + vboxNetFltWinDereferenceWinIf(pNetFlt); + + LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), pPacket (0x%p), Status (0x%x)\n", pNetFlt, pPacket, Status)); +} + +/** + * removes searches for the packet in the list and removes it if found + * @return true if the packet was found and removed, false - otherwise + */ +static bool vboxNetFltWinRemovePacketFromList(PVBOXNETFLT_INTERLOCKED_SINGLE_LIST pList, PNDIS_PACKET pPacket) +{ + PVBOXNETFLT_PKTRSVD_TRANSFERDATA_PT pTDR = (PVBOXNETFLT_PKTRSVD_TRANSFERDATA_PT)pPacket->ProtocolReserved; + return vboxNetFltWinInterlockedSearchListEntry(pList, &pTDR->ListEntry, true /* remove*/); +} + +/** + * puts the packet to the tail of the list + */ +static void vboxNetFltWinPutPacketToList(PVBOXNETFLT_INTERLOCKED_SINGLE_LIST pList, PNDIS_PACKET pPacket, PNDIS_BUFFER pOrigBuffer) +{ + PVBOXNETFLT_PKTRSVD_TRANSFERDATA_PT pTDR = (PVBOXNETFLT_PKTRSVD_TRANSFERDATA_PT)pPacket->ProtocolReserved; + pTDR->pOrigBuffer = pOrigBuffer; + vboxNetFltWinInterlockedPutTail(pList, &pTDR->ListEntry); +} + +static bool vboxNetFltWinPtTransferDataCompleteActive(PVBOXNETFLTINS pNetFltIf, PNDIS_PACKET pPacket, NDIS_STATUS Status) +{ + PNDIS_BUFFER pBuffer; + PVBOXNETFLT_PKTRSVD_TRANSFERDATA_PT pTDR; + + if (!vboxNetFltWinRemovePacketFromList(&pNetFltIf->u.s.WinIf.TransferDataList, pPacket)) + return false; + + pTDR = (PVBOXNETFLT_PKTRSVD_TRANSFERDATA_PT)pPacket->ProtocolReserved; + Assert(pTDR); + Assert(pTDR->pOrigBuffer); + + do + { + NdisUnchainBufferAtFront(pPacket, &pBuffer); + + Assert(pBuffer); + + NdisFreeBuffer(pBuffer); + + pBuffer = pTDR->pOrigBuffer; + + NdisChainBufferAtBack(pPacket, pBuffer); + + /* data transfer was initiated when the netFlt was active + * the netFlt is still retained by us + * 1. check if loopback + * 2. enqueue packet + * 3. release netFlt */ + + if (Status == NDIS_STATUS_SUCCESS) + { + +#ifdef VBOX_LOOPBACK_USEFLAGS + if (vboxNetFltWinIsLoopedBackPacket(pPacket)) + { + /* should not be here */ + Assert(0); + } +#else + PNDIS_PACKET pLb = vboxNetFltWinLbSearchLoopBack(pNetFltIf, pPacket, false); + if (pLb) + { +#ifndef DEBUG_NETFLT_RECV_TRANSFERDATA + /* should not be here */ + Assert(0); +#endif + if (!vboxNetFltWinLbIsFromIntNet(pLb)) + { + /* the packet is not from int net, need to pass it up to the host */ + NdisMIndicateReceivePacket(pNetFltIf->u.s.WinIf.hMiniport, &pPacket, 1); + /* dereference NetFlt, WinIf will be dereferenced on Packet return */ + vboxNetFltWinDereferenceNetFlt(pNetFltIf); + break; + } + } +#endif + else + { + /* 2. enqueue */ + /* use the same packet info to put the packet in the processing packet queue */ + PVBOXNETFLT_PKTRSVD_MP pRecvInfo = (PVBOXNETFLT_PKTRSVD_MP)pPacket->MiniportReserved; + + VBOXNETFLT_LBVERIFY(pNetFltIf, pPacket); + + pRecvInfo->pOrigPacket = NULL; + pRecvInfo->pBufToFree = NULL; + + NdisGetPacketFlags(pPacket) = 0; +# ifdef VBOXNETFLT_NO_PACKET_QUEUE + if (vboxNetFltWinPostIntnet(pNetFltIf, pPacket, 0)) + { + /* drop it */ + vboxNetFltWinFreeSGNdisPacket(pPacket, true); + vboxNetFltWinDereferenceWinIf(pNetFltIf); + } + else + { + NdisMIndicateReceivePacket(pNetFltIf->u.s.WinIf.hMiniport, &pPacket, 1); + } + vboxNetFltWinDereferenceNetFlt(pNetFltIf); + break; +# else + Status = vboxNetFltWinQuEnqueuePacket(pNetFltIf, pPacket, PACKET_MINE); + if (Status == NDIS_STATUS_SUCCESS) + { + break; + } + Assert(0); +# endif + } + } + else + { + Assert(0); + } + /* we are here because of error either in data transfer or in enqueueing the packet */ + vboxNetFltWinFreeSGNdisPacket(pPacket, true); + vboxNetFltWinDereferenceNetFlt(pNetFltIf); + vboxNetFltWinDereferenceWinIf(pNetFltIf); + } while (0); + + return true; +} + +static VOID vboxNetFltWinPtTransferDataComplete(IN NDIS_HANDLE hProtocolBindingContext, + IN PNDIS_PACKET pPacket, + IN NDIS_STATUS Status, + IN UINT cbTransferred) +{ + PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext; + LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p), pPacket (0x%p), Status (0x%x), cbTransfered (%d)\n", pNetFlt, pPacket, Status, cbTransferred)); + if (!vboxNetFltWinPtTransferDataCompleteActive(pNetFlt, pPacket, Status)) + { + if (pNetFlt->u.s.WinIf.hMiniport) + { + NdisMTransferDataComplete(pNetFlt->u.s.WinIf.hMiniport, + pPacket, + Status, + cbTransferred); + } + + vboxNetFltWinDereferenceWinIf(pNetFlt); + } + /* else - all processing is done with vboxNetFltWinPtTransferDataCompleteActive already */ + + LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), pPacket (0x%p), Status (0x%x), cbTransfered (%d)\n", pNetFlt, pPacket, Status, cbTransferred)); +} + +static INT vboxNetFltWinRecvPacketPassThru(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket, BOOLEAN bForceIndicate) +{ + Assert(KeGetCurrentIrql() == DISPATCH_LEVEL); + + PNDIS_PACKET pMyPacket; + NDIS_STATUS Status = vboxNetFltWinPrepareRecvPacket(pNetFlt, pPacket, &pMyPacket, true); + /* the Status holds the current packet status it will be checked for NDIS_STATUS_RESOURCES later + * (see below) */ + Assert(pMyPacket); + if (pMyPacket) + { + NdisMIndicateReceivePacket(pNetFlt->u.s.WinIf.hMiniport, &pMyPacket, 1); + if (Status == NDIS_STATUS_RESOURCES) + { + NdisDprFreePacket(pMyPacket); + return 0; + } + + return 1; + } + + return 0; +} + +/** + * process the packet receive in a "passthru" mode + */ +static NDIS_STATUS vboxNetFltWinRecvPassThru(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket) +{ + Assert(KeGetCurrentIrql() == DISPATCH_LEVEL); + + NDIS_STATUS Status; + PNDIS_PACKET pMyPacket; + + NdisDprAllocatePacket(&Status, &pMyPacket, pNetFlt->u.s.WinIf.hRecvPacketPool); + Assert(Status == NDIS_STATUS_SUCCESS); + if (Status == NDIS_STATUS_SUCCESS) + { + vboxNetFltWinCopyPacketInfoOnRecv(pMyPacket, pPacket, true /* force NDIS_STATUS_RESOURCES */); + Assert(NDIS_GET_PACKET_STATUS(pMyPacket) == NDIS_STATUS_RESOURCES); + + NdisMIndicateReceivePacket(pNetFlt->u.s.WinIf.hMiniport, &pMyPacket, 1); + + NdisDprFreePacket(pMyPacket); + } + return Status; +} + +static VOID vboxNetFltWinRecvIndicatePassThru(PVBOXNETFLTINS pNetFlt, NDIS_HANDLE MacReceiveContext, + PVOID pHeaderBuffer, UINT cbHeaderBuffer, PVOID pLookAheadBuffer, UINT cbLookAheadBuffer, UINT cbPacket) +{ + /* Note: we're using KeGetCurrentProcessorNumber, which is not entirely correct in case + * we're running on 64bit win7+, which can handle > 64 CPUs, however since KeGetCurrentProcessorNumber + * always returns the number < than the number of CPUs in the first group, we're guaranteed to have CPU index < 64 + * @todo: use KeGetCurrentProcessorNumberEx for Win7+ 64 and dynamically extended array */ + ULONG Proc = KeGetCurrentProcessorNumber(); + Assert(Proc < RT_ELEMENTS(pNetFlt->u.s.WinIf.abIndicateRxComplete)); + pNetFlt->u.s.WinIf.abIndicateRxComplete[Proc] = TRUE; + switch (pNetFlt->u.s.WinIf.enmMedium) + { + case NdisMedium802_3: + case NdisMediumWan: + NdisMEthIndicateReceive(pNetFlt->u.s.WinIf.hMiniport, + MacReceiveContext, + (PCHAR)pHeaderBuffer, + cbHeaderBuffer, + pLookAheadBuffer, + cbLookAheadBuffer, + cbPacket); + break; + default: + Assert(FALSE); + break; + } +} + +/** + * process the ProtocolReceive in an "active" mode + * + * @return NDIS_STATUS_SUCCESS - the packet is processed + * NDIS_STATUS_PENDING - the packet is being processed, we are waiting for the ProtocolTransferDataComplete to be called + * NDIS_STATUS_NOT_ACCEPTED - the packet is not needed - typically this is because this is a loopback packet + * NDIS_STATUS_FAILURE - packet processing failed + */ +static NDIS_STATUS vboxNetFltWinPtReceiveActive(PVBOXNETFLTINS pNetFlt, NDIS_HANDLE MacReceiveContext, PVOID pHeaderBuffer, UINT cbHeaderBuffer, + PVOID pLookaheadBuffer, UINT cbLookaheadBuffer, UINT cbPacket) +{ + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + + do + { + if (cbHeaderBuffer != VBOXNETFLT_PACKET_ETHEADER_SIZE) + { + Status = NDIS_STATUS_NOT_ACCEPTED; + break; + } + +#ifndef DEBUG_NETFLT_RECV_TRANSFERDATA + if (cbPacket == cbLookaheadBuffer) + { + PINTNETSG pSG; + PUCHAR pRcvData; +#ifndef VBOX_LOOPBACK_USEFLAGS + PNDIS_PACKET pLb; +#endif + + /* allocate SG buffer */ + Status = vboxNetFltWinAllocSG(cbPacket + cbHeaderBuffer, &pSG); + if (Status != NDIS_STATUS_SUCCESS) + { + Assert(0); + break; + } + + pRcvData = (PUCHAR)pSG->aSegs[0].pv; + + NdisMoveMappedMemory(pRcvData, pHeaderBuffer, cbHeaderBuffer); + + NdisCopyLookaheadData(pRcvData+cbHeaderBuffer, + pLookaheadBuffer, + cbLookaheadBuffer, + pNetFlt->u.s.WinIf.fMacOptions); +#ifndef VBOX_LOOPBACK_USEFLAGS + pLb = vboxNetFltWinLbSearchLoopBackBySG(pNetFlt, pSG, false); + if (pLb) + { +#ifndef DEBUG_NETFLT_RECV_NOPACKET + /* should not be here */ + Assert(0); +#endif + if (!vboxNetFltWinLbIsFromIntNet(pLb)) + { + PNDIS_PACKET pMyPacket; + pMyPacket = vboxNetFltWinNdisPacketFromSG(pNetFlt, /* PVBOXNETFLTINS */ + pSG, /* PINTNETSG */ + pSG, /* PVOID pBufToFree */ + false, /* bool bToWire */ + false); /* bool bCopyMemory */ + if (pMyPacket) + { + NdisMIndicateReceivePacket(pNetFlt->u.s.WinIf.hMiniport, &pMyPacket, 1); + /* dereference the NetFlt here & indicate SUCCESS, which would mean the caller would not do a dereference + * the WinIf dereference will be done on packet return */ + vboxNetFltWinDereferenceNetFlt(pNetFlt); + Status = NDIS_STATUS_SUCCESS; + } + else + { + vboxNetFltWinMemFree(pSG); + Status = NDIS_STATUS_FAILURE; + } + } + else + { + vboxNetFltWinMemFree(pSG); + Status = NDIS_STATUS_NOT_ACCEPTED; + } + break; + } +#endif + VBOXNETFLT_LBVERIFYSG(pNetFlt, pSG); + + /* enqueue SG */ +# ifdef VBOXNETFLT_NO_PACKET_QUEUE + if (vboxNetFltWinPostIntnet(pNetFlt, pSG, VBOXNETFLT_PACKET_SG)) + { + /* drop it */ + vboxNetFltWinMemFree(pSG); + vboxNetFltWinDereferenceWinIf(pNetFlt); + } + else + { + PNDIS_PACKET pMyPacket = vboxNetFltWinNdisPacketFromSG(pNetFlt, /* PVBOXNETFLTINS */ + pSG, /* PINTNETSG */ + pSG, /* PVOID pBufToFree */ + false, /* bool bToWire */ + false); /* bool bCopyMemory */ + Assert(pMyPacket); + if (pMyPacket) + { + NDIS_SET_PACKET_STATUS(pMyPacket, NDIS_STATUS_SUCCESS); + + DBG_CHECK_PACKET_AND_SG(pMyPacket, pSG); + + LogFlow(("non-ndis packet info, packet created (%p)\n", pMyPacket)); + NdisMIndicateReceivePacket(pNetFlt->u.s.WinIf.hMiniport, &pMyPacket, 1); + } + else + { + vboxNetFltWinDereferenceWinIf(pNetFlt); + Status = NDIS_STATUS_RESOURCES; + } + } + vboxNetFltWinDereferenceNetFlt(pNetFlt); +# else + Status = vboxNetFltWinQuEnqueuePacket(pNetFlt, pSG, PACKET_SG | PACKET_MINE); + if (Status != NDIS_STATUS_SUCCESS) + { + Assert(0); + vboxNetFltWinMemFree(pSG); + break; + } +# endif +#endif + } + else + { + PNDIS_PACKET pPacket; + PNDIS_BUFFER pTransferBuffer; + PNDIS_BUFFER pOrigBuffer; + PUCHAR pMemBuf; + UINT cbBuf = cbPacket + cbHeaderBuffer; + UINT cbTransferred; + + /* allocate NDIS Packet buffer */ + NdisAllocatePacket(&Status, &pPacket, pNetFlt->u.s.WinIf.hRecvPacketPool); + if (Status != NDIS_STATUS_SUCCESS) + { + Assert(0); + break; + } + + VBOXNETFLT_OOB_INIT(pPacket); + +#ifdef VBOX_LOOPBACK_USEFLAGS + /* set "don't loopback" flags */ + NdisGetPacketFlags(pPacket) = g_VBoxNetFltGlobalsWin.fPacketDontLoopBack; +#else + NdisGetPacketFlags(pPacket) = 0; +#endif + + Status = vboxNetFltWinMemAlloc((PVOID*)(&pMemBuf), cbBuf); + if (Status != NDIS_STATUS_SUCCESS) + { + Assert(0); + NdisFreePacket(pPacket); + break; + } + NdisAllocateBuffer(&Status, &pTransferBuffer, pNetFlt->u.s.WinIf.hRecvBufferPool, pMemBuf + cbHeaderBuffer, cbPacket); + if (Status != NDIS_STATUS_SUCCESS) + { + Assert(0); + Status = NDIS_STATUS_FAILURE; + NdisFreePacket(pPacket); + vboxNetFltWinMemFree(pMemBuf); + break; + } + + NdisAllocateBuffer(&Status, &pOrigBuffer, pNetFlt->u.s.WinIf.hRecvBufferPool, pMemBuf, cbBuf); + if (Status != NDIS_STATUS_SUCCESS) + { + Assert(0); + Status = NDIS_STATUS_FAILURE; + NdisFreeBuffer(pTransferBuffer); + NdisFreePacket(pPacket); + vboxNetFltWinMemFree(pMemBuf); + break; + } + + NdisChainBufferAtBack(pPacket, pTransferBuffer); + + NdisMoveMappedMemory(pMemBuf, pHeaderBuffer, cbHeaderBuffer); + + vboxNetFltWinPutPacketToList(&pNetFlt->u.s.WinIf.TransferDataList, pPacket, pOrigBuffer); + +#ifdef DEBUG_NETFLT_RECV_TRANSFERDATA + if (cbPacket == cbLookaheadBuffer) + { + NdisCopyLookaheadData(pMemBuf+cbHeaderBuffer, + pLookaheadBuffer, + cbLookaheadBuffer, + pNetFlt->u.s.WinIf.fMacOptions); + } + else +#endif + { + Assert(cbPacket > cbLookaheadBuffer); + + NdisTransferData(&Status, pNetFlt->u.s.WinIf.hBinding, MacReceiveContext, + 0, /* ByteOffset */ + cbPacket, pPacket, &cbTransferred); + } + + if (Status != NDIS_STATUS_PENDING) + { + vboxNetFltWinPtTransferDataComplete(pNetFlt, pPacket, Status, cbTransferred); + } + } + } while (0); + + return Status; +} + +static NDIS_STATUS vboxNetFltWinPtReceive(IN NDIS_HANDLE hProtocolBindingContext, + IN NDIS_HANDLE MacReceiveContext, + IN PVOID pHeaderBuffer, + IN UINT cbHeaderBuffer, + IN PVOID pLookAheadBuffer, + IN UINT cbLookAheadBuffer, + IN UINT cbPacket) +{ + PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext; + PNDIS_PACKET pPacket = NULL; + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + bool bNetFltActive; + bool fWinIfActive = vboxNetFltWinReferenceWinIfNetFlt(pNetFlt, &bNetFltActive); + const bool bPassThruActive = !bNetFltActive; + + LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt)); + + if (fWinIfActive) + { + do + { +#ifndef DEBUG_NETFLT_RECV_NOPACKET + pPacket = NdisGetReceivedPacket(pNetFlt->u.s.WinIf.hBinding, MacReceiveContext); + if (pPacket) + { +# ifndef VBOX_LOOPBACK_USEFLAGS + PNDIS_PACKET pLb = NULL; +# else + if (vboxNetFltWinIsLoopedBackPacket(pPacket)) + { + Assert(0); + /* nothing else to do here, just return the packet */ + //NdisReturnPackets(&pPacket, 1); + Status = NDIS_STATUS_NOT_ACCEPTED; + break; + } + + VBOXNETFLT_LBVERIFY(pNetFlt, pPacket); +# endif + + if (bNetFltActive) + { +# ifndef VBOX_LOOPBACK_USEFLAGS + pLb = vboxNetFltWinLbSearchLoopBack(pNetFlt, pPacket, false); + if (!pLb) +# endif + { + VBOXNETFLT_LBVERIFY(pNetFlt, pPacket); + +# ifdef VBOXNETFLT_NO_PACKET_QUEUE + if (vboxNetFltWinPostIntnet(pNetFlt, pPacket, 0)) + { + /* drop it */ + break; + } +# else + Status = vboxNetFltWinQuEnqueuePacket(pNetFlt, pPacket, PACKET_COPY); + Assert(Status == NDIS_STATUS_SUCCESS); + if (Status == NDIS_STATUS_SUCCESS) + { + //NdisReturnPackets(&pPacket, 1); + fWinIfActive = false; + bNetFltActive = false; + break; + } +# endif + } +# ifndef VBOX_LOOPBACK_USEFLAGS + else if (vboxNetFltWinLbIsFromIntNet(pLb)) + { + /* nothing else to do here, just return the packet */ + //NdisReturnPackets(&pPacket, 1); + Status = NDIS_STATUS_NOT_ACCEPTED; + break; + } + /* we are here because this is a looped back packet set not from intnet + * we will post it to the upper protocol */ +# endif + } + + Assert(Status == STATUS_SUCCESS); + if (Status == STATUS_SUCCESS) + { +# ifndef VBOX_LOOPBACK_USEFLAGS + Assert(!pLb || !vboxNetFltWinLbIsFromIntNet(pLb)); +# endif + Status = vboxNetFltWinRecvPassThru(pNetFlt, pPacket); + Assert(Status == STATUS_SUCCESS); + /* we are done with packet processing, and we will + * not receive packet return event for this packet, + * fWinIfActive should be true to ensure we release WinIf*/ + Assert(fWinIfActive); + if (Status == STATUS_SUCCESS) + break; + } + else + { + /* intnet processing failed - fall back to no-packet mode */ + Assert(bNetFltActive); + Assert(fWinIfActive); + } + + } +#endif /* #ifndef DEBUG_NETFLT_RECV_NOPACKET */ + + if (bNetFltActive) + { + Status = vboxNetFltWinPtReceiveActive(pNetFlt, MacReceiveContext, pHeaderBuffer, cbHeaderBuffer, + pLookAheadBuffer, cbLookAheadBuffer, cbPacket); + if (NT_SUCCESS(Status)) + { + if (Status != NDIS_STATUS_NOT_ACCEPTED) + { + fWinIfActive = false; + bNetFltActive = false; + } + else + { +#ifndef VBOX_LOOPBACK_USEFLAGS + /* this is a loopback packet, nothing to do here */ +#else + Assert(0); + /* should not be here */ +#endif + } + break; + } + } + + /* we are done with packet processing, and we will + * not receive packet return event for this packet, + * fWinIfActive should be true to ensure we release WinIf*/ + Assert(fWinIfActive); + + vboxNetFltWinRecvIndicatePassThru(pNetFlt, MacReceiveContext, pHeaderBuffer, cbHeaderBuffer, pLookAheadBuffer, cbLookAheadBuffer, cbPacket); + /* the status could contain an error value here in case the the IntNet recv failed, + * ensure we return back success status */ + Status = NDIS_STATUS_SUCCESS; + + } while (0); + + if (bNetFltActive) + { + vboxNetFltWinDereferenceNetFlt(pNetFlt); + } + else if (bPassThruActive) + { + vboxNetFltWinDereferenceModePassThru(pNetFlt); + } + if (fWinIfActive) + { + vboxNetFltWinDereferenceWinIf(pNetFlt); + } + } + else + { + Status = NDIS_STATUS_FAILURE; + } + + LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt)); + + return Status; + +} + +static VOID vboxNetFltWinPtReceiveComplete(NDIS_HANDLE hProtocolBindingContext) +{ + PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext; + ULONG cPackets = 0; + bool bNetFltActive; + bool fWinIfActive = vboxNetFltWinReferenceWinIfNetFlt(pNetFlt, &bNetFltActive); + NDIS_HANDLE hMiniport = pNetFlt->u.s.WinIf.hMiniport; + /* Note: we're using KeGetCurrentProcessorNumber, which is not entirely correct in case + * we're running on 64bit win7+, which can handle > 64 CPUs, however since KeGetCurrentProcessorNumber + * always returns the number < than the number of CPUs in the first group, we're guaranteed to have CPU index < 64 + * @todo: use KeGetCurrentProcessorNumberEx for Win7+ 64 and dynamically extended array */ + ULONG iProc = KeGetCurrentProcessorNumber(); + Assert(iProc < RT_ELEMENTS(pNetFlt->u.s.WinIf.abIndicateRxComplete)); + + LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt)); + + if (hMiniport != NULL && pNetFlt->u.s.WinIf.abIndicateRxComplete[iProc]) + { + switch (pNetFlt->u.s.WinIf.enmMedium) + { + case NdisMedium802_3: + case NdisMediumWan: + NdisMEthIndicateReceiveComplete(hMiniport); + break; + default: + Assert(0); + break; + } + } + + pNetFlt->u.s.WinIf.abIndicateRxComplete[iProc] = FALSE; + + if (fWinIfActive) + { + if (bNetFltActive) + { + vboxNetFltWinDereferenceNetFlt(pNetFlt); + } + else + { + vboxNetFltWinDereferenceModePassThru(pNetFlt); + } + vboxNetFltWinDereferenceWinIf(pNetFlt); + } + + LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt)); +} + +static INT vboxNetFltWinPtReceivePacket(NDIS_HANDLE hProtocolBindingContext, PNDIS_PACKET pPacket) +{ + PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext; + INT cRefCount = 0; + bool bNetFltActive; + bool fWinIfActive = vboxNetFltWinReferenceWinIfNetFlt(pNetFlt, &bNetFltActive); + const bool bPassThruActive = !bNetFltActive; + + LogFlow(("==>"__FUNCTION__" : pNetFlt (0x%p)\n", pNetFlt)); + + if (fWinIfActive) + { + do + { +#ifdef VBOX_LOOPBACK_USEFLAGS + if (vboxNetFltWinIsLoopedBackPacket(pPacket)) + { + Assert(0); + Log(("lb_rp")); + + /* nothing else to do here, just return the packet */ + cRefCount = 0; + //NdisReturnPackets(&pPacket, 1); + break; + } + + VBOXNETFLT_LBVERIFY(pNetFlt, pPacket); +#endif + + if (bNetFltActive) + { +#ifndef VBOX_LOOPBACK_USEFLAGS + PNDIS_PACKET pLb = vboxNetFltWinLbSearchLoopBack(pNetFlt, pPacket, false); + if (!pLb) +#endif + { +#ifndef VBOXNETFLT_NO_PACKET_QUEUE + NDIS_STATUS fStatus; +#endif + bool bResources = NDIS_GET_PACKET_STATUS(pPacket) == NDIS_STATUS_RESOURCES; + + VBOXNETFLT_LBVERIFY(pNetFlt, pPacket); +#ifdef DEBUG_misha + /*TODO: remove this assert. + * this is a temporary assert for debugging purposes: + * we're probably doing something wrong with the packets if the miniport reports NDIS_STATUS_RESOURCES */ + Assert(!bResources); +#endif + +#ifdef VBOXNETFLT_NO_PACKET_QUEUE + if (vboxNetFltWinPostIntnet(pNetFlt, pPacket, 0)) + { + /* drop it */ + cRefCount = 0; + break; + } + +#else + fStatus = vboxNetFltWinQuEnqueuePacket(pNetFlt, pPacket, bResources ? PACKET_COPY : 0); + if (fStatus == NDIS_STATUS_SUCCESS) + { + bNetFltActive = false; + fWinIfActive = false; + if (bResources) + { + cRefCount = 0; + //NdisReturnPackets(&pPacket, 1); + } + else + { + cRefCount = 1; + } + break; + } + else + { + Assert(0); + } +#endif + } +#ifndef VBOX_LOOPBACK_USEFLAGS + else if (vboxNetFltWinLbIsFromIntNet(pLb)) + { + /* the packet is from intnet, it has already been set to the host, + * no need for loopng it back to the host again */ + /* nothing else to do here, just return the packet */ + cRefCount = 0; + //NdisReturnPackets(&pPacket, 1); + break; + } +#endif + } + + cRefCount = vboxNetFltWinRecvPacketPassThru(pNetFlt, pPacket, bNetFltActive); + if (cRefCount) + { + Assert(cRefCount == 1); + fWinIfActive = false; + } + + } while (FALSE); + + if (bNetFltActive) + { + vboxNetFltWinDereferenceNetFlt(pNetFlt); + } + else if (bPassThruActive) + { + vboxNetFltWinDereferenceModePassThru(pNetFlt); + } + if (fWinIfActive) + { + vboxNetFltWinDereferenceWinIf(pNetFlt); + } + } + else + { + cRefCount = 0; + //NdisReturnPackets(&pPacket, 1); + } + + LogFlow(("<=="__FUNCTION__" : pNetFlt (0x%p), cRefCount (%d)\n", pNetFlt, cRefCount)); + + return cRefCount; +} + +DECLHIDDEN(bool) vboxNetFltWinPtCloseInterface(PVBOXNETFLTINS pNetFlt, PNDIS_STATUS pStatus) +{ + RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; + + RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp); + + if (pNetFlt->u.s.WinIf.StateFlags.fInterfaceClosing) + { + RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); + Assert(0); + return false; + } + if (pNetFlt->u.s.WinIf.hBinding == NULL) + { + RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); + Assert(0); + return false; + } + + pNetFlt->u.s.WinIf.StateFlags.fInterfaceClosing = TRUE; + RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); + + NdisResetEvent(&pNetFlt->u.s.WinIf.OpenCloseEvent); + NdisCloseAdapter(pStatus, pNetFlt->u.s.WinIf.hBinding); + if (*pStatus == NDIS_STATUS_PENDING) + { + NdisWaitEvent(&pNetFlt->u.s.WinIf.OpenCloseEvent, 0); + *pStatus = pNetFlt->u.s.WinIf.OpenCloseStatus; + } + + Assert (*pStatus == NDIS_STATUS_SUCCESS); + + pNetFlt->u.s.WinIf.hBinding = NULL; + + return true; +} + +static NDIS_STATUS vboxNetFltWinPtPnPSetPower(PVBOXNETFLTINS pNetFlt, NDIS_DEVICE_POWER_STATE enmPowerState) +{ + NDIS_DEVICE_POWER_STATE enmPrevPowerState = vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.PtState); + RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; + + RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp); + + vboxNetFltWinSetPowerState(&pNetFlt->u.s.WinIf.PtState, enmPowerState); + + if (vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.PtState) > NdisDeviceStateD0) + { + if (enmPrevPowerState == NdisDeviceStateD0) + { + pNetFlt->u.s.WinIf.StateFlags.fStandBy = TRUE; + } + RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); + vboxNetFltWinPtRequestsWaitComplete(pNetFlt); + vboxNetFltWinWaitDereference(&pNetFlt->u.s.WinIf.MpState); + vboxNetFltWinWaitDereference(&pNetFlt->u.s.WinIf.PtState); + + /* check packet pool is empty */ + UINT cPPUsage = NdisPacketPoolUsage(pNetFlt->u.s.WinIf.hSendPacketPool); + Assert(cPPUsage == 0); + cPPUsage = NdisPacketPoolUsage(pNetFlt->u.s.WinIf.hRecvPacketPool); + Assert(cPPUsage == 0); + /* for debugging only, ignore the err in release */ + NOREF(cPPUsage); + + Assert(!pNetFlt->u.s.WinIf.StateFlags.fRequestInfo); + } + else + { + if (enmPrevPowerState > NdisDeviceStateD0) + { + pNetFlt->u.s.WinIf.StateFlags.fStandBy = FALSE; + } + + if (pNetFlt->u.s.WinIf.StateFlags.fRequestInfo & VBOXNDISREQUEST_QUEUED) + { + pNetFlt->u.s.WinIf.StateFlags.fRequestInfo = VBOXNDISREQUEST_INPROGRESS; + RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); + + vboxNetFltWinMpRequestPost(pNetFlt); + } + else + { + RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); + } + } + + return NDIS_STATUS_SUCCESS; +} + + +static NDIS_STATUS vboxNetFltWinPtPnPEvent(IN NDIS_HANDLE hProtocolBindingContext, IN PNET_PNP_EVENT pNetPnPEvent) +{ + PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hProtocolBindingContext; + + LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p), NetEvent (%d)\n", pNetFlt, pNetPnPEvent->NetEvent)); + + switch (pNetPnPEvent->NetEvent) + { + case NetEventSetPower: + { + NDIS_DEVICE_POWER_STATE enmPowerState = *((PNDIS_DEVICE_POWER_STATE)pNetPnPEvent->Buffer); + return vboxNetFltWinPtPnPSetPower(pNetFlt, enmPowerState); + } + case NetEventReconfigure: + { + if (!pNetFlt) + { + NdisReEnumerateProtocolBindings(g_VBoxNetFltGlobalsWin.Pt.hProtocol); + } + } + default: + return NDIS_STATUS_SUCCESS; + } + + LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), NetEvent (%d)\n", pNetFlt, pNetPnPEvent->NetEvent)); +} + +#ifdef __cplusplus +# define PTCHARS_40(_p) ((_p).Ndis40Chars) +#else +# define PTCHARS_40(_p) (_p) +#endif + +/** + * register the protocol edge + */ +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtRegister(PVBOXNETFLTGLOBALS_PT pGlobalsPt, PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPathStr) +{ + NDIS_PROTOCOL_CHARACTERISTICS PtChars; + NDIS_STRING NameStr; + + NdisInitUnicodeString(&NameStr, VBOXNETFLT_NAME_PROTOCOL); + + NdisZeroMemory(&PtChars, sizeof (PtChars)); + PTCHARS_40(PtChars).MajorNdisVersion = VBOXNETFLT_VERSION_PT_NDIS_MAJOR; + PTCHARS_40(PtChars).MinorNdisVersion = VBOXNETFLT_VERSION_PT_NDIS_MINOR; + + PTCHARS_40(PtChars).Name = NameStr; + PTCHARS_40(PtChars).OpenAdapterCompleteHandler = vboxNetFltWinPtOpenAdapterComplete; + PTCHARS_40(PtChars).CloseAdapterCompleteHandler = vboxNetFltWinPtCloseAdapterComplete; + PTCHARS_40(PtChars).SendCompleteHandler = vboxNetFltWinPtSendComplete; + PTCHARS_40(PtChars).TransferDataCompleteHandler = vboxNetFltWinPtTransferDataComplete; + PTCHARS_40(PtChars).ResetCompleteHandler = vboxNetFltWinPtResetComplete; + PTCHARS_40(PtChars).RequestCompleteHandler = vboxNetFltWinPtRequestComplete; + PTCHARS_40(PtChars).ReceiveHandler = vboxNetFltWinPtReceive; + PTCHARS_40(PtChars).ReceiveCompleteHandler = vboxNetFltWinPtReceiveComplete; + PTCHARS_40(PtChars).StatusHandler = vboxNetFltWinPtStatus; + PTCHARS_40(PtChars).StatusCompleteHandler = vboxNetFltWinPtStatusComplete; + PTCHARS_40(PtChars).BindAdapterHandler = vboxNetFltWinPtBindAdapter; + PTCHARS_40(PtChars).UnbindAdapterHandler = vboxNetFltWinPtUnbindAdapter; + PTCHARS_40(PtChars).UnloadHandler = vboxNetFltWinPtUnloadProtocol; +#if !defined(DEBUG_NETFLT_RECV) + PTCHARS_40(PtChars).ReceivePacketHandler = vboxNetFltWinPtReceivePacket; +#endif + PTCHARS_40(PtChars).PnPEventHandler = vboxNetFltWinPtPnPEvent; + + NDIS_STATUS Status; + NdisRegisterProtocol(&Status, &pGlobalsPt->hProtocol, &PtChars, sizeof (PtChars)); + Assert(Status == STATUS_SUCCESS); + return Status; +} + +/** + * deregister the protocol edge + */ +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtDeregister(PVBOXNETFLTGLOBALS_PT pGlobalsPt) +{ + if (!pGlobalsPt->hProtocol) + return NDIS_STATUS_SUCCESS; + + NDIS_STATUS Status; + + NdisDeregisterProtocol(&Status, pGlobalsPt->hProtocol); + Assert (Status == NDIS_STATUS_SUCCESS); + if (Status == NDIS_STATUS_SUCCESS) + { + NdisZeroMemory(pGlobalsPt, sizeof (*pGlobalsPt)); + } + return Status; +} diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltP-win.h b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltP-win.h new file mode 100644 index 000000000..63e8f102b --- /dev/null +++ b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltP-win.h @@ -0,0 +1,29 @@ +/* $Id: VBoxNetFltP-win.h 36184 2011-03-07 10:57:04Z vboxsync $ */ +/** @file + * VBoxNetFltP-win.h - Bridged Networking Driver, Windows Specific Code. + * Protocol edge API + */ +/* + * Copyright (C) 2011 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + */ +#ifndef ___VBoxNetFltP_win_h___ +#define ___VBoxNetFltP_win_h___ + +#ifdef VBOXNETADP +# error "No protocol edge" +#endif +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtRegister(PVBOXNETFLTGLOBALS_PT pGlobalsPt, PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPathStr); +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtDeregister(PVBOXNETFLTGLOBALS_PT pGlobalsPt); +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtDoUnbinding(PVBOXNETFLTINS pNetFlt, bool bOnUnbind); +DECLHIDDEN(VOID) vboxNetFltWinPtRequestComplete(NDIS_HANDLE hContext, PNDIS_REQUEST pNdisRequest, NDIS_STATUS Status); +DECLHIDDEN(bool) vboxNetFltWinPtCloseInterface(PVBOXNETFLTINS pNetFlt, PNDIS_STATUS pStatus); +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtDoBinding(PVBOXNETFLTINS pThis, PNDIS_STRING pOurDeviceName, PNDIS_STRING pBindToDeviceName); +#endif /* #ifndef ___VBoxNetFltP_win_h___ */ diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.c b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltRt-win.cpp index 02f1651ba..7175be6b3 100644 --- a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.c +++ b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltRt-win.cpp @@ -1,10 +1,10 @@ -/* $Id: VBoxNetFlt-win.c $ */ +/* $Id: VBoxNetFltRt-win.cpp 37161 2011-05-20 07:28:21Z vboxsync $ */ /** @file - * VBoxNetFlt - Network Filter Driver (Host), Windows Specific Code. Integration with IntNet/NetFlt + * VBoxNetFltRt-win.cpp - Bridged Networking Driver, Windows Specific Code. + * NetFlt Runtime */ - /* - * Copyright (C) 2008 Oracle Corporation + * Copyright (C) 2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -14,30 +14,25 @@ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. */ -/* - * Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample. - * Copyright (c) 1993-1999, Microsoft Corporation - */ - -#include "VBoxNetFltCommon-win.h" +#include "VBoxNetFltCmn-win.h" #include <VBox/intnetinline.h> #include <iprt/thread.h> /** represents the job element of the job queue - * see comments for JOB_QUEUE */ -typedef struct _JOB + * see comments for VBOXNETFLT_JOB_QUEUE */ +typedef struct VBOXNETFLT_JOB { /** link in the job queue */ LIST_ENTRY ListEntry; /** job function to be executed */ - JOB_ROUTINE pRoutine; + PFNVBOXNETFLT_JOB_ROUTINE pfnRoutine; /** parameter to be passed to the job function */ PVOID pContext; /** event that will be fired on job completion */ KEVENT CompletionEvent; /** true if the job manager should use the completion even for completion indication, false-otherwise*/ bool bUseCompletionEvent; -} JOB, *PJOB; +} VBOXNETFLT_JOB, *PVBOXNETFLT_JOB; /** * represents the queue of jobs processed by the worker thread @@ -46,7 +41,7 @@ typedef struct _JOB * our callbacks may be called at APC level by IntNet, there are some tasks that we can not create at APC, * e.g. thread creation. This is why we schedule such jobs to the worker thread working at passive level */ -typedef struct _JOB_QUEUE +typedef struct VBOXNETFLT_JOB_QUEUE { /* jobs */ LIST_ENTRY Jobs; @@ -58,7 +53,7 @@ typedef struct _JOB_QUEUE KEVENT NotifyEvent; /** worker thread */ PKTHREAD pThread; -} JOB_QUEUE, *PJOB_QUEUE; +} VBOXNETFLT_JOB_QUEUE, *PVBOXNETFLT_JOB_QUEUE; typedef struct _CREATE_INSTANCE_CONTEXT { @@ -69,7 +64,7 @@ typedef struct _CREATE_INSTANCE_CONTEXT NDIS_HANDLE hMiniportAdapter; NDIS_HANDLE hWrapperConfigurationContext; #endif - NDIS_STATUS Status; + NDIS_STATUS Status; }CREATE_INSTANCE_CONTEXT, *PCREATE_INSTANCE_CONTEXT; /*contexts used for our jobs */ @@ -92,33 +87,29 @@ typedef struct _WORKER_INFO /* idc initialization */ typedef struct _INIT_IDC_INFO { - JOB Job; - bool bInitialized; - volatile bool bStop; + VBOXNETFLT_JOB Job; + bool bInitialized; + volatile bool bStop; volatile int rc; KEVENT hCompletionEvent; }INIT_IDC_INFO, *PINIT_IDC_INFO; /** globals */ - -/** global lock */ -NDIS_SPIN_LOCK g_GlobalLock; /** global job queue. some operations are required to be done at passive level, e.g. thread creation, adapter bind/unbind initiation, * while IntNet typically calls us APC_LEVEL, so we just create a system thread in our DriverEntry and enqueue the jobs to that thread */ -static JOB_QUEUE g_JobQueue; +static VBOXNETFLT_JOB_QUEUE g_VBoxJobQueue; +volatile static bool g_bVBoxIdcInitialized; +INIT_IDC_INFO g_VBoxInitIdcInfo; /** * The (common) global data. */ static VBOXNETFLTGLOBALS g_VBoxNetFltGlobals; -volatile static bool g_bIdcInitialized; -INIT_IDC_INFO g_InitIdcInfo; - -UINT g_fPacketDontLoopBack; -UINT g_fPacketIsLoopedBack; +/* win-specific global data */ +VBOXNETFLTGLOBALS_WIN g_VBoxNetFltGlobalsWin = {0}; #define LIST_ENTRY_2_JOB(pListEntry) \ - ( (PJOB)((uint8_t *)(pListEntry) - RT_OFFSETOF(JOB, ListEntry)) ) + ( (PVBOXNETFLT_JOB)((uint8_t *)(pListEntry) - RT_OFFSETOF(VBOXNETFLT_JOB, ListEntry)) ) static int vboxNetFltWinAttachToInterface(PVBOXNETFLTINS pThis, void * pContext, bool fRediscovery); static int vboxNetFltWinConnectIt(PVBOXNETFLTINS pThis); @@ -136,7 +127,7 @@ DECLHIDDEN(void) vboxNetFltWinSleep(ULONG milis) } /** wait for the given device to be dereferenced */ -DECLHIDDEN(void) vboxNetFltWinWaitDereference(PADAPT_DEVICE pState) +DECLHIDDEN(void) vboxNetFltWinWaitDereference(PVBOXNETFLT_WINIF_DEVICE pState) { #ifdef DEBUG uint64_t StartNanoTS = RTTimeSystemNanoTS(); @@ -149,9 +140,9 @@ DECLHIDDEN(void) vboxNetFltWinWaitDereference(PADAPT_DEVICE pState) vboxNetFltWinSleep(2); #ifdef DEBUG CurNanoTS = RTTimeSystemNanoTS(); - if(CurNanoTS - StartNanoTS > 20000000) + if (CurNanoTS - StartNanoTS > 20000000) { - DBGPRINT(("device not idle")); + LogRel(("device not idle")); AssertFailed(); // break; } @@ -166,16 +157,16 @@ DECLHIDDEN(void) vboxNetFltWinWaitDereference(PADAPT_DEVICE pState) DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMemAlloc(PVOID* ppMemBuf, UINT cbLength) { #ifdef DEBUG_NETFLT_USE_EXALLOC - *ppMemBuf = ExAllocatePoolWithTag(NonPagedPool, cbLength, MEM_TAG); - if(*ppMemBuf) + *ppMemBuf = ExAllocatePoolWithTag(NonPagedPool, cbLength, VBOXNETFLT_MEM_TAG); + if (*ppMemBuf) { NdisZeroMemory(*ppMemBuf, cbLength); return NDIS_STATUS_SUCCESS; } return NDIS_STATUS_FAILURE; #else - NDIS_STATUS fStatus = NdisAllocateMemoryWithTag(ppMemBuf, cbLength, MEM_TAG); - if(fStatus == NDIS_STATUS_SUCCESS) + NDIS_STATUS fStatus = NdisAllocateMemoryWithTag(ppMemBuf, cbLength, VBOXNETFLT_MEM_TAG); + if (fStatus == NDIS_STATUS_SUCCESS) { NdisZeroMemory(*ppMemBuf, cbLength); } @@ -193,58 +184,10 @@ DECLHIDDEN(void) vboxNetFltWinMemFree(PVOID pvMemBuf) #endif } -/* frees ndis buffers used on send/receive */ -static VOID vboxNetFltWinFiniBuffers(PADAPT pAdapt) -{ - /* NOTE: don't check for NULL since NULL is a valid handle */ -#ifndef VBOXNETADP - NdisFreeBufferPool(pAdapt->hSendBufferPoolHandle); -#endif -#ifndef VBOX_NETFLT_ONDEMAND_BIND - NdisFreeBufferPool(pAdapt->hRecvBufferPoolHandle); -#endif -} - -/* initializes ndis buffers used on send/receive */ -static NDIS_STATUS vboxNetFltWinInitBuffers(PADAPT pAdapt) -{ - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - - do - { - /* NOTE: NULL is a valid handle !!! */ -#ifndef VBOXNETADP - NdisAllocateBufferPool(&Status, - &pAdapt->hSendBufferPoolHandle, - TX_BUFFER_POOL_SIZE); - Assert(Status == NDIS_STATUS_SUCCESS); - if (Status != NDIS_STATUS_SUCCESS) - { - break; - } -#endif - -#ifndef VBOX_NETFLT_ONDEMAND_BIND - /* NOTE: NULL is a valid handle !!! */ - NdisAllocateBufferPool(&Status, - &pAdapt->hRecvBufferPoolHandle, - RX_BUFFER_POOL_SIZE); - Assert(Status == NDIS_STATUS_SUCCESS); - if (Status != NDIS_STATUS_SUCCESS) - { -#ifndef VBOXNETADP - NdisFreeBufferPool(pAdapt->hSendBufferPoolHandle); -#endif - break; - } -#endif - } while (FALSE); - - return Status; -} +#ifndef VBOXNETFLT_NO_PACKET_QUEUE /* initializes packet info pool and allocates the cSize packet infos for the pool */ -static NDIS_STATUS vboxNetFltWinPpAllocatePacketInfoPool(PPACKET_INFO_POOL pPool, UINT cSize) +static NDIS_STATUS vboxNetFltWinPpAllocatePacketInfoPool(PVBOXNETFLT_PACKET_INFO_POOL pPool, UINT cSize) { UINT cbBufSize = sizeof(PACKET_INFO)*cSize; PACKET_INFO * pPacketInfos; @@ -257,12 +200,12 @@ static NDIS_STATUS vboxNetFltWinPpAllocatePacketInfoPool(PPACKET_INFO_POOL pPool fStatus = vboxNetFltWinMemAlloc((PVOID*)&pPacketInfos, cbBufSize); - if(fStatus == NDIS_STATUS_SUCCESS) + if (fStatus == NDIS_STATUS_SUCCESS) { - PPACKET_INFO pInfo; + PVBOXNETFLTPACKET_INFO pInfo; pPool->pBuffer = pPacketInfos; - for(i = 0; i < cSize; i++) + for (i = 0; i < cSize; i++) { pInfo = &pPacketInfos[i]; vboxNetFltWinQuEnqueueTail(&pPool->Queue.Queue, pInfo); @@ -278,13 +221,15 @@ static NDIS_STATUS vboxNetFltWinPpAllocatePacketInfoPool(PPACKET_INFO_POOL pPool } /* frees the packet info pool */ -VOID vboxNetFltWinPpFreePacketInfoPool(PPACKET_INFO_POOL pPool) +VOID vboxNetFltWinPpFreePacketInfoPool(PVBOXNETFLT_PACKET_INFO_POOL pPool) { vboxNetFltWinMemFree(pPool->pBuffer); FINI_INTERLOCKED_PACKET_QUEUE(&pPool->Queue) } +#endif + /** * copies one string to another. in case the destination string size is not enough to hold the complete source string * does nothing and returns NDIS_STATUS_RESOURCES . @@ -293,9 +238,9 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinCopyString(PNDIS_STRING pDst, PNDIS_STRING { NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - if(pDst != pSrc) + if (pDst != pSrc) { - if(pDst->MaximumLength < pSrc->Length) + if (pDst->MaximumLength < pSrc->Length) { AssertFailed(); Status = NDIS_STATUS_RESOURCES; @@ -304,7 +249,7 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinCopyString(PNDIS_STRING pDst, PNDIS_STRING { pDst->Length = pSrc->Length; - if(pDst->Buffer != pSrc->Buffer) + if (pDst->Buffer != pSrc->Buffer) { NdisMoveMemory(pDst->Buffer, pSrc->Buffer, pSrc->Length); } @@ -339,15 +284,11 @@ static NDIS_STATUS vboxNetFltWinNdisBufferMoveToSG0(PNDIS_BUFFER pBuffer, PINTNE Assert(paSeg->pv); - while(pBuffer) + while (pBuffer) { - NdisQueryBufferSafe( - pBuffer, - &pVirtualAddress, - &cbCurrentLength, - NormalPagePriority); + NdisQueryBufferSafe(pBuffer, &pVirtualAddress, &cbCurrentLength, NormalPagePriority); - if(!pVirtualAddress) + if (!pVirtualAddress) { fStatus = NDIS_STATUS_FAILURE; break; @@ -358,15 +299,13 @@ static NDIS_STATUS vboxNetFltWinNdisBufferMoveToSG0(PNDIS_BUFFER pBuffer, PINTNE NdisMoveMemory(ptr, pVirtualAddress, cbCurrentLength); ptr += cbCurrentLength; - NdisGetNextBuffer( - pBuffer, - &pBuffer); + NdisGetNextBuffer(pBuffer, &pBuffer); } - if(fStatus == NDIS_STATUS_SUCCESS) + if (fStatus == NDIS_STATUS_SUCCESS) { pSG->cSegsUsed = 1; - Assert(pSG->cbTotal == paSeg->cb); + Assert(pSG->cbTotal == paSeg->cb); } return fStatus; } @@ -376,21 +315,18 @@ static NDIS_STATUS vboxNetFltWinNdisBufferMoveToSG0(PNDIS_BUFFER pBuffer, PINTNE static NDIS_STATUS vboxNetFltWinNdisBuffersToSG(PNDIS_BUFFER pBuffer, PINTNETSG pSG) { UINT cSegs = 0; - NDIS_STATUS fStatus = NDIS_STATUS_SUCCESS; + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; PVOID pVirtualAddress; UINT cbCurrentLength; - while(pBuffer) + while (pBuffer) { - NdisQueryBufferSafe( - pBuffer, - &pVirtualAddress, - &cbCurrentLength, - NormalPagePriority); + NdisQueryBufferSafe(pBuffer, &pVirtualAddress, &cbCurrentLength, NormalPagePriority); - if(!pVirtualAddress) { - fStatus = NDIS_STATUS_FAILURE; - break; + if (!pVirtualAddress) + { + Status = NDIS_STATUS_FAILURE; + break; } pSG->cbTotal += cbCurrentLength; @@ -399,19 +335,17 @@ static NDIS_STATUS vboxNetFltWinNdisBuffersToSG(PNDIS_BUFFER pBuffer, PINTNETSG pSG->aSegs[cSegs].Phys = NIL_RTHCPHYS; cSegs++; - NdisGetNextBuffer( - pBuffer, - &pBuffer); + NdisGetNextBuffer(pBuffer, &pBuffer); } AssertFatal(cSegs <= pSG->cSegsAlloc); - if(fStatus == NDIS_STATUS_SUCCESS) + if (Status == NDIS_STATUS_SUCCESS) { pSG->cSegsUsed = cSegs; } - return fStatus; + return Status; } static void vboxNetFltWinDeleteSG(PINTNETSG pSG) @@ -423,7 +357,7 @@ static PINTNETSG vboxNetFltWinCreateSG(uint32_t cSegs) { PINTNETSG pSG; NTSTATUS Status = vboxNetFltWinMemAlloc((PVOID*)&pSG, RT_OFFSETOF(INTNETSG, aSegs[cSegs])); - if(Status == STATUS_SUCCESS) + if (Status == STATUS_SUCCESS) { IntNetSgInitTempSegs(pSG, 0 /*cbTotal*/, cSegs, 0 /*cSegsUsed*/); return pSG; @@ -436,23 +370,23 @@ static PINTNETSG vboxNetFltWinCreateSG(uint32_t cSegs) * packet queue functions ************************************************************************************/ #ifndef VBOXNETFLT_NO_PACKET_QUEUE -#if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP) -static NDIS_STATUS vboxNetFltWinQuPostPacket(PADAPT pAdapt, PNDIS_PACKET pPacket, PINTNETSG pSG, uint32_t fFlags +#if !defined(VBOXNETADP) +static NDIS_STATUS vboxNetFltWinQuPostPacket(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket, PINTNETSG pSG, uint32_t fFlags # ifdef DEBUG_NETFLT_PACKETS , PNDIS_PACKET pTmpPacket # endif ) { - NDIS_STATUS fStatus; + NDIS_STATUS Status; PNDIS_PACKET pMyPacket; bool bSrcHost = fFlags & PACKET_SRC_HOST; LogFlow(("posting packet back to driver stack..\n")); - if(!pPacket) + if (!pPacket) { /* INTNETSG was in the packet queue, create a new NdisPacket from INTNETSG*/ - pMyPacket = vboxNetFltWinNdisPacketFromSG(pAdapt, /* PADAPT */ + pMyPacket = vboxNetFltWinNdisPacketFromSG(pNetFlt, pSG, /* PINTNETSG */ pSG, /* PVOID pBufToFree */ bSrcHost, /* bool bToWire */ @@ -479,20 +413,20 @@ static NDIS_STATUS vboxNetFltWinQuPostPacket(PADAPT pAdapt, PNDIS_PACKET pPacket /* NDIS_PACKET was in the packet queue */ DBG_CHECK_PACKET_AND_SG(pPacket, pSG); - if(!(fFlags & PACKET_MINE)) + if (!(fFlags & PACKET_MINE)) { /* the packet is the one that was passed to us in send/receive callback * According to the DDK, we can not post it further, * instead we should allocate our own packet. * So, allocate our own packet (pMyPacket) and copy the packet info there */ - if(bSrcHost) + if (bSrcHost) { - fStatus = vboxNetFltWinPrepareSendPacket(pAdapt, pPacket, &pMyPacket/*, true*/); + Status = vboxNetFltWinPrepareSendPacket(pNetFlt, pPacket, &pMyPacket/*, true*/); LogFlow(("packet from wire, packet created (%p)\n", pMyPacket)); } else { - fStatus = vboxNetFltWinPrepareRecvPacket(pAdapt, pPacket, &pMyPacket, false); + Status = vboxNetFltWinPrepareRecvPacket(pNetFlt, pPacket, &pMyPacket, false); LogFlow(("packet from wire, packet created (%p)\n", pMyPacket)); } } @@ -508,26 +442,26 @@ static NDIS_STATUS vboxNetFltWinQuPostPacket(PADAPT pAdapt, PNDIS_PACKET pPacket if (pMyPacket) { /* we have successfully initialized our packet, post it to the host or to the wire */ - if(bSrcHost) + if (bSrcHost) { #if defined(DEBUG_NETFLT_PACKETS) || !defined(VBOX_LOOPBACK_USEFLAGS) - vboxNetFltWinLbPutSendPacket(pAdapt, pMyPacket, false /* bFromIntNet */); + vboxNetFltWinLbPutSendPacket(pNetFlt, pMyPacket, false /* bFromIntNet */); #endif - NdisSend(&fStatus, pAdapt->hBindingHandle, pMyPacket); + NdisSend(&Status, pNetFlt->u.s.hBinding, pMyPacket); - if (fStatus != NDIS_STATUS_PENDING) + if (Status != NDIS_STATUS_PENDING) { #if defined(DEBUG_NETFLT_PACKETS) || !defined(VBOX_LOOPBACK_USEFLAGS) /* the status is NOT pending, complete the packet */ - bool bTmp = vboxNetFltWinLbRemoveSendPacket(pAdapt, pMyPacket); + bool bTmp = vboxNetFltWinLbRemoveSendPacket(pNetFlt, pMyPacket); Assert(bTmp); #endif - if(pPacket) + if (pPacket) { LogFlow(("status is not pending, completing packet (%p)\n", pPacket)); -#ifndef WIN9X + NdisIMCopySendCompletePerPacketInfo (pPacket, pMyPacket); -#endif + NdisFreePacket(pMyPacket); } else @@ -543,9 +477,9 @@ static NDIS_STATUS vboxNetFltWinQuPostPacket(PADAPT pAdapt, PNDIS_PACKET pPacket } else { - NdisMIndicateReceivePacket(pAdapt->hMiniportHandle, &pMyPacket, 1); + NdisMIndicateReceivePacket(pNetFlt->u.s.hMiniport, &pMyPacket, 1); - fStatus = NDIS_STATUS_PENDING; + Status = NDIS_STATUS_PENDING; /* the packet receive completion is always indicated via MiniportReturnPacket */ } } @@ -553,10 +487,10 @@ static NDIS_STATUS vboxNetFltWinQuPostPacket(PADAPT pAdapt, PNDIS_PACKET pPacket { /*we failed to create our packet */ AssertFailed(); - fStatus = NDIS_STATUS_FAILURE; + Status = NDIS_STATUS_FAILURE; } - return fStatus; + return Status; } #endif @@ -567,7 +501,6 @@ DECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pNetFltIf, PVOID pvPacke { PNDIS_PACKET pPacket = NULL; PINTNETSG pSG = NULL; - PADAPT pAdapt = PVBOXNETFLTINS_2_PADAPT(pNetFltIf); NDIS_STATUS Status; #ifndef VBOXNETADP bool bSrcHost; @@ -585,7 +518,7 @@ DECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pNetFltIf, PVOID pvPacke #endif #ifndef VBOXNETADP - bSrcHost = (fFlags & PACKET_SRC_HOST) != 0; + bSrcHost = (fFlags & VBOXNETFLT_PACKET_SRC_HOST) != 0; #endif /* we first need to obtain the INTNETSG to be passed to intnet */ @@ -596,33 +529,27 @@ DECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pNetFltIf, PVOID pvPacke * however in case our ProtocolReceive is called or the packet's status is set to NDIS_STSTUS_RESOURCES * in ProtocolReceivePacket, we must return the packet immediately on ProtocolReceive*** exit * In this case we allocate the INTNETSG, copy the ndis packet data there and enqueue it. - * In this case the packet info flags has the PACKET_SG fag set + * In this case the packet info flags has the VBOXNETFLT_PACKET_SG fag set * * Besides that the NDIS_PACKET contained in the queue could be either the one passed to us in our send/receive callback * or the one created by us. The latter is possible in case our ProtocolReceive callback is called and we call NdisTransferData * in this case we need to allocate the packet the data to be transferred to. - * If the enqueued packet is the one allocated by us the PACKET_MINE flag is set + * If the enqueued packet is the one allocated by us the VBOXNETFLT_PACKET_MINE flag is set * */ - if((fFlags & PACKET_SG) == 0) + if ((fFlags & VBOXNETFLT_PACKET_SG) == 0) { /* we have NDIS_PACKET enqueued, we need to convert it to INTNETSG to be passed to intnet */ - PNDIS_BUFFER pCurrentBuffer = NULL; - UINT cBufferCount; - UINT uBytesCopied = 0; - UINT cbPacketLength; + PNDIS_BUFFER pCurrentBuffer = NULL; + UINT cBufferCount; + UINT uBytesCopied = 0; + UINT cbPacketLength; pPacket = (PNDIS_PACKET)pvPacket; LogFlow(("ndis packet info, packet (%p)\n", pPacket)); LogFlow(("preparing pSG")); - NdisQueryPacket(pPacket, - NULL, - &cBufferCount, - &pCurrentBuffer, - &cbPacketLength); - - + NdisQueryPacket(pPacket, NULL, &cBufferCount, &pCurrentBuffer, &cbPacketLength); Assert(cBufferCount); #ifdef VBOXNETFLT_NO_PACKET_QUEUE @@ -632,13 +559,13 @@ DECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pNetFltIf, PVOID pvPacke * somewhere outside of our driver (3 pages of system thread stack does not seem to be enough) * * since we have a "serialized" packet processing, i.e. all packets are being processed and passed - * to intnet by this thread, we just use one previously allocated INTNETSG which is stored in PADAPT */ + * to intnet by this thread, we just use one previously allocated INTNETSG which is stored in PVBOXNETFLTINS */ pSG = pWorker->pSG; - if(cBufferCount > pSG->cSegsAlloc) + if (cBufferCount > pSG->cSegsAlloc) { pSG = vboxNetFltWinCreateSG(cBufferCount + 2); - if(pSG) + if (pSG) { vboxNetFltWinDeleteSG(pWorker->pSG); pWorker->pSG = pSG; @@ -650,7 +577,7 @@ DECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pNetFltIf, PVOID pvPacke } #endif - if(pSG) + if (pSG) { #ifdef VBOXNETFLT_NO_PACKET_QUEUE bDeleteSG = true; @@ -660,7 +587,7 @@ DECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pNetFltIf, PVOID pvPacke /* convert the ndis buffers to INTNETSG */ Status = vboxNetFltWinNdisBuffersToSG(pCurrentBuffer, pSG); - if(Status != NDIS_STATUS_SUCCESS) + if (Status != NDIS_STATUS_SUCCESS) { pSG = NULL; } @@ -674,15 +601,11 @@ DECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pNetFltIf, PVOID pvPacke { /* we have the INTNETSG enqueued. (see the above comment explaining why/when this may happen) * just use the INTNETSG to pass it to intnet */ -#ifndef VBOX_NETFLT_ONDEMAND_BIND - #ifndef VBOXNETADP +#ifndef VBOXNETADP /* the PINTNETSG is stored only when the underlying miniport * indicates NDIS_STATUS_RESOURCES, we should never have this when processing * the "from-host" packedts */ Assert(!bSrcHost); - #endif -#else - /* we have both host and wire in ProtocolReceive */ #endif pSG = (PINTNETSG)pvPacket; @@ -690,10 +613,10 @@ DECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pNetFltIf, PVOID pvPacke } #ifdef DEBUG_NETFLT_PACKETS - if(!pPacket && !pTmpPacket) + if (!pPacket && !pTmpPacket) { /* create tmp packet that woud be used for matching */ - pTmpPacket = vboxNetFltWinNdisPacketFromSG(pAdapt, /* PADAPT */ + pTmpPacket = vboxNetFltWinNdisPacketFromSG(pNetFltIf, pSG, /* PINTNETSG */ pSG, /* PVOID pBufToFree */ bSrcHost, /* bool bToWire */ @@ -710,37 +633,34 @@ DECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pNetFltIf, PVOID pvPacke { #ifndef VBOXNETADP /* the pSG was successfully initialized, post it to the netFlt*/ -#ifndef VBOX_NETFLT_ONDEMAND_BIND - bDropIt = -#endif - pSG ? pNetFltIf->pSwitchPort->pfnRecv(pNetFltIf->pSwitchPort, NULL /* pvIf */, pSG, + bDropIt = pSG ? pNetFltIf->pSwitchPort->pfnRecv(pNetFltIf->pSwitchPort, NULL /* pvIf */, pSG, bSrcHost ? INTNETTRUNKDIR_HOST : INTNETTRUNKDIR_WIRE ) : false; #else - if(pSG) + if (pSG) { pNetFltIf->pSwitchPort->pfnRecv(pNetFltIf->pSwitchPort, NULL /* pvIf */, pSG, INTNETTRUNKDIR_HOST); - STATISTIC_INCREASE(pAdapt->cTxSuccess); + STATISTIC_INCREASE(pNetFltIf->u.s.WinIf.cTxSuccess); } else { - STATISTIC_INCREASE(pAdapt->cTxError); + STATISTIC_INCREASE(pNetFltIf->u.s.WinIf.cTxError); } #endif #ifndef VBOXNETFLT_NO_PACKET_QUEUE -# if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP) - if(!bDropIt) +# if !defined(VBOXNETADP) + if (!bDropIt) { - Status = vboxNetFltWinQuPostPacket(pAdapt, pPacket, pSG, fFlags + Status = vboxNetFltWinQuPostPacket(pNetFltIf, pPacket, pSG, fFlags # ifdef DEBUG_NETFLT_PACKETS , pTmpPacket # endif ); - if(Status == NDIS_STATUS_PENDING) + if (Status == NDIS_STATUS_PENDING) { /* we will process packet completion in the completion routine */ bPending = true; @@ -754,20 +674,18 @@ DECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pNetFltIf, PVOID pvPacke } /* drop it */ - if(pPacket) + if (pPacket) { - if(!(fFlags & PACKET_MINE)) + if (!(fFlags & PACKET_MINE)) { -# if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP) +# if !defined(VBOXNETADP) /* complete the packets */ - if(fFlags & PACKET_SRC_HOST) + if (fFlags & PACKET_SRC_HOST) { # endif -# ifndef VBOX_NETFLT_ONDEMAND_BIND /* NDIS_SET_PACKET_STATUS(pPacket, Status); */ - NdisMSendComplete(pAdapt->hMiniportHandle, pPacket, Status); -# endif -# if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP) + NdisMSendComplete(pNetFltIf->u.s.hMiniport, pPacket, Status); +# if !defined(VBOXNETADP) } else { @@ -775,15 +693,13 @@ DECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pNetFltIf, PVOID pvPacke # ifndef VBOXNETADP NdisReturnPackets(&pPacket, 1); # endif -# if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP) +# if !defined(VBOXNETADP) } # endif } else { -# ifndef VBOX_NETFLT_ONDEMAND_BIND Assert(!(fFlags & PACKET_SRC_HOST)); -# endif vboxNetFltWinFreeSGNdisPacket(pPacket, true); } } @@ -795,10 +711,10 @@ DECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pNetFltIf, PVOID pvPacke # ifndef VBOXNETADP bPending = false; # endif - } while(0); + } while (0); #ifdef DEBUG_NETFLT_PACKETS - if(pTmpPacket) + if (pTmpPacket) { vboxNetFltWinFreeSGNdisPacket(pTmpPacket, true); } @@ -810,7 +726,7 @@ DECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pNetFltIf, PVOID pvPacke return false; #endif #else /* #ifdef VBOXNETFLT_NO_PACKET_QUEUE */ - } while(0); + } while (0); if (bDeleteSG) vboxNetFltWinMemFree(pSG); @@ -822,7 +738,6 @@ DECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pNetFltIf, PVOID pvPacke # endif #endif } - #ifndef VBOXNETFLT_NO_PACKET_QUEUE /* * thread start function for the thread which processes the packets enqueued in our send and receive callbacks called by ndis @@ -836,39 +751,34 @@ static VOID vboxNetFltWinQuPacketQueueWorkerThreadProc(PVBOXNETFLTINS pNetFltIf) { bool fResume = true; NTSTATUS fStatus; - PADAPT pAdapt = PVBOXNETFLTINS_2_PADAPT(pNetFltIf); PPACKET_QUEUE_WORKER pWorker = &pNetFltIf->u.s.PacketQueueWorker; - /* two events we're waiting is "kill" and "notify" events - * the former is used for the thread termination - * the latter gets fired each time the packet is added to the queue */ - PVOID pEvents[] = { - (PVOID) &pWorker->KillEvent, - (PVOID) &pWorker->NotifyEvent, - }; + PVOID apEvents[] = { + (PVOID)&pWorker->KillEvent, + (PVOID)&pWorker->NotifyEvent + }; - while(fResume) + while (fResume) { uint32_t cNumProcessed; uint32_t cNumPostedToHostWire; - fStatus = KeWaitForMultipleObjects(2, pEvents, WaitAny, Executive, KernelMode, FALSE, - NULL, NULL); - if(!NT_SUCCESS(fStatus) || fStatus == STATUS_WAIT_0) + fStatus = KeWaitForMultipleObjects(RT_ELEMENTS(apEvents), apEvents, WaitAny, Executive, KernelMode, FALSE, NULL, NULL); + if (!NT_SUCCESS(fStatus) || fStatus == STATUS_WAIT_0) { /* "kill" event was set * will process queued packets and exit */ fResume = false; } - LogFlow(("==> processing vboxNetFltWinQuPacketQueueWorkerThreadProc\n")); + LogFlow(("processing vboxNetFltWinQuPacketQueueWorkerThreadProc\n")); cNumProcessed = 0; cNumPostedToHostWire = 0; do { - PPACKET_INFO pInfo; + PVBOXNETFLTPACKET_INFO pInfo; #ifdef DEBUG_NETFLT_PACKETS /* packet used for matching */ @@ -880,14 +790,14 @@ static VOID vboxNetFltWinQuPacketQueueWorkerThreadProc(PVBOXNETFLTINS pNetFltIf) * the same should be done for enqueue !!! */ pInfo = vboxNetFltWinQuInterlockedDequeueHead(&pWorker->PacketQueue); - if(!pInfo) + if (!pInfo) { break; } - LogFlow(("==> found info (%p)\n", pInfo)); + LogFlow(("found info (0x%p)\n", pInfo)); - if(vboxNetFltWinQuProcessInfo(pNetFltIf, pWorker, pInfo->pPacket, pInfo->fFlags)) + if (vboxNetFltWinQuProcessInfo(pNetFltIf, pWorker, pInfo->pPacket, pInfo->fFlags)) { cNumPostedToHostWire++; } @@ -895,17 +805,17 @@ static VOID vboxNetFltWinQuPacketQueueWorkerThreadProc(PVBOXNETFLTINS pNetFltIf) vboxNetFltWinPpFreePacketInfo(pInfo); cNumProcessed++; - } while(TRUE); + } while (TRUE); - if(cNumProcessed) + if (cNumProcessed) { vboxNetFltWinDecReferenceNetFlt(pNetFltIf, cNumProcessed); Assert(cNumProcessed >= cNumPostedToHostWire); - if(cNumProcessed != cNumPostedToHostWire) + if (cNumProcessed != cNumPostedToHostWire) { - vboxNetFltWinDecReferenceAdapt(pAdapt, cNumProcessed - cNumPostedToHostWire); + vboxNetFltWinDecReferenceWinIf(pNetFltIf, cNumProcessed - cNumPostedToHostWire); } } } @@ -916,24 +826,23 @@ static VOID vboxNetFltWinQuPacketQueueWorkerThreadProc(PVBOXNETFLTINS pNetFltIf) /** * thread start function for the job processing thread * - * see comments for PJOB_QUEUE + * see comments for PVBOXNETFLT_JOB_QUEUE */ -static VOID vboxNetFltWinJobWorkerThreadProc(PJOB_QUEUE pQueue) +static VOID vboxNetFltWinJobWorkerThreadProc(PVBOXNETFLT_JOB_QUEUE pQueue) { bool fResume = true; NTSTATUS Status; - PVOID pEvents[] = { - (PVOID) &pQueue->KillEvent, - (PVOID) &pQueue->NotifyEvent, - }; + PVOID apEvents[] = { + (PVOID)&pQueue->KillEvent, + (PVOID)&pQueue->NotifyEvent, + }; do { - Status = KeWaitForMultipleObjects(2, pEvents, WaitAny, Executive, KernelMode, FALSE, - NULL, NULL); + Status = KeWaitForMultipleObjects(RT_ELEMENTS(apEvents), apEvents, WaitAny, Executive, KernelMode, FALSE, NULL, NULL); Assert(NT_SUCCESS(Status)); - if(!NT_SUCCESS(Status) || Status == STATUS_WAIT_0) + if (!NT_SUCCESS(Status) || Status == STATUS_WAIT_0) { /* will process queued jobs and exit */ Assert(Status == STATUS_WAIT_0); @@ -943,23 +852,23 @@ static VOID vboxNetFltWinJobWorkerThreadProc(PJOB_QUEUE pQueue) do { PLIST_ENTRY pJobEntry = ExInterlockedRemoveHeadList(&pQueue->Jobs, &pQueue->Lock); - PJOB pJob; + PVBOXNETFLT_JOB pJob; - if(!pJobEntry) + if (!pJobEntry) break; pJob = LIST_ENTRY_2_JOB(pJobEntry); Assert(KeGetCurrentIrql() == PASSIVE_LEVEL); - pJob->pRoutine(pJob->pContext); + pJob->pfnRoutine(pJob->pContext); Assert(KeGetCurrentIrql() == PASSIVE_LEVEL); - if(pJob->bUseCompletionEvent) + if (pJob->bUseCompletionEvent) { KeSetEvent(&pJob->CompletionEvent, 1, FALSE); } - } while(TRUE); - } while(fResume); + } while (TRUE); + } while (fResume); Assert(Status == STATUS_WAIT_0); @@ -968,11 +877,11 @@ static VOID vboxNetFltWinJobWorkerThreadProc(PJOB_QUEUE pQueue) /** * enqueues the job to the job queue to be processed by the job worker thread - * see comments for PJOB_QUEUE + * see comments for PVBOXNETFLT_JOB_QUEUE */ -static VOID vboxNetFltWinJobEnqueueJob(PJOB_QUEUE pQueue, PJOB pJob, bool bEnqueueHead) +static VOID vboxNetFltWinJobEnqueueJob(PVBOXNETFLT_JOB_QUEUE pQueue, PVBOXNETFLT_JOB pJob, bool bEnqueueHead) { - if(bEnqueueHead) + if (bEnqueueHead) { ExInterlockedInsertHeadList(&pQueue->Jobs, &pJob->ListEntry, &pQueue->Lock); } @@ -984,27 +893,27 @@ static VOID vboxNetFltWinJobEnqueueJob(PJOB_QUEUE pQueue, PJOB pJob, bool bEnque KeSetEvent(&pQueue->NotifyEvent, 1, FALSE); } -DECLINLINE(VOID) vboxNetFltWinJobInit(PJOB pJob, JOB_ROUTINE pRoutine, PVOID pContext, bool bUseEvent) +DECLINLINE(VOID) vboxNetFltWinJobInit(PVBOXNETFLT_JOB pJob, PFNVBOXNETFLT_JOB_ROUTINE pfnRoutine, PVOID pContext, bool bUseEvent) { - pJob->pRoutine = pRoutine; + pJob->pfnRoutine = pfnRoutine; pJob->pContext = pContext; pJob->bUseCompletionEvent = bUseEvent; - if(bUseEvent) + if (bUseEvent) KeInitializeEvent(&pJob->CompletionEvent, NotificationEvent, FALSE); } /** * enqueues the job to the job queue to be processed by the job worker thread and * blocks until the job is done - * see comments for PJOB_QUEUE + * see comments for PVBOXNETFLT_JOB_QUEUE */ -static VOID vboxNetFltWinJobSynchExec(PJOB_QUEUE pQueue, JOB_ROUTINE pRoutine, PVOID pContext) +static VOID vboxNetFltWinJobSynchExec(PVBOXNETFLT_JOB_QUEUE pQueue, PFNVBOXNETFLT_JOB_ROUTINE pfnRoutine, PVOID pContext) { - JOB Job; + VBOXNETFLT_JOB Job; Assert(KeGetCurrentIrql() < DISPATCH_LEVEL); - vboxNetFltWinJobInit(&Job, pRoutine, pContext, true); + vboxNetFltWinJobInit(&Job, pfnRoutine, pContext, true); vboxNetFltWinJobEnqueueJob(pQueue, &Job, false); @@ -1015,48 +924,50 @@ static VOID vboxNetFltWinJobSynchExec(PJOB_QUEUE pQueue, JOB_ROUTINE pRoutine, P * enqueues the job to be processed by the job worker thread at passive level and * blocks until the job is done */ -DECLHIDDEN(VOID) vboxNetFltWinJobSynchExecAtPassive(JOB_ROUTINE pRoutine, PVOID pContext) +DECLHIDDEN(VOID) vboxNetFltWinJobSynchExecAtPassive(PFNVBOXNETFLT_JOB_ROUTINE pfnRoutine, PVOID pContext) { - vboxNetFltWinJobSynchExec(&g_JobQueue, pRoutine, pContext); + vboxNetFltWinJobSynchExec(&g_VBoxJobQueue, pfnRoutine, pContext); } /** * helper function used for system thread creation */ -static NTSTATUS vboxNetFltWinQuCreateSystemThread(PKTHREAD * ppThread, PKSTART_ROUTINE pStartRoutine, PVOID pStartContext) +static NTSTATUS vboxNetFltWinQuCreateSystemThread(PKTHREAD *ppThread, PKSTART_ROUTINE pfnStartRoutine, PVOID pvStartContext) { - NTSTATUS fStatus; - HANDLE hThread; - OBJECT_ATTRIBUTES fObjectAttributes; - + OBJECT_ATTRIBUTES ObjectAttributes; Assert(KeGetCurrentIrql() == PASSIVE_LEVEL); - InitializeObjectAttributes(&fObjectAttributes, NULL, OBJ_KERNEL_HANDLE, - NULL, NULL); + InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); - fStatus = PsCreateSystemThread(&hThread, THREAD_ALL_ACCESS, - &fObjectAttributes, NULL, NULL, - (PKSTART_ROUTINE) pStartRoutine, pStartContext); - if (!NT_SUCCESS(fStatus)) - return fStatus; + HANDLE hThread; + NTSTATUS Status = PsCreateSystemThread(&hThread, THREAD_ALL_ACCESS, &ObjectAttributes, NULL, NULL, (PKSTART_ROUTINE)pfnStartRoutine, pvStartContext); + Assert(Status == STATUS_SUCCESS); + if (Status == STATUS_SUCCESS) + { + Status = ObReferenceObjectByHandle(hThread, THREAD_ALL_ACCESS, NULL, KernelMode, (PVOID*)ppThread, NULL); + Assert(Status == STATUS_SUCCESS); + ZwClose(hThread); + if (Status == STATUS_SUCCESS) + { + return STATUS_SUCCESS; + } - ObReferenceObjectByHandle(hThread, THREAD_ALL_ACCESS, NULL, - KernelMode, (PVOID*) ppThread, NULL); - ZwClose(hThread); - return STATUS_SUCCESS; + /* @todo: how would we fail in this case ?*/ + } + return Status; } /** * initialize the job queue - * see comments for PJOB_QUEUE + * see comments for PVBOXNETFLT_JOB_QUEUE */ -static NTSTATUS vboxNetFltWinJobInitQueue(PJOB_QUEUE pQueue) +static NTSTATUS vboxNetFltWinJobInitQueue(PVBOXNETFLT_JOB_QUEUE pQueue) { NTSTATUS fStatus; Assert(KeGetCurrentIrql() == PASSIVE_LEVEL); - NdisZeroMemory(pQueue, sizeof(JOB_QUEUE)); + NdisZeroMemory(pQueue, sizeof(VBOXNETFLT_JOB_QUEUE)); KeInitializeEvent(&pQueue->KillEvent, NotificationEvent, FALSE); @@ -1065,7 +976,7 @@ static NTSTATUS vboxNetFltWinJobInitQueue(PJOB_QUEUE pQueue) InitializeListHead(&pQueue->Jobs); fStatus = vboxNetFltWinQuCreateSystemThread(&pQueue->pThread, (PKSTART_ROUTINE)vboxNetFltWinJobWorkerThreadProc, pQueue); - if(fStatus != STATUS_SUCCESS) + if (fStatus != STATUS_SUCCESS) { pQueue->pThread = NULL; } @@ -1079,13 +990,13 @@ static NTSTATUS vboxNetFltWinJobInitQueue(PJOB_QUEUE pQueue) /** * deinitialize the job queue - * see comments for PJOB_QUEUE + * see comments for PVBOXNETFLT_JOB_QUEUE */ -static void vboxNetFltWinJobFiniQueue(PJOB_QUEUE pQueue) +static void vboxNetFltWinJobFiniQueue(PVBOXNETFLT_JOB_QUEUE pQueue) { Assert(KeGetCurrentIrql() == PASSIVE_LEVEL); - if(pQueue->pThread) + if (pQueue->pThread) { KeSetEvent(&pQueue->KillEvent, 0, FALSE); @@ -1116,19 +1027,19 @@ DECLHIDDEN(NTSTATUS) vboxNetFltWinQuInitPacketQueue(PVBOXNETFLTINS pInstance) do { - Status = vboxNetFltWinPpAllocatePacketInfoPool(&pWorker->PacketInfoPool, PACKET_INFO_POOL_SIZE); + Status = vboxNetFltWinPpAllocatePacketInfoPool(&pWorker->PacketInfoPool, VBOXNETFLT_PACKET_INFO_POOL_SIZE); - if(Status == NDIS_STATUS_SUCCESS) + if (Status == NDIS_STATUS_SUCCESS) { pWorker->pSG = vboxNetFltWinCreateSG(PACKET_QUEUE_SG_SEGS_ALLOC); - if(!pWorker->pSG) + if (!pWorker->pSG) { Status = STATUS_INSUFFICIENT_RESOURCES; break; } Status = vboxNetFltWinQuCreateSystemThread(&pWorker->pThread, (PKSTART_ROUTINE)vboxNetFltWinQuPacketQueueWorkerThreadProc, pInstance); - if(Status != STATUS_SUCCESS) + if (Status != STATUS_SUCCESS) { vboxNetFltWinPpFreePacketInfoPool(&pWorker->PacketInfoPool); vboxNetFltWinMemFree(pWorker->pSG); @@ -1137,7 +1048,7 @@ DECLHIDDEN(NTSTATUS) vboxNetFltWinQuInitPacketQueue(PVBOXNETFLTINS pInstance) } } - } while(0); + } while (0); return Status; } @@ -1152,11 +1063,9 @@ DECLHIDDEN(void) vboxNetFltWinQuFiniPacketQueue(PVBOXNETFLTINS pInstance) PPACKET_QUEUE_WORKER pWorker = &pInstance->u.s.PacketQueueWorker; Assert(KeGetCurrentIrql() < DISPATCH_LEVEL); -// Assert(pAdapt->pPacketQueueSG); - /* using the pPacketQueueSG as an indicator that the packet queue is initialized */ RTSpinlockAcquireNoInts((pInstance)->hSpinlock, &Tmp); - if(pWorker->pSG) + if (pWorker->pSG) { pSG = pWorker->pSG; pWorker->pSG = NULL; @@ -1194,10 +1103,10 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinAllocSG(UINT cbPacket, PINTNETSG *ppSG) * 2. buffer of cbPacket containing the entire packet */ AssertCompileSizeAlignment(INTNETSG, sizeof(PVOID)); Status = vboxNetFltWinMemAlloc((PVOID*)&pSG, cbPacket + sizeof(INTNETSG)); - if(Status == NDIS_STATUS_SUCCESS) + if (Status == NDIS_STATUS_SUCCESS) { IntNetSgInitTemp(pSG, pSG + 1, cbPacket); - LogFlow(("pSG created (%p)\n", pSG)); + LogFlow(("pSG created (%p)\n", pSG)); *ppSG = pSG; } return Status; @@ -1207,7 +1116,7 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinAllocSG(UINT cbPacket, PINTNETSG *ppSG) /** * put the packet info to the queue */ -DECLINLINE(void) vboxNetFltWinQuEnqueueInfo(PPACKET_QUEUE_WORKER pWorker, PPACKET_INFO pInfo) +DECLINLINE(void) vboxNetFltWinQuEnqueueInfo(PVBOXNETFLTPACKET_QUEUE_WORKER pWorker, PVBOXNETFLTPACKET_INFO pInfo) { vboxNetFltWinQuInterlockedEnqueueTail(&pWorker->PacketQueue, pInfo); @@ -1225,18 +1134,18 @@ DECLINLINE(void) vboxNetFltWinQuEnqueueInfo(PPACKET_QUEUE_WORKER pWorker, PPACKE */ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQuEnqueuePacket(PVBOXNETFLTINS pInstance, PVOID pPacket, const UINT fPacketFlags) { - PPACKET_INFO pInfo; - PPACKET_QUEUE_WORKER pWorker = &pInstance->u.s.PacketQueueWorker; + PVBOXNETFLT_PACKET_INFO pInfo; + PVBOXNETFLT_PACKET_QUEUE_WORKER pWorker = &pInstance->u.s.PacketQueueWorker; NDIS_STATUS fStatus = NDIS_STATUS_SUCCESS; do { - if(fPacketFlags & PACKET_COPY) + if (fPacketFlags & PACKET_COPY) { - PNDIS_BUFFER pBuffer = NULL; - UINT cBufferCount; - UINT uBytesCopied = 0; - UINT cbPacketLength; + PNDIS_BUFFER pBuffer = NULL; + UINT cBufferCount; + UINT uBytesCopied = 0; + UINT cbPacketLength; PINTNETSG pSG; /* the packet is Ndis packet */ @@ -1253,7 +1162,7 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQuEnqueuePacket(PVBOXNETFLTINS pInstance, P Assert(cBufferCount); fStatus = vboxNetFltWinAllocSG(cbPacketLength, &pSG); - if(fStatus != NDIS_STATUS_SUCCESS) + if (fStatus != NDIS_STATUS_SUCCESS) { AssertFailed(); break; @@ -1261,7 +1170,7 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQuEnqueuePacket(PVBOXNETFLTINS pInstance, P pInfo = vboxNetFltWinPpAllocPacketInfo(&pWorker->PacketInfoPool); - if(!pInfo) + if (!pInfo) { AssertFailed(); /* TODO: what status to set? */ @@ -1277,7 +1186,7 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQuEnqueuePacket(PVBOXNETFLTINS pInstance, P SET_PACKET_TO_INFO(pInfo, pSG); fStatus = vboxNetFltWinNdisBufferMoveToSG0(pBuffer, pSG); - if(fStatus != NDIS_STATUS_SUCCESS) + if (fStatus != NDIS_STATUS_SUCCESS) { AssertFailed(); vboxNetFltWinPpFreePacketInfo(pInfo); @@ -1291,7 +1200,7 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQuEnqueuePacket(PVBOXNETFLTINS pInstance, P { pInfo = vboxNetFltWinPpAllocPacketInfo(&pWorker->PacketInfoPool); - if(!pInfo) + if (!pInfo) { AssertFailed(); /* TODO: what status to set? */ @@ -1307,164 +1216,56 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQuEnqueuePacket(PVBOXNETFLTINS pInstance, P vboxNetFltWinQuEnqueueInfo(pWorker, pInfo); - } while(0); + } while (0); return fStatus; } #endif -#ifndef VBOX_NETFLT_ONDEMAND_BIND -/* - * ioctl i/f - */ -static NTSTATUS -vboxNetFltWinPtDispatchIoctl( - IN PDEVICE_OBJECT pDeviceObject, - IN PIO_STACK_LOCATION pIrpStack) -{ -#if 0 - ULONG CtlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode; - NTSTATUS Status = STATUS_SUCCESS; - int rc; - - switch(CtlCode) - { - - case VBOXNETFLT_WIN_IOCTL_INIT: - rc = vboxNetFltWinInitIdc(); - if(!RT_SUCCESS(rc)) - { - Status = STATUS_UNSUCCESSFUL; - } - break; - case VBOXNETFLT_WIN_IOCTL_FINI: - /* we are finalizing during unload */ - /* TODO: FIXME: need to prevent driver unload that can occur in case IntNet is connected to us, - * but we are not bound to any adapters */ -/* rc = vboxNetFltWinTryFiniIdc(); - if(!RT_SUCCESS(rc)) - { - Status = STATUS_UNSUCCESSFUL; - } - */ - break; - - default: - Status = STATUS_NOT_SUPPORTED; - break; - } - - return Status; -#else - return STATUS_NOT_SUPPORTED; -#endif -} - -/* -Routine Description: - - Process IRPs sent to this device. - -Arguments: - - DeviceObject - pointer to a device object - Irp - pointer to an I/O Request Packet - -Return Value: - - NTSTATUS - STATUS_SUCCESS always - change this when adding - real code to handle ioctls. - -*/ -DECLHIDDEN(NTSTATUS) -vboxNetFltWinPtDispatch( - IN PDEVICE_OBJECT pDeviceObject, - IN PIRP pIrp - ) -{ - PIO_STACK_LOCATION pIrpStack; - NTSTATUS Status = STATUS_SUCCESS; - - LogFlow(("==>Pt Dispatch\n")); - pIrpStack = IoGetCurrentIrpStackLocation(pIrp); - - - switch (pIrpStack->MajorFunction) - { - case IRP_MJ_CREATE: - break; - - case IRP_MJ_CLEANUP: - break; - - case IRP_MJ_CLOSE: - break; - - case IRP_MJ_DEVICE_CONTROL: - Status = vboxNetFltWinPtDispatchIoctl(pDeviceObject, pIrpStack); - break; - default: - break; - } - - pIrp->IoStatus.Status = Status; - IoCompleteRequest(pIrp, IO_NO_INCREMENT); - - LogFlow(("<== Pt Dispatch\n")); - - return Status; - -} -#endif /* * netflt */ #ifndef VBOXNETADP -/* - * NOTE! the routine is NOT re-enterable for the given pAdapt - * the serialization is not implemented for performance reasons - * since we are assuming the caller serializes the requests as IntNet does - */ -static NDIS_STATUS vboxNetFltWinSynchNdisRequest(PADAPT pAdapt, PNDIS_REQUEST pRequest) +static NDIS_STATUS vboxNetFltWinSynchNdisRequest(PVBOXNETFLTINS pNetFlt, PNDIS_REQUEST pRequest) { int rc; Assert(KeGetCurrentIrql() < DISPATCH_LEVEL); /* 1. serialize */ - rc = RTSemFastMutexRequest(pAdapt->hSynchRequestMutex); AssertRC(rc); - if(RT_SUCCESS(rc)) + rc = RTSemFastMutexRequest(pNetFlt->u.s.WinIf.hSynchRequestMutex); AssertRC(rc); + if (RT_SUCCESS(rc)) { NDIS_STATUS fRequestStatus = NDIS_STATUS_SUCCESS; - /* 2. set pAdapt->pSynchRequest */ - Assert(!pAdapt->pSynchRequest); - pAdapt->pSynchRequest = pRequest; + /* 2. set pNetFlt->u.s.pSynchRequest */ + Assert(!pNetFlt->u.s.WinIf.pSynchRequest); + pNetFlt->u.s.WinIf.pSynchRequest = pRequest; /* 3. call NdisRequest */ - NdisRequest(&fRequestStatus, pAdapt->hBindingHandle, pRequest); + NdisRequest(&fRequestStatus, pNetFlt->u.s.WinIf.hBinding, pRequest); - if(fRequestStatus == NDIS_STATUS_PENDING) + if (fRequestStatus == NDIS_STATUS_PENDING) { /* 3.1 if pending wait and assign the resulting status */ - KeWaitForSingleObject(&pAdapt->hSynchCompletionEvent, Executive, + KeWaitForSingleObject(&pNetFlt->u.s.WinIf.hSynchCompletionEvent, Executive, KernelMode, FALSE, NULL); - fRequestStatus = pAdapt->fSynchCompletionStatus; + fRequestStatus = pNetFlt->u.s.WinIf.SynchCompletionStatus; } - /* 4. clear the pAdapt->pSynchRequest */ - pAdapt->pSynchRequest = NULL; + /* 4. clear the pNetFlt->u.s.pSynchRequest */ + pNetFlt->u.s.WinIf.pSynchRequest = NULL; - RTSemFastMutexRelease(pAdapt->hSynchRequestMutex); AssertRC(rc); + RTSemFastMutexRelease(pNetFlt->u.s.WinIf.hSynchRequestMutex); AssertRC(rc); return fRequestStatus; } return NDIS_STATUS_FAILURE; } -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinGetMacAddress(PADAPT pAdapt, PRTMAC pMac) +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinGetMacAddress(PVBOXNETFLTINS pNetFlt, PRTMAC pMac) { NDIS_REQUEST request; NDIS_STATUS status; @@ -1472,8 +1273,8 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinGetMacAddress(PADAPT pAdapt, PRTMAC pMac) request.DATA.QUERY_INFORMATION.InformationBuffer = pMac; request.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(RTMAC); request.DATA.QUERY_INFORMATION.Oid = OID_802_3_CURRENT_ADDRESS; - status = vboxNetFltWinSynchNdisRequest(pAdapt, &request); - if(status != NDIS_STATUS_SUCCESS) + status = vboxNetFltWinSynchNdisRequest(pNetFlt, &request); + if (status != NDIS_STATUS_SUCCESS) { /* TODO */ AssertFailed(); @@ -1483,7 +1284,7 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinGetMacAddress(PADAPT pAdapt, PRTMAC pMac) } -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQueryPhysicalMedium(PADAPT pAdapt, NDIS_PHYSICAL_MEDIUM * pMedium) +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQueryPhysicalMedium(PVBOXNETFLTINS pNetFlt, NDIS_PHYSICAL_MEDIUM * pMedium) { NDIS_REQUEST Request; NDIS_STATUS Status; @@ -1491,10 +1292,10 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQueryPhysicalMedium(PADAPT pAdapt, NDIS_PHY Request.DATA.QUERY_INFORMATION.InformationBuffer = pMedium; Request.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(NDIS_PHYSICAL_MEDIUM); Request.DATA.QUERY_INFORMATION.Oid = OID_GEN_PHYSICAL_MEDIUM; - Status = vboxNetFltWinSynchNdisRequest(pAdapt, &Request); - if(Status != NDIS_STATUS_SUCCESS) + Status = vboxNetFltWinSynchNdisRequest(pNetFlt, &Request); + if (Status != NDIS_STATUS_SUCCESS) { - if(Status == NDIS_STATUS_NOT_SUPPORTED || Status == NDIS_STATUS_NOT_RECOGNIZED || Status == NDIS_STATUS_INVALID_OID) + if (Status == NDIS_STATUS_NOT_SUPPORTED || Status == NDIS_STATUS_NOT_RECOGNIZED || Status == NDIS_STATUS_INVALID_OID) { Status = NDIS_STATUS_NOT_SUPPORTED; } @@ -1507,7 +1308,7 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQueryPhysicalMedium(PADAPT pAdapt, NDIS_PHY return Status; } -DECLHIDDEN(bool) vboxNetFltWinIsPromiscuous(PADAPT pAdapt) +DECLHIDDEN(bool) vboxNetFltWinIsPromiscuous(PVBOXNETFLTINS pNetFlt) { /** @todo r=bird: This is too slow and is probably returning the wrong * information. What we're interested in is whether someone besides us @@ -1515,13 +1316,13 @@ DECLHIDDEN(bool) vboxNetFltWinIsPromiscuous(PADAPT pAdapt) NDIS_REQUEST request; NDIS_STATUS status; ULONG filter; - Assert(VBOXNETFLT_PROMISCUOUS_SUPPORTED(pAdapt)); + Assert(VBOXNETFLT_PROMISCUOUS_SUPPORTED(pNetFlt)); request.RequestType = NdisRequestQueryInformation; request.DATA.QUERY_INFORMATION.InformationBuffer = &filter; request.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(filter); request.DATA.QUERY_INFORMATION.Oid = OID_GEN_CURRENT_PACKET_FILTER; - status = vboxNetFltWinSynchNdisRequest(pAdapt, &request); - if(status != NDIS_STATUS_SUCCESS) + status = vboxNetFltWinSynchNdisRequest(pNetFlt, &request); + if (status != NDIS_STATUS_SUCCESS) { /* TODO */ AssertFailed(); @@ -1530,13 +1331,13 @@ DECLHIDDEN(bool) vboxNetFltWinIsPromiscuous(PADAPT pAdapt) return (filter & NDIS_PACKET_TYPE_PROMISCUOUS) != 0; } -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinSetPromiscuous(PADAPT pAdapt, bool bYes) +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinSetPromiscuous(PVBOXNETFLTINS pNetFlt, bool bYes) { /** @todo Need to report changes to the switch via: * pThis->pSwitchPort->pfnReportPromiscuousMode(pThis->pSwitchPort, fPromisc); */ - Assert(VBOXNETFLT_PROMISCUOUS_SUPPORTED(pAdapt)); - if(VBOXNETFLT_PROMISCUOUS_SUPPORTED(pAdapt)) + Assert(VBOXNETFLT_PROMISCUOUS_SUPPORTED(pNetFlt)); + if (VBOXNETFLT_PROMISCUOUS_SUPPORTED(pNetFlt)) { NDIS_REQUEST Request; NDIS_STATUS fStatus; @@ -1547,48 +1348,48 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinSetPromiscuous(PADAPT pAdapt, bool bYes) Request.DATA.QUERY_INFORMATION.InformationBuffer = &fFilter; Request.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(fFilter); Request.DATA.QUERY_INFORMATION.Oid = OID_GEN_CURRENT_PACKET_FILTER; - fStatus = vboxNetFltWinSynchNdisRequest(pAdapt, &Request); - if(fStatus != NDIS_STATUS_SUCCESS) + fStatus = vboxNetFltWinSynchNdisRequest(pNetFlt, &Request); + if (fStatus != NDIS_STATUS_SUCCESS) { /* TODO: */ AssertFailed(); return fStatus; } - if(!pAdapt->bUpperProtSetFilterInitialized) + if (!pNetFlt->u.s.WinIf.StateFlags.fUpperProtSetFilterInitialized) { /* the cache was not initialized yet, initiate it with the current filter value */ - pAdapt->fUpperProtocolSetFilter = fFilter; - pAdapt->bUpperProtSetFilterInitialized = true; + pNetFlt->u.s.WinIf.fUpperProtocolSetFilter = fFilter; + pNetFlt->u.s.WinIf.StateFlags.fUpperProtSetFilterInitialized = TRUE; } - if(bYes) + if (bYes) { fExpectedFilter = NDIS_PACKET_TYPE_PROMISCUOUS; fOurFilter = NDIS_PACKET_TYPE_PROMISCUOUS; } else { - fExpectedFilter = pAdapt->fUpperProtocolSetFilter; + fExpectedFilter = pNetFlt->u.s.WinIf.fUpperProtocolSetFilter; fOurFilter = 0; } - if(fExpectedFilter != fFilter) + if (fExpectedFilter != fFilter) { Request.RequestType = NdisRequestSetInformation; Request.DATA.SET_INFORMATION.InformationBuffer = &fExpectedFilter; Request.DATA.SET_INFORMATION.InformationBufferLength = sizeof(fExpectedFilter); Request.DATA.SET_INFORMATION.Oid = OID_GEN_CURRENT_PACKET_FILTER; - fStatus = vboxNetFltWinSynchNdisRequest(pAdapt, &Request); - if(fStatus != NDIS_STATUS_SUCCESS) + fStatus = vboxNetFltWinSynchNdisRequest(pNetFlt, &Request); + if (fStatus != NDIS_STATUS_SUCCESS) { /* TODO */ AssertFailed(); return fStatus; } } - pAdapt->fOurSetFilter = fOurFilter; + pNetFlt->u.s.WinIf.fOurSetFilter = fOurFilter; return fStatus; } return NDIS_STATUS_NOT_SUPPORTED; @@ -1612,8 +1413,6 @@ DECLHIDDEN(void) vboxNetFltWinGenerateMACAddress(RTMAC *pMac) DECLHIDDEN(int) vboxNetFltWinMAC2NdisString(RTMAC *pMac, PNDIS_STRING pNdisString) { static const char s_achDigits[17] = "0123456789abcdef"; - uint8_t u8; - int i; PWSTR pString; /* validate parameters */ @@ -1623,11 +1422,11 @@ DECLHIDDEN(int) vboxNetFltWinMAC2NdisString(RTMAC *pMac, PNDIS_STRING pNdisStrin pString = pNdisString->Buffer; - for( i = 0; i < 6; i++) + for (int i = 0; i < 6; i++) { - u8 = pMac->au8[i]; - pString[ 0] = s_achDigits[(u8 >> 4) & 0xf]; - pString[ 1] = s_achDigits[(u8/*>>0*/)& 0xf]; + uint8_t u8 = pMac->au8[i]; + pString[0] = s_achDigits[(u8 >> 4) & 0xf]; + pString[1] = s_achDigits[(u8/*>>0*/)& 0xf]; pString += 2; } @@ -1640,15 +1439,15 @@ DECLHIDDEN(int) vboxNetFltWinMAC2NdisString(RTMAC *pMac, PNDIS_STRING pNdisStrin static int vboxNetFltWinWchar2Int(WCHAR c, uint8_t * pv) { - if(c >= L'A' && c <= L'F') + if (c >= L'A' && c <= L'F') { *pv = (c - L'A') + 10; } - else if(c >= L'a' && c <= L'f') + else if (c >= L'a' && c <= L'f') { *pv = (c - L'a') + 10; } - else if(c >= L'0' && c <= L'9') + else if (c >= L'0' && c <= L'9') { *pv = (c - L'0'); } @@ -1671,17 +1470,17 @@ DECLHIDDEN(int) vboxNetFltWinMACFromNdisString(RTMAC *pMac, PNDIS_STRING pNdisSt pString = pNdisString->Buffer; - for(i = 0; i < 6; i++) + for (i = 0; i < 6; i++) { uint8_t v1, v2; rc = vboxNetFltWinWchar2Int(pString[0], &v1); - if(RT_FAILURE(rc)) + if (RT_FAILURE(rc)) { break; } rc = vboxNetFltWinWchar2Int(pString[1], &v2); - if(RT_FAILURE(rc)) + if (RT_FAILURE(rc)) { break; } @@ -1698,29 +1497,24 @@ DECLHIDDEN(int) vboxNetFltWinMACFromNdisString(RTMAC *pMac, PNDIS_STRING pNdisSt /** * creates a NDIS_PACKET from the PINTNETSG */ -#ifdef VBOX_NETFLT_ONDEMAND_BIND -/* TODO: the bToWire parameter seems to be unneeded here, remove them*/ -#endif -DECLHIDDEN(PNDIS_PACKET) vboxNetFltWinNdisPacketFromSG(PADAPT pAdapt, PINTNETSG pSG, PVOID pBufToFree, bool bToWire, bool bCopyMemory) +DECLHIDDEN(PNDIS_PACKET) vboxNetFltWinNdisPacketFromSG(PVBOXNETFLTINS pNetFlt, PINTNETSG pSG, PVOID pBufToFree, bool bToWire, bool bCopyMemory) { NDIS_STATUS fStatus; PNDIS_PACKET pPacket; Assert(pSG->aSegs[0].pv); - Assert(pSG->cbTotal >= sizeof(ETH_HEADER_SIZE)); + Assert(pSG->cbTotal >= sizeof(VBOXNETFLT_PACKET_ETHEADER_SIZE)); /** @todo Hrmpf, how can we fix this assumption? I fear this'll cause data * corruption and maybe even BSODs ... */ AssertReturn(pSG->cSegsUsed == 1 || bCopyMemory, NULL); -#ifdef VBOX_NETFLT_ONDEMAND_BIND - NdisAllocatePacket(&fStatus, &pPacket, pAdapt->hSendPacketPoolHandle); -#elif defined(VBOXNETADP) - NdisAllocatePacket(&fStatus, &pPacket, pAdapt->hRecvPacketPoolHandle); +#ifdef VBOXNETADP + NdisAllocatePacket(&fStatus, &pPacket, pNetFlt->u.s.WinIf.hRecvPacketPool); #else - NdisAllocatePacket(&fStatus, &pPacket, bToWire ? pAdapt->hSendPacketPoolHandle : pAdapt->hRecvPacketPoolHandle); + NdisAllocatePacket(&fStatus, &pPacket, bToWire ? pNetFlt->u.s.WinIf.hSendPacketPool : pNetFlt->u.s.WinIf.hRecvPacketPool); #endif - if(fStatus == NDIS_STATUS_SUCCESS) + if (fStatus == NDIS_STATUS_SUCCESS) { PNDIS_BUFFER pBuffer; PVOID pvMemBuf; @@ -1730,76 +1524,65 @@ DECLHIDDEN(PNDIS_PACKET) vboxNetFltWinNdisPacketFromSG(PADAPT pAdapt, PINTNETSG * in case the status contains NDIS_STATUS_RESOURCES */ VBOXNETFLT_OOB_INIT(pPacket); - if(bCopyMemory) + if (bCopyMemory) { fStatus = vboxNetFltWinMemAlloc(&pvMemBuf, pSG->cbTotal); Assert(fStatus == NDIS_STATUS_SUCCESS); - if(fStatus == NDIS_STATUS_SUCCESS) + if (fStatus == NDIS_STATUS_SUCCESS) IntNetSgRead(pSG, pvMemBuf); } else { pvMemBuf = pSG->aSegs[0].pv; } - if(fStatus == NDIS_STATUS_SUCCESS) + if (fStatus == NDIS_STATUS_SUCCESS) { -#ifdef VBOX_NETFLT_ONDEMAND_BIND - NdisAllocateBuffer(&fStatus, &pBuffer, - pAdapt->hSendBufferPoolHandle, - pvMemBuf, - pSG->cbTotal); -#elif defined(VBOXNETADP) +#ifdef VBOXNETADP NdisAllocateBuffer(&fStatus, &pBuffer, - pAdapt->hRecvBufferPoolHandle, + pNetFlt->u.s.WinIf.hRecvBufferPool, pvMemBuf, pSG->cbTotal); #else NdisAllocateBuffer(&fStatus, &pBuffer, - bToWire ? pAdapt->hSendBufferPoolHandle : pAdapt->hRecvBufferPoolHandle, + bToWire ? pNetFlt->u.s.WinIf.hSendBufferPool : pNetFlt->u.s.WinIf.hRecvBufferPool, pvMemBuf, pSG->cbTotal); #endif - if(fStatus == NDIS_STATUS_SUCCESS) + if (fStatus == NDIS_STATUS_SUCCESS) { NdisChainBufferAtBack(pPacket, pBuffer); -#ifndef VBOX_NETFLT_ONDEMAND_BIND - if(bToWire) -#endif + if (bToWire) { - PSEND_RSVD pSendRsvd; - pSendRsvd = (PSEND_RSVD)(pPacket->ProtocolReserved); - pSendRsvd->pOriginalPkt = NULL; - pSendRsvd->pBufToFree = pBufToFree; + PVBOXNETFLT_PKTRSVD_PT pSendInfo = (PVBOXNETFLT_PKTRSVD_PT)pPacket->ProtocolReserved; + pSendInfo->pOrigPacket = NULL; + pSendInfo->pBufToFree = pBufToFree; #ifdef VBOX_LOOPBACK_USEFLAGS /* set "don't loopback" flags */ - NdisSetPacketFlags(pPacket, g_fPacketDontLoopBack); + NdisGetPacketFlags(pPacket) = g_VBoxNetFltGlobalsWin.fPacketDontLoopBack; #else - NdisSetPacketFlags(pPacket, 0); + NdisGetPacketFlags(pPacket) = 0; #endif } -#ifndef VBOX_NETFLT_ONDEMAND_BIND else { - PRECV_RSVD pRecvRsvd; - pRecvRsvd = (PRECV_RSVD)(pPacket->MiniportReserved); - pRecvRsvd->pOriginalPkt = NULL; - pRecvRsvd->pBufToFree = pBufToFree; + PVBOXNETFLT_PKTRSVD_MP pRecvInfo = (PVBOXNETFLT_PKTRSVD_MP)pPacket->MiniportReserved; + pRecvInfo->pOrigPacket = NULL; + pRecvInfo->pBufToFree = pBufToFree; - /* me must set the header size on receive */ - NDIS_SET_PACKET_HEADER_SIZE(pPacket, ETH_HEADER_SIZE); + /* we must set the header size on receive */ + NDIS_SET_PACKET_HEADER_SIZE(pPacket, VBOXNETFLT_PACKET_ETHEADER_SIZE); /* NdisAllocatePacket zero-initializes the OOB data, * but keeps the packet flags, clean them here */ - NdisSetPacketFlags(pPacket, 0); + NdisGetPacketFlags(pPacket) = 0; } -#endif /* TODO: set out of bound data */ } else { AssertFailed(); - if(bCopyMemory) + if (bCopyMemory) { vboxNetFltWinMemFree(pvMemBuf); } @@ -1841,14 +1624,14 @@ DECLHIDDEN(void) vboxNetFltWinFreeSGNdisPacket(PNDIS_PACKET pPacket, bool bFreeM do { NdisUnchainBufferAtBack(pPacket, &pBuffer); - if(pBuffer != NULL) + if (pBuffer != NULL) { PVOID pvMemBuf; UINT cbLength; NdisQueryBufferSafe(pBuffer, &pvMemBuf, &cbLength, NormalPagePriority); NdisFreeBuffer(pBuffer); - if(bFreeMem) + if (bFreeMem) { vboxNetFltWinMemFree(pvMemBuf); } @@ -1857,65 +1640,27 @@ DECLHIDDEN(void) vboxNetFltWinFreeSGNdisPacket(PNDIS_PACKET pPacket, bool bFreeM { break; } - } while(true); + } while (true); NdisFreePacket(pPacket); } -/* - * Free all packet pools on the specified adapter. - * @param pAdapt - pointer to ADAPT structure - */ -static VOID -vboxNetFltWinPtFreeAllPacketPools( - IN PADAPT pAdapt - ) -{ -#ifndef VBOX_NETFLT_ONDEMAND_BIND - if (pAdapt->hRecvPacketPoolHandle != NULL) - { - /* - * Free the packet pool that is used to indicate receives - */ - NdisFreePacketPool(pAdapt->hRecvPacketPoolHandle); - - pAdapt->hRecvPacketPoolHandle = NULL; - } -#endif /* #ifndef VBOX_NETFLT_ONDEMAND_BIND*/ -#ifndef VBOXNETADP - if (pAdapt->hSendPacketPoolHandle != NULL) - { - - /* - * Free the packet pool that is used to send packets below - */ - - NdisFreePacketPool(pAdapt->hSendPacketPoolHandle); - - pAdapt->hSendPacketPoolHandle = NULL; - - } -#endif -} -#if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP) -static void vboxNetFltWinAssociateMiniportProtocol() +#if !defined(VBOXNETADP) +static void vboxNetFltWinAssociateMiniportProtocol(PVBOXNETFLTGLOBALS_WIN pGlobalsWin) { - NdisIMAssociateMiniport(vboxNetFltWinMpGetHandle(), vboxNetFltWinPtGetHandle()); + NdisIMAssociateMiniport(pGlobalsWin->Mp.hMiniport, pGlobalsWin->Pt.hProtocol); } #endif /* * NetFlt driver unload function */ -DECLHIDDEN(VOID) -vboxNetFltWinUnload( - IN PDRIVER_OBJECT DriverObject - ) +DECLHIDDEN(VOID) vboxNetFltWinUnload(IN PDRIVER_OBJECT DriverObject) { int rc; UNREFERENCED_PARAMETER(DriverObject); - LogFlow(("vboxNetFltWinUnload: entered\n")); + LogFlow((__FUNCTION__" ==> DO (0x%x)\n", DriverObject)); rc = vboxNetFltWinTryFiniIdc(); if (RT_FAILURE(rc)) @@ -1923,111 +1668,89 @@ vboxNetFltWinUnload( /* TODO: we can not prevent driver unload here */ AssertFailed(); - Log(("vboxNetFltWinTryFiniIdc - failed, busy.\n")); + Log((__FUNCTION__": vboxNetFltWinTryFiniIdc - failed, busy.\n")); } - vboxNetFltWinJobFiniQueue(&g_JobQueue); + vboxNetFltWinJobFiniQueue(&g_VBoxJobQueue); #ifndef VBOXNETADP - vboxNetFltWinPtDeregister(); -#endif -#ifndef VBOX_NETFLT_ONDEMAND_BIND - vboxNetFltWinMpDeregister(); + vboxNetFltWinPtDeregister(&g_VBoxNetFltGlobalsWin.Pt); #endif + vboxNetFltWinMpDeregister(&g_VBoxNetFltGlobalsWin.Mp); + vboxNetFltWinFiniNetFltBase(); /* don't use logging or any RT after de-init */ - NdisFreeSpinLock(&g_GlobalLock); + LogFlow((__FUNCTION__" <== DO (0x%x)\n", DriverObject)); } RT_C_DECLS_BEGIN -NTSTATUS -DriverEntry( - IN PDRIVER_OBJECT DriverObject, - IN PUNICODE_STRING RegistryPath - ); +NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath); RT_C_DECLS_END -/* - * First entry point to be called, when this driver is loaded. - * Register with NDIS as an intermediate driver. - * @return STATUS_SUCCESS if all initialization is successful, STATUS_XXX - * error code if not. - */ -NTSTATUS -DriverEntry( - IN PDRIVER_OBJECT DriverObject, - IN PUNICODE_STRING RegistryPath - ) + +NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; int rc; - ULONG MjVersion; - ULONG MnVersion; - - NdisAllocateSpinLock(&g_GlobalLock); -#ifdef VBOX_NETFLT_ONDEMAND_BIND - /* we are registering in the DriverEntry only when we are working as a protocol - * since in this case our driver is loaded after the VBoxDrv*/ - rc = vboxNetFltWinInitNetFlt(); -#else - /* the idc registration is initiated via IOCTL since our driver - * can be loaded when the VBoxDrv is not in case we are a Ndis IM driver */ + /* the idc registration is initiated via IOCTL since our driver + * can be loaded when the VBoxDrv is not in case we are a Ndis IM driver */ rc = vboxNetFltWinInitNetFltBase(); -#endif AssertRC(rc); - if(RT_SUCCESS(rc)) + if (RT_SUCCESS(rc)) { - PsGetVersion(&MjVersion, &MnVersion, - NULL, /* PULONG BuildNumber OPTIONAL */ - NULL /* PUNICODE_STRING CSDVersion OPTIONAL */ - ); - - g_fPacketDontLoopBack = NDIS_FLAGS_DONT_LOOPBACK; - - if(MjVersion == 5 && MnVersion == 0) - { - /* this is Win2k*/ - g_fPacketDontLoopBack |= NDIS_FLAGS_SKIP_LOOPBACK_W2K; - } - - g_fPacketIsLoopedBack = NDIS_FLAGS_IS_LOOPBACK_PACKET; - - Status = vboxNetFltWinJobInitQueue(&g_JobQueue); + Status = vboxNetFltWinJobInitQueue(&g_VBoxJobQueue); Assert(Status == STATUS_SUCCESS); - if(Status == STATUS_SUCCESS) + if (Status == STATUS_SUCCESS) { + ULONG MjVersion; + ULONG MnVersion; + /* note: we do it after we initialize the Job Queue */ vboxNetFltWinStartInitIdcProbing(); -#ifndef VBOX_NETFLT_ONDEMAND_BIND - Status = vboxNetFltWinMpRegister(DriverObject, RegistryPath); + NdisZeroMemory(&g_VBoxNetFltGlobalsWin, sizeof (g_VBoxNetFltGlobalsWin)); + KeInitializeEvent(&g_VBoxNetFltGlobalsWin.SynchEvent, SynchronizationEvent, TRUE /* signalled*/); + + PsGetVersion(&MjVersion, &MnVersion, + NULL, /* PULONG BuildNumber OPTIONAL */ + NULL /* PUNICODE_STRING CSDVersion OPTIONAL */ + ); + + g_VBoxNetFltGlobalsWin.fPacketDontLoopBack = NDIS_FLAGS_DONT_LOOPBACK; + + if (MjVersion == 5 && MnVersion == 0) + { + /* this is Win2k, we don't support it actually, but just in case */ + g_VBoxNetFltGlobalsWin.fPacketDontLoopBack |= NDIS_FLAGS_SKIP_LOOPBACK_W2K; + } + + g_VBoxNetFltGlobalsWin.fPacketIsLoopedBack = NDIS_FLAGS_IS_LOOPBACK_PACKET; + + Status = vboxNetFltWinMpRegister(&g_VBoxNetFltGlobalsWin.Mp, DriverObject, RegistryPath); Assert(Status == STATUS_SUCCESS); if (Status == NDIS_STATUS_SUCCESS) -#endif { #ifndef VBOXNETADP - Status = vboxNetFltWinPtRegister(DriverObject, RegistryPath); + Status = vboxNetFltWinPtRegister(&g_VBoxNetFltGlobalsWin.Pt, DriverObject, RegistryPath); Assert(Status == STATUS_SUCCESS); if (Status == NDIS_STATUS_SUCCESS) #endif { -#if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP) - vboxNetFltWinAssociateMiniportProtocol(); +#ifndef VBOXNETADP + vboxNetFltWinAssociateMiniportProtocol(&g_VBoxNetFltGlobalsWin); #endif return STATUS_SUCCESS; //#ifndef VBOXNETADP -// vboxNetFltWinPtDeregister(); +// vboxNetFltWinPtDeregister(&g_VBoxNetFltGlobalsWin.Pt); //#endif } -#ifndef VBOX_NETFLT_ONDEMAND_BIND - vboxNetFltWinMpDeregister(); -#endif + vboxNetFltWinMpDeregister(&g_VBoxNetFltGlobalsWin.Mp); } - vboxNetFltWinJobFiniQueue(&g_JobQueue); + vboxNetFltWinJobFiniQueue(&g_VBoxJobQueue); } vboxNetFltWinFiniNetFlt(); } @@ -2036,45 +1759,31 @@ DriverEntry( Status = NDIS_STATUS_FAILURE; } - NdisFreeSpinLock(&g_GlobalLock); - - return(Status); + return Status; } -#if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP) +#ifndef VBOXNETADP /** * creates and initializes the packet to be sent to the underlying miniport given a packet posted to our miniport edge * according to DDK docs we must create our own packet rather than posting the one passed to us */ -DECLHIDDEN(NDIS_STATUS) -vboxNetFltWinPrepareSendPacket( - IN PADAPT pAdapt, - IN PNDIS_PACKET pPacket, - OUT PNDIS_PACKET *ppMyPacket - /*, IN bool bNetFltActive */ - ) +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPrepareSendPacket(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket, PNDIS_PACKET *ppMyPacket) { - NDIS_STATUS fStatus; + NDIS_STATUS Status; - NdisAllocatePacket(&fStatus, - ppMyPacket, - pAdapt->hSendPacketPoolHandle); + NdisAllocatePacket(&Status, ppMyPacket, pNetFlt->u.s.WinIf.hSendPacketPool); - if (fStatus == NDIS_STATUS_SUCCESS) + if (Status == NDIS_STATUS_SUCCESS) { - PSEND_RSVD pSendRsvd; - - pSendRsvd = (PSEND_RSVD)((*ppMyPacket)->ProtocolReserved); - pSendRsvd->pOriginalPkt = pPacket; - pSendRsvd->pBufToFree = NULL; - - NDIS_PACKET_FIRST_NDIS_BUFFER(*ppMyPacket) = NDIS_PACKET_FIRST_NDIS_BUFFER(pPacket); - NDIS_PACKET_LAST_NDIS_BUFFER(*ppMyPacket) = NDIS_PACKET_LAST_NDIS_BUFFER(pPacket); + PVBOXNETFLT_PKTRSVD_PT pSendInfo = (PVBOXNETFLT_PKTRSVD_PT)((*ppMyPacket)->ProtocolReserved); + pSendInfo->pOrigPacket = pPacket; + pSendInfo->pBufToFree = NULL; + /* the rest will be filled on send */ vboxNetFltWinCopyPacketInfoOnSend(*ppMyPacket, pPacket); #ifdef VBOX_LOOPBACK_USEFLAGS - NdisGetPacketFlags(*ppMyPacket) |= g_fPacketDontLoopBack; + NdisGetPacketFlags(*ppMyPacket) |= g_VBoxNetFltGlobalsWin.fPacketDontLoopBack; #endif } else @@ -2082,77 +1791,54 @@ vboxNetFltWinPrepareSendPacket( *ppMyPacket = NULL; } - return fStatus; + return Status; } /** * creates and initializes the packet to be sent to the upperlying protocol given a packet indicated to our protocol edge * according to DDK docs we must create our own packet rather than posting the one passed to us */ -DECLHIDDEN(NDIS_STATUS) -vboxNetFltWinPrepareRecvPacket( - IN PADAPT pAdapt, - IN PNDIS_PACKET pPacket, - OUT PNDIS_PACKET *ppMyPacket, - IN bool bDpr - ) +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPrepareRecvPacket(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket, PNDIS_PACKET *ppMyPacket, bool bDpr) { - NDIS_STATUS fStatus; + NDIS_STATUS Status; - /* - * Get a packet off the pool and indicate that up - */ - if(bDpr) + if (bDpr) { Assert(KeGetCurrentIrql() == DISPATCH_LEVEL); - - NdisDprAllocatePacket(&fStatus, - ppMyPacket, - pAdapt->hRecvPacketPoolHandle); + NdisDprAllocatePacket(&Status, ppMyPacket, pNetFlt->u.s.WinIf.hRecvPacketPool); } else { - NdisAllocatePacket(&fStatus, - ppMyPacket, - pAdapt->hRecvPacketPoolHandle); + NdisAllocatePacket(&Status, ppMyPacket, pNetFlt->u.s.WinIf.hRecvPacketPool); } - if (fStatus == NDIS_STATUS_SUCCESS) + if (Status == NDIS_STATUS_SUCCESS) { - PRECV_RSVD pRecvRsvd; + PVBOXNETFLT_PKTRSVD_MP pRecvInfo = (PVBOXNETFLT_PKTRSVD_MP)((*ppMyPacket)->MiniportReserved); + pRecvInfo->pOrigPacket = pPacket; + pRecvInfo->pBufToFree = NULL; - pRecvRsvd = (PRECV_RSVD)((*ppMyPacket)->MiniportReserved); - pRecvRsvd->pOriginalPkt = pPacket; - pRecvRsvd->pBufToFree = NULL; - - NDIS_PACKET_FIRST_NDIS_BUFFER(*ppMyPacket) = NDIS_PACKET_FIRST_NDIS_BUFFER(pPacket); - NDIS_PACKET_LAST_NDIS_BUFFER(*ppMyPacket) = NDIS_PACKET_LAST_NDIS_BUFFER(pPacket); - - fStatus = vboxNetFltWinCopyPacketInfoOnRecv(*ppMyPacket, pPacket); + Status = vboxNetFltWinCopyPacketInfoOnRecv(*ppMyPacket, pPacket, false); } else { *ppMyPacket = NULL; } - return fStatus; + return Status; } #endif - /** - * initializes the ADAPT (our context structure) and binds to the given adapter + * initializes the VBOXNETFLTINS (our context structure) and binds to the given adapter */ -#if defined(VBOX_NETFLT_ONDEMAND_BIND) -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PADAPT pAdapt) -#elif defined(VBOXNETADP) -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PADAPT *ppAdapt, NDIS_HANDLE hMiniportAdapter, PNDIS_STRING pBindToMiniportName /* actually this is our miniport name*/, NDIS_HANDLE hWrapperConfigurationContext) +#if defined(VBOXNETADP) +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PVBOXNETFLTINS *ppNetFlt, NDIS_HANDLE hMiniportAdapter, PNDIS_STRING pBindToMiniportName /* actually this is our miniport name*/, NDIS_HANDLE hWrapperConfigurationContext) #else -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PADAPT *ppAdapt, PNDIS_STRING pOurMiniportName, PNDIS_STRING pBindToMiniportName) +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PVBOXNETFLTINS *ppNetFlt, PNDIS_STRING pOurMiniportName, PNDIS_STRING pBindToMiniportName) #endif { NDIS_STATUS Status; do { -#ifndef VBOX_NETFLT_ONDEMAND_BIND ANSI_STRING AnsiString; int rc; PVBOXNETFLTINS pInstance; @@ -2177,14 +1863,14 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PADAPT *ppAdapt, PNDIS_STRING pO Status = RtlUnicodeStringToAnsiString(&AnsiString, pBindToMiniportName, true); - if(Status != STATUS_SUCCESS) + if (Status != STATUS_SUCCESS) { break; } rc = vboxNetFltSearchCreateInstance(&g_VBoxNetFltGlobals, AnsiString.Buffer, &pInstance, &Context); RtlFreeAnsiString(&AnsiString); - if(RT_FAILURE(rc)) + if (RT_FAILURE(rc)) { AssertFailed(); Status = Context.Status != NDIS_STATUS_SUCCESS ? Context.Status : NDIS_STATUS_FAILURE; @@ -2193,15 +1879,12 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PADAPT *ppAdapt, PNDIS_STRING pO Assert(pInstance); - if(rc == VINF_ALREADY_INITIALIZED) + if (rc == VINF_ALREADY_INITIALIZED) { - PADAPT pAdapt = PVBOXNETFLTINS_2_PADAPT(pInstance); /* the case when our adapter was unbound while IntNet was connected to it */ - /* the instance remains valid until intNet disconnects from it, we simply search and re-use it*/ - - /* re-initialize PADAPT */ + /* the instance remains valid until IntNet disconnects from it, we simply search and re-use it*/ rc = vboxNetFltWinAttachToInterface(pInstance, &Context, true); - if(RT_FAILURE(rc)) + if (RT_FAILURE(rc)) { AssertFailed(); Status = Context.Status != NDIS_STATUS_SUCCESS ? Context.Status : NDIS_STATUS_FAILURE; @@ -2212,257 +1895,138 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PADAPT *ppAdapt, PNDIS_STRING pO } } - *ppAdapt = PVBOXNETFLTINS_2_PADAPT(pInstance); -#else - Status = vboxNetFltWinPtAllocInitPADAPT(pAdapt); - if (Status != NDIS_STATUS_SUCCESS) - { - break; - } - - Status = vboxNetFltWinPtDoBinding(pAdapt); - if (Status != NDIS_STATUS_SUCCESS) - { - vboxNetFltWinPtFiniPADAPT(pAdapt); - break; - } -#endif - }while(FALSE); - - return Status; -} - -/** - * initializes the ADAPT - */ -#ifdef VBOX_NETFLT_ONDEMAND_BIND -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtAllocInitPADAPT(PADAPT pAdapt) -{ - NDIS_STATUS Status; - - do - { - Status = vboxNetFltWinPtInitPADAPT(pAdapt); - if (Status != NDIS_STATUS_SUCCESS) - { - break; - } - Status = NDIS_STATUS_SUCCESS; - } while(0); - - return Status; -} + *ppNetFlt = pInstance; -/** - * unbinds from the adapter we are bound to and deinitializes the ADAPT - */ -static NDIS_STATUS vboxNetFltWinPtFiniUnbind(PADAPT pAdapt) -{ - NDIS_STATUS Status; - - LogFlow(("==> vboxNetFltWinPtFiniUnbind: Adapt %p\n", pAdapt)); - - Assert(KeGetCurrentIrql() == PASSIVE_LEVEL); - - do - { - Status = vboxNetFltWinPtDoUnbinding(pAdapt, true); - if(Status != NDIS_STATUS_SUCCESS) - { - AssertFailed(); - /* TODO: should we break ? */ - /* break; */ - } - - vboxNetFltWinPtFiniPADAPT(pAdapt); - } while(0); - LogFlow(("<== vboxNetFltWinPtFiniUnbind: Adapt %p\n", pAdapt)); + } while (FALSE); return Status; } -#endif - /* - * deinitializes the ADAPT + * deinitializes the VBOXNETFLTWIN */ -DECLHIDDEN(VOID) vboxNetFltWinPtFiniPADAPT(PADAPT pAdapt) +DECLHIDDEN(VOID) vboxNetFltWinPtFiniWinIf(PVBOXNETFLTWIN pWinIf) { #ifndef VBOXNETADP int rc; #endif - LogFlow(("<== vboxNetFltWinPtFiniPADAPT : pAdapt %p\n", pAdapt)); + LogFlow(("==>"__FUNCTION__" : pWinIf 0x%p\n", pWinIf)); Assert(KeGetCurrentIrql() == PASSIVE_LEVEL); #ifndef VBOXNETADP - if(pAdapt->DeviceName.Buffer) + if (pWinIf->MpDeviceName.Buffer) { - vboxNetFltWinMemFree(pAdapt->DeviceName.Buffer); + vboxNetFltWinMemFree(pWinIf->MpDeviceName.Buffer); } - FINI_INTERLOCKED_SINGLE_LIST(&pAdapt->TransferDataList); + FINI_INTERLOCKED_SINGLE_LIST(&pWinIf->TransferDataList); # if defined(DEBUG_NETFLT_LOOPBACK) || !defined(VBOX_LOOPBACK_USEFLAGS) - FINI_INTERLOCKED_SINGLE_LIST(&pAdapt->SendPacketQueue); + FINI_INTERLOCKED_SINGLE_LIST(&pWinIf->SendPacketQueue); # endif + NdisFreeBufferPool(pWinIf->hSendBufferPool); + NdisFreePacketPool(pWinIf->hSendPacketPool); + rc = RTSemFastMutexDestroy(pWinIf->hSynchRequestMutex); AssertRC(rc); #endif -#ifndef VBOX_NETFLT_ONDEMAND_BIND - /* moved to vboxNetFltWinDetachFromInterfaceWorker */ -#else -# ifndef VBOXNETFLT_NO_PACKET_QUEUE - vboxNetFltWinQuFiniPacketQueue(pAdapt); -# endif -#endif - - vboxNetFltWinFiniBuffers(pAdapt); - - /* - * Free the memory here, if was not released earlier(by calling the HaltHandler) - */ - vboxNetFltWinPtFreeAllPacketPools (pAdapt); -#ifndef VBOXNETADP - rc = RTSemFastMutexDestroy(pAdapt->hSynchRequestMutex); AssertRC(rc); -#endif + /* NOTE: NULL is a valid handle */ + NdisFreeBufferPool(pWinIf->hRecvBufferPool); + NdisFreePacketPool(pWinIf->hRecvPacketPool); - LogFlow(("<== vboxNetFltWinPtFiniPADAPT : pAdapt %p\n", pAdapt)); + LogFlow(("<=="__FUNCTION__" : pWinIf 0x%p\n", pWinIf)); } -DECLHIDDEN(VOID) vboxNetFltWinPtFiniPADAPT(PADAPT pAdapt); #ifndef VBOXNETADP -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitPADAPT(IN PADAPT pAdapt, IN PNDIS_STRING pOurDeviceName) +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitWinIf(PVBOXNETFLTWIN pWinIf, IN PNDIS_STRING pOurDeviceName) #else -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitPADAPT(IN PADAPT pAdapt) +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitWinIf(PVBOXNETFLTWIN pWinIf) #endif { - NDIS_STATUS Status; + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; #ifndef VBOXNETADP int rc; #endif - BOOLEAN bCallFiniOnFail = FALSE; + BOOLEAN bCallFiniOnFail = FALSE; - LogFlow(("==> vboxNetFltWinPtInitPADAPT : pAdapt %p\n", pAdapt)); + LogFlow(("==>"__FUNCTION__": pWinIf 0x%p\n", pWinIf)); Assert(KeGetCurrentIrql() == PASSIVE_LEVEL); - do + NdisZeroMemory(pWinIf, sizeof (VBOXNETFLTWIN)); + NdisAllocatePacketPoolEx(&Status, &pWinIf->hRecvPacketPool, + VBOXNETFLT_PACKET_POOL_SIZE_NORMAL, + VBOXNETFLT_PACKET_POOL_SIZE_OVERFLOW, + PROTOCOL_RESERVED_SIZE_IN_PACKET); + Assert(Status == NDIS_STATUS_SUCCESS); + if (Status == NDIS_STATUS_SUCCESS) { - NdisZeroMemory(pAdapt, sizeof(ADAPT)); -#ifndef VBOXNETADP - NdisInitializeEvent(&pAdapt->hEvent); - - KeInitializeEvent(&pAdapt->hSynchCompletionEvent, SynchronizationEvent, FALSE); - - /* - * Allocate a packet pool for sends. We need this to pass sends down. - * We cannot use the same packet descriptor that came down to our send - * handler (see also NDIS 5.1 packet stacking). - */ - NdisAllocatePacketPoolEx(&Status, - &pAdapt->hSendPacketPoolHandle, - MIN_PACKET_POOL_SIZE, - MAX_PACKET_POOL_SIZE - MIN_PACKET_POOL_SIZE, - sizeof(SEND_RSVD)); - - if (Status != NDIS_STATUS_SUCCESS) - { - pAdapt->hSendPacketPoolHandle = NULL; - break; - } -#else -#endif - - Status = vboxNetFltWinInitBuffers(pAdapt); - if (Status != NDIS_STATUS_SUCCESS) + /* NOTE: NULL is a valid handle !!! */ + NdisAllocateBufferPool(&Status, &pWinIf->hRecvBufferPool, VBOXNETFLT_BUFFER_POOL_SIZE_RX); + Assert(Status == NDIS_STATUS_SUCCESS); + if (Status == NDIS_STATUS_SUCCESS) { - break; - } - - bCallFiniOnFail = TRUE; + pWinIf->MpState.PowerState = NdisDeviceStateD3; + vboxNetFltWinSetOpState(&pWinIf->MpState, kVBoxNetDevOpState_Deinitialized); #ifndef VBOXNETADP - rc = RTSemFastMutexCreate(&pAdapt->hSynchRequestMutex); - if(RT_FAILURE(rc)) - { - Status = NDIS_STATUS_FAILURE; - break; - } -#endif + pWinIf->PtState.PowerState = NdisDeviceStateD3; + vboxNetFltWinSetOpState(&pWinIf->PtState, kVBoxNetDevOpState_Deinitialized); -#ifndef VBOX_NETFLT_ONDEMAND_BIND -# ifndef VBOXNETADP - Status = vboxNetFltWinMemAlloc((PVOID*)&pAdapt->DeviceName.Buffer, pOurDeviceName->Length); - if(Status != NDIS_STATUS_SUCCESS) - { - AssertFailed(); - pAdapt->DeviceName.Buffer = NULL; - break; - } - pAdapt->DeviceName.MaximumLength = pOurDeviceName->Length; - pAdapt->DeviceName.Length = 0; - Status = vboxNetFltWinCopyString(&pAdapt->DeviceName, pOurDeviceName); - if(Status != NDIS_STATUS_SUCCESS) - { - AssertFailed(); - break; - } -# endif + NdisAllocateBufferPool(&Status, + &pWinIf->hSendBufferPool, + VBOXNETFLT_BUFFER_POOL_SIZE_TX); + Assert(Status == NDIS_STATUS_SUCCESS); + if (Status == NDIS_STATUS_SUCCESS) + { + INIT_INTERLOCKED_SINGLE_LIST(&pWinIf->TransferDataList); - /* - * Allocate a packet pool for receives. We need this to indicate receives. - * Same consideration as sends (see also NDIS 5.1 packet stacking). - */ - NdisAllocatePacketPoolEx(&Status, - &pAdapt->hRecvPacketPoolHandle, - MIN_PACKET_POOL_SIZE, - MAX_PACKET_POOL_SIZE - MIN_PACKET_POOL_SIZE, - PROTOCOL_RESERVED_SIZE_IN_PACKET); +# if defined(DEBUG_NETFLT_LOOPBACK) || !defined(VBOX_LOOPBACK_USEFLAGS) + INIT_INTERLOCKED_SINGLE_LIST(&pWinIf->SendPacketQueue); +# endif + NdisInitializeEvent(&pWinIf->OpenCloseEvent); - if (Status != NDIS_STATUS_SUCCESS) - { - pAdapt->hRecvPacketPoolHandle = NULL; - break; - } -#ifndef VBOXNETADP - NdisInitializeEvent(&pAdapt->MiniportInitEvent); -#endif -#endif -#ifndef VBOXNETADP - pAdapt->PTState.PowerState = NdisDeviceStateD3; - vboxNetFltWinSetOpState(&pAdapt->PTState, kVBoxNetDevOpState_Deinitialized); + KeInitializeEvent(&pWinIf->hSynchCompletionEvent, SynchronizationEvent, FALSE); - INIT_INTERLOCKED_SINGLE_LIST(&pAdapt->TransferDataList); + NdisInitializeEvent(&pWinIf->MpInitCompleteEvent); -# if defined(DEBUG_NETFLT_LOOPBACK) || !defined(VBOX_LOOPBACK_USEFLAGS) - INIT_INTERLOCKED_SINGLE_LIST(&pAdapt->SendPacketQueue); -# endif + NdisAllocatePacketPoolEx(&Status, &pWinIf->hSendPacketPool, + VBOXNETFLT_PACKET_POOL_SIZE_NORMAL, + VBOXNETFLT_PACKET_POOL_SIZE_OVERFLOW, + sizeof (PVBOXNETFLT_PKTRSVD_PT)); + Assert(Status == NDIS_STATUS_SUCCESS); + if (Status == NDIS_STATUS_SUCCESS) + { + rc = RTSemFastMutexCreate(&pWinIf->hSynchRequestMutex); + AssertRC(rc); + if (RT_SUCCESS(rc)) + { + Status = vboxNetFltWinMemAlloc((PVOID*)&pWinIf->MpDeviceName.Buffer, pOurDeviceName->Length); + Assert(Status == NDIS_STATUS_SUCCESS); + if (Status == NDIS_STATUS_SUCCESS) + { + pWinIf->MpDeviceName.MaximumLength = pOurDeviceName->Length; + pWinIf->MpDeviceName.Length = 0; + Status = vboxNetFltWinCopyString(&pWinIf->MpDeviceName, pOurDeviceName); #endif - /* TODO: do we need it here ?? */ - pAdapt->MPState.PowerState = NdisDeviceStateD3; - vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized); - -#ifdef VBOX_NETFLT_ONDEMAND_BIND - { - PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt); - rc = vboxNetFltWinConnectIt(pNetFlt); - if(RT_FAILURE(rc)) - { - AssertFailed(); - Status = NDIS_STATUS_FAILURE; - break; + return NDIS_STATUS_SUCCESS; +#ifndef VBOXNETADP + vboxNetFltWinMemFree(pWinIf->MpDeviceName.Buffer); + } + RTSemFastMutexDestroy(pWinIf->hSynchRequestMutex); + } + else + { + Status = NDIS_STATUS_FAILURE; + } + NdisFreePacketPool(pWinIf->hSendPacketPool); + } + NdisFreeBufferPool(pWinIf->hSendBufferPool); } - } #endif - /* moved to vboxNetFltOsInitInstance */ - } while(0); - - if (Status != NDIS_STATUS_SUCCESS) - { - if(bCallFiniOnFail) - { - vboxNetFltWinPtFiniPADAPT(pAdapt); + NdisFreeBufferPool(pWinIf->hRecvBufferPool); } + NdisFreePacketPool(pWinIf->hRecvPacketPool); } - LogFlow(("<== vboxNetFltWinPtInitPADAPT : pAdapt %p, Status %x\n", pAdapt, Status)); + LogFlow(("<=="__FUNCTION__": pWinIf 0x%p, Status 0x%x\n", pWinIf, Status)); return Status; } @@ -2496,13 +2060,13 @@ DECLHIDDEN(PRTNETETHERHDR) vboxNetFltWinGetEthHdr(PNDIS_PACKET pPacket) NdisQueryPacket(pPacket, NULL, &cBufCount1, &pBuffer1, &uTotalPacketLength1); Assert(pBuffer1); - Assert(uTotalPacketLength1 >= ETH_HEADER_SIZE); - if(uTotalPacketLength1 < ETH_HEADER_SIZE) + Assert(uTotalPacketLength1 >= VBOXNETFLT_PACKET_ETHEADER_SIZE); + if (uTotalPacketLength1 < VBOXNETFLT_PACKET_ETHEADER_SIZE) return NULL; NdisQueryBufferSafe(pBuffer1, &pEth, &cbLength1, NormalPagePriority); - Assert(cbLength1 >= ETH_HEADER_SIZE); - if(cbLength1 < ETH_HEADER_SIZE) + Assert(cbLength1 >= VBOXNETFLT_PACKET_ETHEADER_SIZE); + if (cbLength1 < VBOXNETFLT_PACKET_ETHEADER_SIZE) return NULL; return pEth; @@ -2512,12 +2076,12 @@ DECLHIDDEN(PRTNETETHERHDR) vboxNetFltWinGetEthHdrSG(PINTNETSG pSG) { Assert(pSG->cSegsUsed); Assert(pSG->cSegsAlloc >= pSG->cSegsUsed); - Assert(pSG->aSegs[0].cb >= ETH_HEADER_SIZE); + Assert(pSG->aSegs[0].cb >= VBOXNETFLT_PACKET_ETHEADER_SIZE); - if(!pSG->cSegsUsed) + if (!pSG->cSegsUsed) return NULL; - if(pSG->aSegs[0].cb < ETH_HEADER_SIZE) + if (pSG->aSegs[0].cb < VBOXNETFLT_PACKET_ETHEADER_SIZE) return NULL; return (PRTNETETHERHDR)pSG->aSegs[0].pv; @@ -2528,13 +2092,13 @@ DECLHIDDEN(bool) vboxNetFltWinCheckMACs(PNDIS_PACKET pPacket, PRTMAC pDst, PRTMA PRTNETETHERHDR pHdr = vboxNetFltWinGetEthHdr(pPacket); Assert(pHdr); - if(!pHdr) + if (!pHdr) return false; - if(pDst && memcmp(pDst, &pHdr->DstMac, sizeof(RTMAC))) + if (pDst && memcmp(pDst, &pHdr->DstMac, sizeof(RTMAC))) return false; - if(pSrc && memcmp(pSrc, &pHdr->SrcMac, sizeof(RTMAC))) + if (pSrc && memcmp(pSrc, &pHdr->SrcMac, sizeof(RTMAC))) return false; return true; @@ -2545,13 +2109,13 @@ DECLHIDDEN(bool) vboxNetFltWinCheckMACsSG(PINTNETSG pSG, PRTMAC pDst, PRTMAC pSr PRTNETETHERHDR pHdr = vboxNetFltWinGetEthHdrSG(pSG); Assert(pHdr); - if(!pHdr) + if (!pHdr) return false; - if(pDst && memcmp(pDst, &pHdr->DstMac, sizeof(RTMAC))) + if (pDst && memcmp(pDst, &pHdr->DstMac, sizeof(RTMAC))) return false; - if(pSrc && memcmp(pSrc, &pHdr->SrcMac, sizeof(RTMAC))) + if (pSrc && memcmp(pSrc, &pHdr->SrcMac, sizeof(RTMAC))) return false; return true; @@ -2588,7 +2152,7 @@ DECLHIDDEN(bool) vboxNetFltWinMatchPackets(PNDIS_PACKET pPacket1, PNDIS_PACKET p Assert(pBuffer1); Assert(pBuffer2); - if(uTotalPacketLength1 != uTotalPacketLength2) + if (uTotalPacketLength1 != uTotalPacketLength2) { bMatch = false; } @@ -2596,7 +2160,7 @@ DECLHIDDEN(bool) vboxNetFltWinMatchPackets(PNDIS_PACKET pPacket1, PNDIS_PACKET p { UINT ucbLength2Match = 0; UINT ucbMatch; - if(cbMatch < 0 || (UINT)cbMatch > uTotalPacketLength1) + if (cbMatch < 0 || (UINT)cbMatch > uTotalPacketLength1) { /* NOTE: assuming uTotalPacketLength1 == uTotalPacketLength2*/ ucbMatch = uTotalPacketLength1; @@ -2609,9 +2173,9 @@ DECLHIDDEN(bool) vboxNetFltWinMatchPackets(PNDIS_PACKET pPacket1, PNDIS_PACKET p ucbMatch = (UINT)cbMatch; } - for(;;) + for (;;) { - if(!cbLength1) + if (!cbLength1) { NdisQueryBufferSafe(pBuffer1, &pMemBuf1, &cbLength1, NormalPagePriority); NdisGetNextBuffer(pBuffer1, &pBuffer1); @@ -2623,7 +2187,7 @@ DECLHIDDEN(bool) vboxNetFltWinMatchPackets(PNDIS_PACKET pPacket1, PNDIS_PACKET p pMemBuf1 += ucbLength2Match; } - if(!cbLength2) + if (!cbLength2) { NdisQueryBufferSafe(pBuffer2, &pMemBuf2, &cbLength2, NormalPagePriority); NdisGetNextBuffer(pBuffer2, &pBuffer2); @@ -2638,14 +2202,14 @@ DECLHIDDEN(bool) vboxNetFltWinMatchPackets(PNDIS_PACKET pPacket1, PNDIS_PACKET p ucbLength2Match = MIN(ucbMatch, cbLength1); ucbLength2Match = MIN(ucbLength2Match, cbLength2); - if(memcmp((PVOID*)pMemBuf1, (PVOID*)pMemBuf2, ucbLength2Match)) + if (memcmp((PVOID*)pMemBuf1, (PVOID*)pMemBuf2, ucbLength2Match)) { bMatch = false; break; } ucbMatch -= ucbLength2Match; - if(!ucbMatch) + if (!ucbMatch) break; cbLength1 -= ucbLength2Match; @@ -2654,7 +2218,7 @@ DECLHIDDEN(bool) vboxNetFltWinMatchPackets(PNDIS_PACKET pPacket1, PNDIS_PACKET p } #ifdef DEBUG_NETFLT_PACKETS - if(bMatch && !bCompleteMatch) + if (bMatch && !bCompleteMatch) { /* check that the packets fully match */ DBG_CHECK_PACKETS(pPacket1, pPacket2); @@ -2688,7 +2252,7 @@ DECLHIDDEN(bool) vboxNetFltWinMatchPacketAndSG(PNDIS_PACKET pPacket, PINTNETSG p Assert(pSG->cSegsUsed); Assert(pSG->cSegsAlloc >= pSG->cSegsUsed); - if(uTotalPacketLength1 != uTotalPacketLength2) + if (uTotalPacketLength1 != uTotalPacketLength2) { AssertFailed(); bMatch = false; @@ -2698,7 +2262,7 @@ DECLHIDDEN(bool) vboxNetFltWinMatchPacketAndSG(PNDIS_PACKET pPacket, PINTNETSG p UINT ucbLength2Match = 0; UINT ucbMatch; - if(cbMatch < 0 || (UINT)cbMatch > uTotalPacketLength1) + if (cbMatch < 0 || (UINT)cbMatch > uTotalPacketLength1) { /* NOTE: assuming uTotalPacketLength1 == uTotalPacketLength2*/ ucbMatch = uTotalPacketLength1; @@ -2709,9 +2273,9 @@ DECLHIDDEN(bool) vboxNetFltWinMatchPacketAndSG(PNDIS_PACKET pPacket, PINTNETSG p ucbMatch = (UINT)cbMatch; } - for(;;) + for (;;) { - if(!cbLength1) + if (!cbLength1) { NdisQueryBufferSafe(pBuffer1, &pMemBuf1, &cbLength1, NormalPagePriority); NdisGetNextBuffer(pBuffer1, &pBuffer1); @@ -2723,7 +2287,7 @@ DECLHIDDEN(bool) vboxNetFltWinMatchPacketAndSG(PNDIS_PACKET pPacket, PINTNETSG p pMemBuf1 += ucbLength2Match; } - if(!cbLength2) + if (!cbLength2) { Assert(i < pSG->cSegsUsed); pMemBuf2 = (uint8_t*)pSG->aSegs[i].pv; @@ -2740,7 +2304,7 @@ DECLHIDDEN(bool) vboxNetFltWinMatchPacketAndSG(PNDIS_PACKET pPacket, PINTNETSG p ucbLength2Match = MIN(ucbMatch, cbLength1); ucbLength2Match = MIN(ucbLength2Match, cbLength2); - if(memcmp((PVOID*)pMemBuf1, (PVOID*)pMemBuf2, ucbLength2Match)) + if (memcmp((PVOID*)pMemBuf1, (PVOID*)pMemBuf2, ucbLength2Match)) { bMatch = false; AssertFailed(); @@ -2748,7 +2312,7 @@ DECLHIDDEN(bool) vboxNetFltWinMatchPacketAndSG(PNDIS_PACKET pPacket, PINTNETSG p } ucbMatch -= ucbLength2Match; - if(!ucbMatch) + if (!ucbMatch) break; cbLength1 -= ucbLength2Match; @@ -2756,7 +2320,7 @@ DECLHIDDEN(bool) vboxNetFltWinMatchPacketAndSG(PNDIS_PACKET pPacket, PINTNETSG p } } - if(bMatch && !bCompleteMatch) + if (bMatch && !bCompleteMatch) { /* check that the packets fully match */ DBG_CHECK_PACKET_AND_SG(pPacket, pSG); @@ -2788,7 +2352,7 @@ static bool vboxNetFltWinMatchSGs(PINTNETSG pSG1, PINTNETSG pSG2, const INT cbMa Assert(pSG1->cSegsAlloc >= pSG1->cSegsUsed); Assert(pSG2->cSegsAlloc >= pSG2->cSegsUsed); - if(uTotalPacketLength1 != uTotalPacketLength2) + if (uTotalPacketLength1 != uTotalPacketLength2) { AssertFailed(); bMatch = false; @@ -2796,7 +2360,7 @@ static bool vboxNetFltWinMatchSGs(PINTNETSG pSG1, PINTNETSG pSG2, const INT cbMa else { UINT ucbMatch; - if(cbMatch < 0 || (UINT)cbMatch > uTotalPacketLength1) + if (cbMatch < 0 || (UINT)cbMatch > uTotalPacketLength1) { /* NOTE: assuming uTotalPacketLength1 == uTotalPacketLength2*/ ucbMatch = uTotalPacketLength1; @@ -2810,7 +2374,7 @@ static bool vboxNetFltWinMatchSGs(PINTNETSG pSG1, PINTNETSG pSG2, const INT cbMa do { UINT ucbLength2Match; - if(!cbLength1) + if (!cbLength1) { Assert(i1 < pSG1->cSegsUsed); pMemBuf1 = pSG1->aSegs[i1].pv; @@ -2818,7 +2382,7 @@ static bool vboxNetFltWinMatchSGs(PINTNETSG pSG1, PINTNETSG pSG2, const INT cbMa i1++; } - if(!cbLength2) + if (!cbLength2) { Assert(i2 < pSG2->cSegsUsed); pMemBuf2 = pSG2->aSegs[i2].pv; @@ -2829,7 +2393,7 @@ static bool vboxNetFltWinMatchSGs(PINTNETSG pSG1, PINTNETSG pSG2, const INT cbMa ucbLength2Match = MIN(ucbMatch, cbLength1); ucbLength2Match = MIN(ucbLength2Match, cbLength2); - if(memcmp(pMemBuf1, pMemBuf2, ucbLength2Match)) + if (memcmp(pMemBuf1, pMemBuf2, ucbLength2Match)) { bMatch = false; AssertFailed(); @@ -2841,7 +2405,7 @@ static bool vboxNetFltWinMatchSGs(PINTNETSG pSG1, PINTNETSG pSG2, const INT cbMa } while (ucbMatch); } - if(bMatch && !bCompleteMatch) + if (bMatch && !bCompleteMatch) { /* check that the packets fully match */ DBG_CHECK_SGS(pSG1, pSG2); @@ -2876,12 +2440,12 @@ static int vboxNetFltWinTryFiniIdc() vboxNetFltWinStopInitIdcProbing(); - if(g_bIdcInitialized) + if (g_bVBoxIdcInitialized) { rc = vboxNetFltTryDeleteIdc(&g_VBoxNetFltGlobals); - if(RT_SUCCESS(rc)) + if (RT_SUCCESS(rc)) { - g_bIdcInitialized = false; + g_bVBoxIdcInitialized = false; } } else @@ -2895,7 +2459,7 @@ static int vboxNetFltWinTryFiniIdc() static int vboxNetFltWinFiniNetFlt() { int rc = vboxNetFltWinTryFiniIdc(); - if(RT_SUCCESS(rc)) + if (RT_SUCCESS(rc)) { vboxNetFltWinFiniNetFltBase(); } @@ -2911,7 +2475,7 @@ static int vboxNetFltWinInitNetFltBase() do { - Assert(!g_bIdcInitialized); + Assert(!g_bVBoxIdcInitialized); rc = RTR0Init(0); if (!RT_SUCCESS(rc)) @@ -2926,7 +2490,7 @@ static int vboxNetFltWinInitNetFltBase() RTR0Term(); break; } - }while(0); + }while (0); return rc; } @@ -2940,11 +2504,8 @@ static int vboxNetFltWinInitIdc() do { - if(g_bIdcInitialized) + if (g_bVBoxIdcInitialized) { -#ifdef VBOX_NETFLT_ONDEMAND_BIND - AssertFailed(); -#endif rc = VINF_ALREADY_INITIALIZED; break; } @@ -2961,25 +2522,26 @@ static int vboxNetFltWinInitIdc() break; } - g_bIdcInitialized = true; + g_bVBoxIdcInitialized = true; } while (0); return rc; } -static void vboxNetFltWinInitIdcProbingWorker(PINIT_IDC_INFO pInitIdcInfo) +static VOID vboxNetFltWinInitIdcProbingWorker(PVOID pvContext) { + PINIT_IDC_INFO pInitIdcInfo = (PINIT_IDC_INFO)pvContext; int rc = vboxNetFltWinInitIdc(); - if(RT_FAILURE(rc)) + if (RT_FAILURE(rc)) { bool bInterupted = ASMAtomicUoReadBool(&pInitIdcInfo->bStop); - if(!bInterupted) + if (!bInterupted) { RTThreadSleep(1000); /* 1 s */ bInterupted = ASMAtomicUoReadBool(&pInitIdcInfo->bStop); - if(!bInterupted) + if (!bInterupted) { - vboxNetFltWinJobEnqueueJob(&g_JobQueue, &pInitIdcInfo->Job, false); + vboxNetFltWinJobEnqueueJob(&g_VBoxJobQueue, &pInitIdcInfo->Job, false); return; } } @@ -2988,29 +2550,29 @@ static void vboxNetFltWinInitIdcProbingWorker(PINIT_IDC_INFO pInitIdcInfo) rc = VERR_INTERRUPTED; } - ASMAtomicUoWriteU32(&pInitIdcInfo->rc, rc); + ASMAtomicUoWriteS32(&pInitIdcInfo->rc, rc); KeSetEvent(&pInitIdcInfo->hCompletionEvent, 0, FALSE); } static int vboxNetFltWinStopInitIdcProbing() { - if(!g_InitIdcInfo.bInitialized) + if (!g_VBoxInitIdcInfo.bInitialized) return VERR_INVALID_STATE; - ASMAtomicUoWriteBool(&g_InitIdcInfo.bStop, true); - KeWaitForSingleObject(&g_InitIdcInfo.hCompletionEvent, Executive, KernelMode, FALSE, NULL); + ASMAtomicUoWriteBool(&g_VBoxInitIdcInfo.bStop, true); + KeWaitForSingleObject(&g_VBoxInitIdcInfo.hCompletionEvent, Executive, KernelMode, FALSE, NULL); - return g_InitIdcInfo.rc; + return g_VBoxInitIdcInfo.rc; } static int vboxNetFltWinStartInitIdcProbing() { - Assert(!g_bIdcInitialized); - KeInitializeEvent(&g_InitIdcInfo.hCompletionEvent, NotificationEvent, FALSE); - g_InitIdcInfo.bStop = false; - g_InitIdcInfo.bInitialized = true; - vboxNetFltWinJobInit(&g_InitIdcInfo.Job, vboxNetFltWinInitIdcProbingWorker, &g_InitIdcInfo, false); - vboxNetFltWinJobEnqueueJob(&g_JobQueue, &g_InitIdcInfo.Job, false); + Assert(!g_bVBoxIdcInitialized); + KeInitializeEvent(&g_VBoxInitIdcInfo.hCompletionEvent, NotificationEvent, FALSE); + g_VBoxInitIdcInfo.bStop = false; + g_VBoxInitIdcInfo.bInitialized = true; + vboxNetFltWinJobInit(&g_VBoxInitIdcInfo.Job, vboxNetFltWinInitIdcProbingWorker, &g_VBoxInitIdcInfo, false); + vboxNetFltWinJobEnqueueJob(&g_VBoxJobQueue, &g_VBoxInitIdcInfo.Job, false); return VINF_SUCCESS; } @@ -3021,7 +2583,7 @@ static int vboxNetFltWinInitNetFlt() do { rc = vboxNetFltWinInitNetFltBase(); - if(RT_FAILURE(rc)) + if (RT_FAILURE(rc)) { AssertFailed(); break; @@ -3048,40 +2610,26 @@ static int vboxNetFltWinInitNetFlt() /* detach*/ static int vboxNetFltWinDeleteInstance(PVBOXNETFLTINS pThis) { - PADAPT pAdapt = PVBOXNETFLTINS_2_PADAPT(pThis); RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; - NDIS_STATUS Status; - LogFlow(("vboxNetFltWinDeleteInstance: pThis=%p \n", pThis)); + LogFlow(("vboxNetFltWinDeleteInstance: pThis=0x%p \n", pThis)); Assert(KeGetCurrentIrql() < DISPATCH_LEVEL); - Assert(pAdapt); Assert(pThis); Assert(pThis->fDisconnectedFromHost); Assert(!pThis->fRediscoveryPending); Assert(pThis->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE); #ifndef VBOXNETADP - Assert(pAdapt->PTState.OpState == kVBoxNetDevOpState_Deinitialized); - Assert(!pAdapt->hBindingHandle); + Assert(pThis->u.s.WinIf.PtState.OpState == kVBoxNetDevOpState_Deinitialized); + Assert(!pThis->u.s.WinIf.hBinding); #endif - Assert(pAdapt->MPState.OpState == kVBoxNetDevOpState_Deinitialized); + Assert(pThis->u.s.WinIf.MpState.OpState == kVBoxNetDevOpState_Deinitialized); #ifndef VBOXNETFLT_NO_PACKET_QUEUE Assert(!pThis->u.s.PacketQueueWorker.pSG); #endif -// Assert(!pAdapt->hMiniportHandle); -#ifndef VBOX_NETFLT_ONDEMAND_BIND - Status = vboxNetFltWinMpDereferenceControlDevice(); - Assert(Status == NDIS_STATUS_SUCCESS); -#else - Status = vboxNetFltWinPtFiniUnbind(pAdapt); - if(Status != NDIS_STATUS_SUCCESS) - { - AssertFailed(); - /* pDetachInfo->Status = VERR_GENERAL_FAILURE; */ - } -#endif + RTSemMutexDestroy(pThis->u.s.hWinIfMutex); - RTSemMutexDestroy(pThis->u.s.hAdaptMutex); + vboxNetFltWinDrvDereference(); return VINF_SUCCESS; } @@ -3095,88 +2643,62 @@ static NDIS_STATUS vboxNetFltWinDisconnectIt(PVBOXNETFLTINS pInstance) } /* detach*/ -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinDetachFromInterface(PADAPT pAdapt, bool bOnUnbind) +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinDetachFromInterface(PVBOXNETFLTINS pNetFlt, bool bOnUnbind) { - PVBOXNETFLTINS pThis = PADAPT_2_PVBOXNETFLTINS(pAdapt); RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; NDIS_STATUS Status; int rc; - LogFlow(("vboxNetFltWinDetachFromInterface: pThis=%p\n", pThis)); + LogFlow((__FUNCTION__": pThis=%0xp\n", pNetFlt)); Assert(KeGetCurrentIrql() < DISPATCH_LEVEL); - Assert(pAdapt); - Assert(pThis); -/* Assert(!pThis->fActive); */ + Assert(pNetFlt); - /* paranoia to ensyre the instance is not removed while we're waiting on the mutex + /* paranoia to ensure the instance is not removed while we're waiting on the mutex * in case ndis does something unpredictable, e.g. calls our miniport halt independently * from protocol unbind and concurrently with it*/ - vboxNetFltRetain(pThis, false); + vboxNetFltRetain(pNetFlt, false); - rc = RTSemMutexRequest(pThis->u.s.hAdaptMutex, RT_INDEFINITE_WAIT); - if(RT_SUCCESS(rc)) + rc = RTSemMutexRequest(pNetFlt->u.s.hWinIfMutex, RT_INDEFINITE_WAIT); + if (RT_SUCCESS(rc)) { -#ifndef VBOX_NETFLT_ONDEMAND_BIND - Assert(vboxNetFltWinGetAdaptState(pAdapt) == kVBoxAdaptState_Connected); - Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Initialized); + Assert(vboxNetFltWinGetWinIfState(pNetFlt) == kVBoxWinIfState_Connected); + Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Initialized); #ifndef VBOXNETADP - Assert(vboxNetFltWinGetOpState(&pAdapt->PTState) == kVBoxNetDevOpState_Initialized); -#endif -// if( -//#ifdef VBOXNETADP -// vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Initialized -//#else -// vboxNetFltWinGetOpState(&pAdapt->PTState) == kVBoxNetDevOpState_Initialized -//// && vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Initialized -//#endif -// ) - if(vboxNetFltWinGetAdaptState(pAdapt) == kVBoxAdaptState_Connected) + Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.PtState) == kVBoxNetDevOpState_Initialized); +#endif + if (vboxNetFltWinGetWinIfState(pNetFlt) == kVBoxWinIfState_Connected) { - vboxNetFltWinSetAdaptState(pAdapt, kVBoxAdaptState_Disconnecting); + vboxNetFltWinSetWinIfState(pNetFlt, kVBoxWinIfState_Disconnecting); #ifndef VBOXNETADP - Status = vboxNetFltWinPtDoUnbinding(pAdapt, bOnUnbind); + Status = vboxNetFltWinPtDoUnbinding(pNetFlt, bOnUnbind); #else - Status = vboxNetFltWinMpDoDeinitialization(pAdapt); + Status = vboxNetFltWinMpDoDeinitialization(pNetFlt); #endif Assert(Status == NDIS_STATUS_SUCCESS); - vboxNetFltWinSetAdaptState(pAdapt, kVBoxAdaptState_Disconnected); - Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitialized); + vboxNetFltWinSetWinIfState(pNetFlt, kVBoxWinIfState_Disconnected); + Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized); #ifndef VBOXNETADP - Assert(vboxNetFltWinGetOpState(&pAdapt->PTState) == kVBoxNetDevOpState_Deinitialized); + Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.PtState) == kVBoxNetDevOpState_Deinitialized); #endif -// /* paranoia */ -// vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized); -//#ifndef VBOXNETADP -// vboxNetFltWinSetOpState(&pAdapt->PTState, kVBoxNetDevOpState_Deinitialized); -//#endif - - vboxNetFltWinPtFiniPADAPT(pAdapt); + vboxNetFltWinPtFiniWinIf(&pNetFlt->u.s.WinIf); /* we're unbinding, make an unbind-related release */ - vboxNetFltRelease(pThis, false); -#else - Status = vboxNetFltWinPtFiniUnbind(pAdapt); - if(Status != NDIS_STATUS_SUCCESS) - { - AssertFailed(); - /* pDetachInfo->Status = VERR_GENERAL_FAILURE; */ - } -#endif + vboxNetFltRelease(pNetFlt, false); } else { AssertBreakpoint(); #ifndef VBOXNETADP - pAdapt->Status = NDIS_STATUS_FAILURE; + pNetFlt->u.s.WinIf.OpenCloseStatus = NDIS_STATUS_FAILURE; #endif - if(!bOnUnbind) + if (!bOnUnbind) { - vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized); + vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized); } Status = NDIS_STATUS_FAILURE; } - RTSemMutexRelease(pThis->u.s.hAdaptMutex); + RTSemMutexRelease(pNetFlt->u.s.hWinIfMutex); } else { @@ -3185,7 +2707,7 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinDetachFromInterface(PADAPT pAdapt, bool bOn } /* release for the retain we made before waining on the mutex */ - vboxNetFltRelease(pThis, false); + vboxNetFltRelease(pNetFlt, false); return Status; } @@ -3200,17 +2722,16 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinDetachFromInterface(PADAPT pAdapt, bool bOn static bool vboxNetFltWinIsPromiscuous2(PVBOXNETFLTINS pThis) { #ifndef VBOXNETADP - PADAPT pAdapt = PVBOXNETFLTINS_2_PADAPT(pThis); - if(VBOXNETFLT_PROMISCUOUS_SUPPORTED(pAdapt)) + if (VBOXNETFLT_PROMISCUOUS_SUPPORTED(pThis)) { bool bPromiscuous; - if(!vboxNetFltWinReferenceAdapt(pAdapt)) + if (!vboxNetFltWinReferenceWinIf(pThis)) return false; - bPromiscuous = (pAdapt->fUpperProtocolSetFilter & NDIS_PACKET_TYPE_PROMISCUOUS) == NDIS_PACKET_TYPE_PROMISCUOUS; + bPromiscuous = (pThis->u.s.WinIf.fUpperProtocolSetFilter & NDIS_PACKET_TYPE_PROMISCUOUS) == NDIS_PACKET_TYPE_PROMISCUOUS; /*vboxNetFltWinIsPromiscuous(pAdapt);*/ - vboxNetFltWinDereferenceAdapt(pAdapt); + vboxNetFltWinDereferenceWinIf(pThis); return bPromiscuous; } return false; @@ -3231,7 +2752,7 @@ static bool vboxNetFltWinIsPromiscuous2(PVBOXNETFLTINS pThis) static void vboxNetFltWinReportStuff(PVBOXNETFLTINS pThis) { /** @todo Keep these up to date, esp. the promiscuous mode bit. */ - if ( pThis->pSwitchPort + if (pThis->pSwitchPort && vboxNetFltTryRetainBusyNotDisconnected(pThis)) { pThis->pSwitchPort->pfnReportMacAddress(pThis->pSwitchPort, &pThis->u.s.MacAddr); @@ -3256,142 +2777,101 @@ static void vboxNetFltWinAttachToInterfaceWorker(PATTACH_INFO pAttachInfo) PVBOXNETFLTINS pThis = pAttachInfo->pNetFltIf; NDIS_STATUS Status = NDIS_STATUS_SUCCESS; int rc; - PADAPT pAdapt = PVBOXNETFLTINS_2_PADAPT(pThis); Assert(KeGetCurrentIrql() == PASSIVE_LEVEL); /* to ensure we're not removed while we're here */ vboxNetFltRetain(pThis, false); - rc = RTSemMutexRequest(pThis->u.s.hAdaptMutex, RT_INDEFINITE_WAIT); - if(RT_SUCCESS(rc)) + rc = RTSemMutexRequest(pThis->u.s.hWinIfMutex, RT_INDEFINITE_WAIT); + if (RT_SUCCESS(rc)) { RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; - Assert(vboxNetFltWinGetAdaptState(pAdapt) == kVBoxAdaptState_Disconnected); - Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitialized); + Assert(vboxNetFltWinGetWinIfState(pThis) == kVBoxWinIfState_Disconnected); + Assert(vboxNetFltWinGetOpState(&pThis->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized); #ifndef VBOXNETADP - Assert(vboxNetFltWinGetOpState(&pAdapt->PTState) == kVBoxNetDevOpState_Deinitialized); + Assert(vboxNetFltWinGetOpState(&pThis->u.s.WinIf.PtState) == kVBoxNetDevOpState_Deinitialized); #endif -// if(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitialized -//#ifndef VBOXNETADP -// && vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitialized -//#endif -// ) - if(vboxNetFltWinGetAdaptState(pAdapt) == kVBoxAdaptState_Disconnected) + if (vboxNetFltWinGetWinIfState(pThis) == kVBoxWinIfState_Disconnected) { - -#ifndef VBOX_NETFLT_ONDEMAND_BIND - if(pAttachInfo->fRediscovery) + if (pAttachInfo->fRediscovery) { /* rediscovery means adaptor bind is performed while intnet is already using it * i.e. adaptor was unbound while being used by intnet and now being bound back again */ Assert(((VBOXNETFTLINSSTATE)ASMAtomicUoReadU32((uint32_t volatile *)&pThis->enmState)) == kVBoxNetFltInsState_Connected); } #ifndef VBOXNETADP - Status = vboxNetFltWinPtInitPADAPT(pAdapt, pAttachInfo->pCreateContext->pOurName); + Status = vboxNetFltWinPtInitWinIf(&pThis->u.s.WinIf, pAttachInfo->pCreateContext->pOurName); #else - Status = vboxNetFltWinPtInitPADAPT(pAdapt); + Status = vboxNetFltWinPtInitWinIf(&pThis->u.s.WinIf); #endif - if(Status == NDIS_STATUS_SUCCESS) + if (Status == NDIS_STATUS_SUCCESS) { - vboxNetFltWinSetAdaptState(pAdapt, kVBoxAdaptState_Connecting); + vboxNetFltWinSetWinIfState(pThis, kVBoxWinIfState_Connecting); #ifndef VBOXNETADP - Status = vboxNetFltWinPtDoBinding(pAdapt, pAttachInfo->pCreateContext->pOurName, pAttachInfo->pCreateContext->pBindToName); + Status = vboxNetFltWinPtDoBinding(pThis, pAttachInfo->pCreateContext->pOurName, pAttachInfo->pCreateContext->pBindToName); #else - Status = vboxNetFltWinMpDoInitialization(pAdapt, pAttachInfo->pCreateContext->hMiniportAdapter, pAttachInfo->pCreateContext->hWrapperConfigurationContext); + Status = vboxNetFltWinMpDoInitialization(pThis, pAttachInfo->pCreateContext->hMiniportAdapter, pAttachInfo->pCreateContext->hWrapperConfigurationContext); #endif if (Status == NDIS_STATUS_SUCCESS) { - if(pAttachInfo->fRediscovery || (Status = vboxNetFltWinMpReferenceControlDevice()) == NDIS_STATUS_SUCCESS) + if (!pAttachInfo->fRediscovery) { + vboxNetFltWinDrvReference(); + } #ifndef VBOXNETADP - if(pAdapt->Status == NDIS_STATUS_SUCCESS) + if (pThis->u.s.WinIf.OpenCloseStatus == NDIS_STATUS_SUCCESS) #endif - { - vboxNetFltWinSetAdaptState(pAdapt, kVBoxAdaptState_Connected); -// Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Initialized); + { + vboxNetFltWinSetWinIfState(pThis, kVBoxWinIfState_Connected); #ifndef VBOXNETADP - Assert(vboxNetFltWinGetOpState(&pAdapt->PTState) == kVBoxNetDevOpState_Initialized); + Assert(vboxNetFltWinGetOpState(&pThis->u.s.WinIf.PtState) == kVBoxNetDevOpState_Initialized); #endif -// /* paranoia */ -//// vboxNetFltWinSetAdaptState(&pAdapt->MPState, kVBoxNetDevOpState_Initialized); -//#ifndef VBOXNETADP -// vboxNetFltWinSetOpState(&pAdapt->PTState, kVBoxNetDevOpState_Initialized); -//#endif - - - /* 4. mark as connected */ - RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp); - ASMAtomicUoWriteBool(&pThis->fDisconnectedFromHost, false); - RTSpinlockReleaseNoInts(pThis->hSpinlock, &Tmp); + /* 4. mark as connected */ + RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp); + ASMAtomicUoWriteBool(&pThis->fDisconnectedFromHost, false); + RTSpinlockReleaseNoInts(pThis->hSpinlock, &Tmp); - pAttachInfo->Status = VINF_SUCCESS; - pAttachInfo->pCreateContext->Status = NDIS_STATUS_SUCCESS; + pAttachInfo->Status = VINF_SUCCESS; + pAttachInfo->pCreateContext->Status = NDIS_STATUS_SUCCESS; - RTSemMutexRelease(pThis->u.s.hAdaptMutex); + RTSemMutexRelease(pThis->u.s.hWinIfMutex); - vboxNetFltRelease(pThis, false); + vboxNetFltRelease(pThis, false); - /* 5. Report MAC address, promiscuousness and GSO capabilities. */ - vboxNetFltWinReportStuff(pThis); + /* 5. Report MAC address, promiscuousness and GSO capabilities. */ + vboxNetFltWinReportStuff(pThis); - return; - } - AssertBreakpoint(); - - if(!pAttachInfo->fRediscovery) - { - vboxNetFltWinMpDereferenceControlDevice(); - } + return; } AssertBreakpoint(); + + if (!pAttachInfo->fRediscovery) + { + vboxNetFltWinDrvDereference(); + } #ifndef VBOXNETADP - vboxNetFltWinPtDoUnbinding(pAdapt, true); + vboxNetFltWinPtDoUnbinding(pThis, true); #else - vboxNetFltWinMpDoDeinitialization(pAdapt); + vboxNetFltWinMpDoDeinitialization(pThis); #endif } AssertBreakpoint(); - vboxNetFltWinPtFiniPADAPT(pAdapt); + vboxNetFltWinPtFiniWinIf(&pThis->u.s.WinIf); } AssertBreakpoint(); - vboxNetFltWinSetAdaptState(pAdapt, kVBoxAdaptState_Disconnected); - Assert(vboxNetFltWinGetOpState(&pAdapt->MPState) == kVBoxNetDevOpState_Deinitialized); + vboxNetFltWinSetWinIfState(pThis, kVBoxWinIfState_Disconnected); + Assert(vboxNetFltWinGetOpState(&pThis->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized); #ifndef VBOXNETADP - Assert(vboxNetFltWinGetOpState(&pAdapt->PTState) == kVBoxNetDevOpState_Deinitialized); + Assert(vboxNetFltWinGetOpState(&pThis->u.s.WinIf.PtState) == kVBoxNetDevOpState_Deinitialized); #endif -// /* paranoia */ -// vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized); -//#ifndef VBOXNETADP -// vboxNetFltWinSetOpState(&pAdapt->PTState, kVBoxNetDevOpState_Deinitialized); -//#endif } AssertBreakpoint(); -#else /* VBOX_NETFLT_ONDEMAND_BIND */ - Assert(KeGetCurrentIrql() == PASSIVE_LEVEL); - - Status = vboxNetFltWinPtInitBind(pAdapt); - if (Status != NDIS_STATUS_SUCCESS) - { - pAttachInfo->Status = VERR_GENERAL_FAILURE; - break; - } - - Status = vboxNetFltWinGetMacAddress(pAdapt, &pThis->u.s.MacAddr); - if (Status != NDIS_STATUS_SUCCESS) - { - vboxNetFltWinPtFiniUnbind(pAdapt); - pAttachInfo->Status = VERR_GENERAL_FAILURE; - break; - } -#endif /* VBOX_NETFLT_ONDEMAND_BIND */ - - pAttachInfo->Status = VERR_GENERAL_FAILURE; pAttachInfo->pCreateContext->Status = Status; - RTSemMutexRelease(pThis->u.s.hAdaptMutex); + RTSemMutexRelease(pThis->u.s.hWinIfMutex); } else { @@ -3420,15 +2900,143 @@ static int vboxNetFltWinAttachToInterface(PVBOXNETFLTINS pThis, void * pContext, Info.fRediscovery = fRediscovery; Info.pCreateContext = (PCREATE_INSTANCE_CONTEXT)pContext; - -#ifdef VBOX_NETFLT_ONDEMAND_BIND - /* packet queue worker thread gets created on attach interface, need to do it via job at passive level */ - vboxNetFltWinJobSynchExecAtPassive((JOB_ROUTINE)vboxNetFltWinAttachToInterfaceWorker, &Info); -#else vboxNetFltWinAttachToInterfaceWorker(&Info); -#endif + return Info.Status; } +static NTSTATUS vboxNetFltWinPtDevDispatch(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp) +{ + PIO_STACK_LOCATION pIrpSl = IoGetCurrentIrpStackLocation(pIrp);; + NTSTATUS Status = STATUS_SUCCESS; + + switch (pIrpSl->MajorFunction) + { + case IRP_MJ_DEVICE_CONTROL: + Status = STATUS_NOT_SUPPORTED; + break; + case IRP_MJ_CREATE: + case IRP_MJ_CLEANUP: + case IRP_MJ_CLOSE: + break; + default: + Assert(0); + break; + } + + pIrp->IoStatus.Status = Status; + IoCompleteRequest(pIrp, IO_NO_INCREMENT); + + return Status; +} + +static NDIS_STATUS vboxNetFltWinDevCreate(PVBOXNETFLTGLOBALS_WIN pGlobals) +{ + NDIS_STRING DevName, LinkName; + PDRIVER_DISPATCH aMajorFunctions[IRP_MJ_MAXIMUM_FUNCTION+1]; + NdisInitUnicodeString(&DevName, VBOXNETFLT_NAME_DEVICE); + NdisInitUnicodeString(&LinkName, VBOXNETFLT_NAME_LINK); + + Assert(!pGlobals->hDevice); + Assert(!pGlobals->pDevObj); + NdisZeroMemory(aMajorFunctions, sizeof (aMajorFunctions)); + aMajorFunctions[IRP_MJ_CREATE] = vboxNetFltWinPtDevDispatch; + aMajorFunctions[IRP_MJ_CLEANUP] = vboxNetFltWinPtDevDispatch; + aMajorFunctions[IRP_MJ_CLOSE] = vboxNetFltWinPtDevDispatch; + aMajorFunctions[IRP_MJ_DEVICE_CONTROL] = vboxNetFltWinPtDevDispatch; + + NDIS_STATUS Status = NdisMRegisterDevice(pGlobals->Mp.hNdisWrapper, + &DevName, &LinkName, + aMajorFunctions, + &pGlobals->pDevObj, + &pGlobals->hDevice); + Assert(Status == NDIS_STATUS_SUCCESS); + return Status; +} + +static NDIS_STATUS vboxNetFltWinDevDestroy(PVBOXNETFLTGLOBALS_WIN pGlobals) +{ + Assert(pGlobals->hDevice); + Assert(pGlobals->pDevObj); + NDIS_STATUS Status = NdisMDeregisterDevice(pGlobals->hDevice); + Assert(Status == NDIS_STATUS_SUCCESS); + if (Status == NDIS_STATUS_SUCCESS) + { + pGlobals->hDevice = NULL; + pGlobals->pDevObj = NULL; + } + return Status; +} + +static NDIS_STATUS vboxNetFltWinDevCreateReference(PVBOXNETFLTGLOBALS_WIN pGlobals) +{ + Assert(KeGetCurrentIrql() == PASSIVE_LEVEL); + NDIS_STATUS Status = KeWaitForSingleObject(&pGlobals->SynchEvent, Executive, KernelMode, FALSE, NULL); + Assert(Status == STATUS_SUCCESS); + if (Status == STATUS_SUCCESS) + { + Assert(pGlobals->cDeviceRefs >= 0); + if (++pGlobals->cDeviceRefs == 1) + { + Status = vboxNetFltWinDevCreate(pGlobals); + if (Status == NDIS_STATUS_SUCCESS) + { + ObReferenceObject(pGlobals->pDevObj); + } + } + else + { + Status = NDIS_STATUS_SUCCESS; + } + KeSetEvent(&pGlobals->SynchEvent, 0, FALSE); + } + else + { + /* should never happen actually */ + Assert(0); + Status = NDIS_STATUS_FAILURE; + } + return Status; +} + +static NDIS_STATUS vboxNetFltWinDevDereference(PVBOXNETFLTGLOBALS_WIN pGlobals) +{ + Assert(KeGetCurrentIrql() == PASSIVE_LEVEL); + NDIS_STATUS Status = KeWaitForSingleObject(&pGlobals->SynchEvent, Executive, KernelMode, FALSE, NULL); + Assert(Status == STATUS_SUCCESS); + if (Status == STATUS_SUCCESS) + { + Assert(pGlobals->cDeviceRefs > 0); + if (!(--pGlobals->cDeviceRefs)) + { + ObDereferenceObject(pGlobals->pDevObj); + Status = vboxNetFltWinDevDestroy(pGlobals); + } + else + { + Status = NDIS_STATUS_SUCCESS; + } + KeSetEvent(&pGlobals->SynchEvent, 0, FALSE); + } + else + { + /* should never happen actually */ + Assert(0); + Status = NDIS_STATUS_FAILURE; + } + return Status; +} + +/* reference the driver module to prevent driver unload */ +DECLHIDDEN(void) vboxNetFltWinDrvReference() +{ + vboxNetFltWinDevCreateReference(&g_VBoxNetFltGlobalsWin); +} + +/* dereference the driver module to prevent driver unload */ +DECLHIDDEN(void) vboxNetFltWinDrvDereference() +{ + vboxNetFltWinDevDereference(&g_VBoxNetFltGlobalsWin); +} /* * @@ -3447,18 +3055,17 @@ int vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, void *pvIfData, PINTNETSG pSG, ui { int rc = VINF_SUCCESS; uint32_t cRefs = 0; - PADAPT pAdapt; -#if !defined(VBOXNETADP) && !defined(VBOX_NETFLT_ONDEMAND_BIND) - if(fDst & INTNETTRUNKDIR_WIRE) +#ifndef VBOXNETADP + if (fDst & INTNETTRUNKDIR_WIRE) { cRefs++; } - if(fDst & INTNETTRUNKDIR_HOST) + if (fDst & INTNETTRUNKDIR_HOST) { cRefs++; } #else - if(fDst & INTNETTRUNKDIR_WIRE || fDst & INTNETTRUNKDIR_HOST) + if (fDst & INTNETTRUNKDIR_WIRE || fDst & INTNETTRUNKDIR_HOST) { cRefs = 1; } @@ -3466,22 +3073,16 @@ int vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, void *pvIfData, PINTNETSG pSG, ui AssertReturn(cRefs, VINF_SUCCESS); - pAdapt = PVBOXNETFLTINS_2_PADAPT(pThis); - - if(!vboxNetFltWinIncReferenceAdapt(pAdapt, cRefs)) + if (!vboxNetFltWinIncReferenceWinIf(pThis, cRefs)) { return VERR_GENERAL_FAILURE; } #ifndef VBOXNETADP - if ((fDst & INTNETTRUNKDIR_WIRE) -# ifdef VBOX_NETFLT_ONDEMAND_BIND - || (fDst & INTNETTRUNKDIR_HOST) -# endif - ) + if (fDst & INTNETTRUNKDIR_WIRE) { PNDIS_PACKET pPacket; - pPacket = vboxNetFltWinNdisPacketFromSG(pAdapt, pSG, NULL /*pBufToFree*/, + pPacket = vboxNetFltWinNdisPacketFromSG(pThis, pSG, NULL /*pBufToFree*/, true /*fToWire*/, true /*fCopyMemory*/); if (pPacket) @@ -3491,23 +3092,23 @@ int vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, void *pvIfData, PINTNETSG pSG, ui #ifndef VBOX_LOOPBACK_USEFLAGS /* force "don't loopback" flags to prevent loopback branch invocation in any case * to avoid ndis misbehave */ - NdisGetPacketFlags(pPacket) |= g_fPacketDontLoopBack; + NdisGetPacketFlags(pPacket) |= g_VBoxNetFltGlobalsWin.fPacketDontLoopBack; #else /* this is done by default in vboxNetFltWinNdisPacketFromSG */ #endif #if defined(DEBUG_NETFLT_PACKETS) || !defined(VBOX_LOOPBACK_USEFLAGS) - vboxNetFltWinLbPutSendPacket(pAdapt, pPacket, true /* bFromIntNet */); + vboxNetFltWinLbPutSendPacket(pThis, pPacket, true /* bFromIntNet */); #endif - NdisSend(&fStatus, pAdapt->hBindingHandle, pPacket); + NdisSend(&fStatus, pThis->u.s.WinIf.hBinding, pPacket); if (fStatus != NDIS_STATUS_PENDING) { #if defined(DEBUG_NETFLT_PACKETS) || !defined(VBOX_LOOPBACK_USEFLAGS) /* the status is NOT pending, complete the packet */ - bool bTmp = vboxNetFltWinLbRemoveSendPacket(pAdapt, pPacket); + bool bTmp = vboxNetFltWinLbRemoveSendPacket(pThis, pPacket); Assert(bTmp); #endif - if(!NT_SUCCESS(fStatus)) + if (!NT_SUCCESS(fStatus)) { /* TODO: convert status to VERR_xxx */ rc = VERR_GENERAL_FAILURE; @@ -3528,33 +3129,28 @@ int vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, void *pvIfData, PINTNETSG pSG, ui } } #endif -#ifndef VBOX_NETFLT_ONDEMAND_BIND + #ifndef VBOXNETADP if (fDst & INTNETTRUNKDIR_HOST) #else - if(cRefs) + if (cRefs) #endif { - PNDIS_PACKET pPacket = vboxNetFltWinNdisPacketFromSG(pAdapt, pSG, NULL /*pBufToFree*/, + PNDIS_PACKET pPacket = vboxNetFltWinNdisPacketFromSG(pThis, pSG, NULL /*pBufToFree*/, false /*fToWire*/, true /*fCopyMemory*/); if (pPacket) { -#ifdef VBOXNETADP - NdisMIndicateReceivePacket(pAdapt->hMiniportHandle, &pPacket, 1); -#else - /* flush any packets currently queued */ - vboxNetFltWinPtQueueReceivedPacket(pAdapt, pPacket, TRUE /* BOOLEAN DoIndicate */); -#endif + NdisMIndicateReceivePacket(pThis->u.s.WinIf.hMiniport, &pPacket, 1); cRefs--; #ifdef VBOXNETADP - STATISTIC_INCREASE(pAdapt->cRxSuccess); + STATISTIC_INCREASE(pThis->u.s.WinIf.cRxSuccess); #endif } else { AssertFailed(); #ifdef VBOXNETADP - STATISTIC_INCREASE(pAdapt->cRxError); + STATISTIC_INCREASE(pThis->u.s.WinIf.cRxError); #endif rc = VERR_NO_MEMORY; } @@ -3562,11 +3158,10 @@ int vboxNetFltPortOsXmit(PVBOXNETFLTINS pThis, void *pvIfData, PINTNETSG pSG, ui Assert(cRefs <= 2); - if(cRefs) + if (cRefs) { - vboxNetFltWinDecReferenceAdapt(pAdapt, cRefs); + vboxNetFltWinDecReferenceWinIf(pThis, cRefs); } -#endif return rc; } @@ -3576,22 +3171,20 @@ void vboxNetFltPortOsSetActive(PVBOXNETFLTINS pThis, bool fActive) #ifndef VBOXNETADP NDIS_STATUS Status; #endif - PADAPT pAdapt = PVBOXNETFLTINS_2_PADAPT(pThis); - /* we first wait for all pending ops to complete * this might include all packets queued for processing */ - for(;;) + for (;;) { - if(fActive) + if (fActive) { - if(!pThis->u.s.cModePassThruRefs) + if (!pThis->u.s.cModePassThruRefs) { break; } } else { - if(!pThis->u.s.cModeNetFltRefs) + if (!pThis->u.s.cModeNetFltRefs) { break; } @@ -3599,27 +3192,23 @@ void vboxNetFltPortOsSetActive(PVBOXNETFLTINS pThis, bool fActive) vboxNetFltWinSleep(2); } - if(!vboxNetFltWinReferenceAdapt(pAdapt)) + if (!vboxNetFltWinReferenceWinIf(pThis)) return; #ifndef VBOXNETADP - /* the packets put to ReceiveQueue Array are currently not holding the references, - * simply need to flush them */ - vboxNetFltWinPtFlushReceiveQueue(pAdapt, false /*fReturn*/); - - if(fActive) + if (fActive) { #ifdef DEBUG_misha - NDIS_PHYSICAL_MEDIUM PhMedium; + NDIS_PHYSICAL_MEDIUM PhMedium; bool bPromiscSupported; - Status = vboxNetFltWinQueryPhysicalMedium(pAdapt, &PhMedium); - if(Status != NDIS_STATUS_SUCCESS) + Status = vboxNetFltWinQueryPhysicalMedium(pThis, &PhMedium); + if (Status != NDIS_STATUS_SUCCESS) { - DBGPRINT(("vboxNetFltWinQueryPhysicalMedium failed, Status (0x%x), setting medium to NdisPhysicalMediumUnspecified\n", Status)); + LogRel(("vboxNetFltWinQueryPhysicalMedium failed, Status (0x%x), setting medium to NdisPhysicalMediumUnspecified\n", Status)); Assert(Status == NDIS_STATUS_NOT_SUPPORTED); - if(Status != NDIS_STATUS_NOT_SUPPORTED) + if (Status != NDIS_STATUS_NOT_SUPPORTED) { LogRel(("vboxNetFltWinQueryPhysicalMedium failed, Status (0x%x), setting medium to NdisPhysicalMediumUnspecified\n", Status)); } @@ -3627,63 +3216,62 @@ void vboxNetFltPortOsSetActive(PVBOXNETFLTINS pThis, bool fActive) } else { - DBGPRINT(("(SUCCESS) vboxNetFltWinQueryPhysicalMedium SUCCESS\n")); + LogRel(("(SUCCESS) vboxNetFltWinQueryPhysicalMedium SUCCESS\n")); } - bPromiscSupported = (!(PhMedium == NdisPhysicalMediumWirelessWan + bPromiscSupported = (!(PhMedium == NdisPhysicalMediumWirelessWan || PhMedium == NdisPhysicalMediumWirelessLan || PhMedium == NdisPhysicalMediumNative802_11 || PhMedium == NdisPhysicalMediumBluetooth /*|| PhMedium == NdisPhysicalMediumWiMax */ )); - Assert(bPromiscSupported == VBOXNETFLT_PROMISCUOUS_SUPPORTED(pAdapt)); + Assert(bPromiscSupported == VBOXNETFLT_PROMISCUOUS_SUPPORTED(pThis)); #endif } - if(VBOXNETFLT_PROMISCUOUS_SUPPORTED(pAdapt)) + if (VBOXNETFLT_PROMISCUOUS_SUPPORTED(pThis)) { - Status = vboxNetFltWinSetPromiscuous(pAdapt, fActive); - if(Status != NDIS_STATUS_SUCCESS) + Status = vboxNetFltWinSetPromiscuous(pThis, fActive); + if (Status != NDIS_STATUS_SUCCESS) { - DBGPRINT(("vboxNetFltWinSetPromiscuous failed, Status (0x%x), fActive (%d)\n", Status, fActive)); - AssertFailed(); LogRel(("vboxNetFltWinSetPromiscuous failed, Status (0x%x), fActive (%d)\n", Status, fActive)); + AssertFailed(); } } #else # ifdef VBOXNETADP_REPORT_DISCONNECTED - if(fActive) + if (fActive) { - NdisMIndicateStatus(pAdapt->hMiniportHandle, + NdisMIndicateStatus(pThis->u.s.WinIf.hMiniport, NDIS_STATUS_MEDIA_CONNECT, (PVOID)NULL, 0); } else { - NdisMIndicateStatus(pAdapt->hMiniportHandle, + NdisMIndicateStatus(pThis->u.s.WinIf.hMiniport, NDIS_STATUS_MEDIA_DISCONNECT, (PVOID)NULL, 0); } #else - if(fActive) + if (fActive) { /* indicate status change to make the ip settings be re-picked for dhcp */ - NdisMIndicateStatus(pAdapt->hMiniportHandle, + NdisMIndicateStatus(pThis->u.s.WinIf.hMiniport, NDIS_STATUS_MEDIA_DISCONNECT, (PVOID)NULL, 0); - NdisMIndicateStatus(pAdapt->hMiniportHandle, + NdisMIndicateStatus(pThis->u.s.WinIf.hMiniport, NDIS_STATUS_MEDIA_CONNECT, (PVOID)NULL, 0); } # endif #endif - vboxNetFltWinDereferenceAdapt(pAdapt); + vboxNetFltWinDereferenceWinIf(pThis); return; } @@ -3694,21 +3282,21 @@ int vboxNetFltOsDisconnectIt(PVBOXNETFLTINS pThis) return Status == NDIS_STATUS_SUCCESS ? VINF_SUCCESS : VERR_GENERAL_FAILURE; } -static void vboxNetFltWinConnectItWorker(PWORKER_INFO pInfo) +static void vboxNetFltWinConnectItWorker(PVOID pvContext) { + PWORKER_INFO pInfo = (PWORKER_INFO)pvContext; #if !defined(VBOXNETADP) || !defined(VBOXNETFLT_NO_PACKET_QUEUE) NDIS_STATUS Status; #endif PVBOXNETFLTINS pInstance = pInfo->pNetFltIf; - PADAPT pAdapt = PVBOXNETFLTINS_2_PADAPT(pInstance); Assert(KeGetCurrentIrql() == PASSIVE_LEVEL); /* this is not a rediscovery, initialize Mac cache */ - if(vboxNetFltWinReferenceAdapt(pAdapt)) + if (vboxNetFltWinReferenceWinIf(pInstance)) { #ifndef VBOXNETADP - Status = vboxNetFltWinGetMacAddress(pAdapt, &pInstance->u.s.MacAddr); + Status = vboxNetFltWinGetMacAddress(pInstance, &pInstance->u.s.MacAddr); if (Status == NDIS_STATUS_SUCCESS) #endif { @@ -3716,7 +3304,7 @@ static void vboxNetFltWinConnectItWorker(PWORKER_INFO pInfo) pInfo->Status = VINF_SUCCESS; #else Status = vboxNetFltWinQuInitPacketQueue(pInstance); - if(Status == NDIS_STATUS_SUCCESS) + if (Status == NDIS_STATUS_SUCCESS) { pInfo->Status = VINF_SUCCESS; } @@ -3733,7 +3321,7 @@ static void vboxNetFltWinConnectItWorker(PWORKER_INFO pInfo) } #endif - vboxNetFltWinDereferenceAdapt(pAdapt); + vboxNetFltWinDereferenceWinIf(pInstance); } else { @@ -3766,7 +3354,7 @@ void vboxNetFltOsDeleteInstance(PVBOXNETFLTINS pThis) int vboxNetFltOsInitInstance(PVBOXNETFLTINS pThis, void *pvContext) { - int rc = RTSemMutexCreate(&pThis->u.s.hAdaptMutex); + int rc = RTSemMutexCreate(&pThis->u.s.hWinIfMutex); if (RT_SUCCESS(rc)) { rc = vboxNetFltWinAttachToInterface(pThis, pvContext, false /*fRediscovery*/ ); @@ -3774,20 +3362,19 @@ int vboxNetFltOsInitInstance(PVBOXNETFLTINS pThis, void *pvContext) { return rc; } - RTSemMutexDestroy(pThis->u.s.hAdaptMutex); + RTSemMutexDestroy(pThis->u.s.hWinIfMutex); } return rc; } int vboxNetFltOsPreInitInstance(PVBOXNETFLTINS pThis) { - PADAPT pAdapt = PVBOXNETFLTINS_2_PADAPT(pThis); pThis->u.s.cModeNetFltRefs = 0; pThis->u.s.cModePassThruRefs = 0; - vboxNetFltWinSetAdaptState(pAdapt, kVBoxAdaptState_Disconnected); - vboxNetFltWinSetOpState(&pAdapt->MPState, kVBoxNetDevOpState_Deinitialized); + vboxNetFltWinSetWinIfState(pThis, kVBoxWinIfState_Disconnected); + vboxNetFltWinSetOpState(&pThis->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized); #ifndef VBOXNETADP - vboxNetFltWinSetOpState(&pAdapt->PTState, kVBoxNetDevOpState_Deinitialized); + vboxNetFltWinSetOpState(&pThis->u.s.WinIf.PtState, kVBoxNetDevOpState_Deinitialized); #endif return VINF_SUCCESS; } @@ -3807,4 +3394,3 @@ int vboxNetFltPortOsDisconnectInterface(PVBOXNETFLTINS pThis, void *pvIfData) /* Nothing to do */ return VINF_SUCCESS; } - diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.h b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltRt-win.h index 541c04033..9ef0d2588 100644 --- a/src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.h +++ b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltRt-win.h @@ -1,10 +1,10 @@ -/* $Id: VBoxNetFlt-win.h $ */ +/* $Id: VBoxNetFltRt-win.h 36184 2011-03-07 10:57:04Z vboxsync $ */ /** @file - * VBoxNetFlt - Network Filter Driver (Host), Windows Specific Code. Integration with IntNet/NetFlt + * VBoxNetFltRt-win.h - Bridged Networking Driver, Windows Specific Code. + * NetFlt Runtime API */ - /* - * Copyright (C) 2008 Oracle Corporation + * Copyright (C) 2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -14,44 +14,8 @@ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. */ -/* - * Based in part on Microsoft DDK sample code for Ndis Intermediate Miniport passthru driver sample. - * Copyright (c) 1993-1999, Microsoft Corporation - */ - -#ifndef ___VBoxNetFlt_win_h___ -#define ___VBoxNetFlt_win_h___ - -/* - * globals - */ - -/** global lock */ -extern NDIS_SPIN_LOCK g_GlobalLock; - -extern UINT g_fPacketDontLoopBack; -extern UINT g_fPacketIsLoopedBack; - -/* - * Debug Print API - */ -#ifdef DEBUG - -#define DBGPRINT(Fmt) DbgPrint Fmt - -#else /* if DBG */ - -#define DBGPRINT(Fmt) - -#endif /* if DBG */ - -/** get the PVBOXNETFLTINS from PADAPT */ -#define PADAPT_2_PVBOXNETFLTINS(_pAdapt) ( (PVBOXNETFLTINS)((uint8_t *)(_pAdapt) - RT_OFFSETOF(VBOXNETFLTINS, u.s.IfAdaptor)) ) -/** get the PADAPT from PVBOXNETFLTINS */ -#define PVBOXNETFLTINS_2_PADAPT(_pNetFlt) ( &(_pNetFlt)->u.s.IfAdaptor ) - - -DECLHIDDEN(NTSTATUS) vboxNetFltWinPtDispatch(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp); +#ifndef ___VBoxNetFltRt_win_h___ +#define ___VBoxNetFltRt_win_h___ DECLHIDDEN(VOID) vboxNetFltWinUnload(IN PDRIVER_OBJECT DriverObject); #ifndef VBOXNETADP @@ -67,26 +31,26 @@ DECLHIDDEN(bool) vboxNetFltWinMatchPacketAndSG(PNDIS_PACKET pPacket, PINTNETSG p #define LIST_ENTRY_2_PACKET_INFO(pListEntry) \ - ( (PPACKET_INFO)((uint8_t *)(pListEntry) - RT_OFFSETOF(PACKET_INFO, ListEntry)) ) + ( (PVBOXNETFLT_PACKET_INFO)((uint8_t *)(pListEntry) - RT_OFFSETOF(VBOXNETFLT_PACKET_INFO, ListEntry)) ) #if !defined(VBOX_LOOPBACK_USEFLAGS) || defined(DEBUG_NETFLT_PACKETS) -#define VBOX_SLE_2_SEND_RSVD(_pEntry) \ - ( (PSEND_RSVD)((uint8_t *)(_pEntry) - RT_OFFSETOF(SEND_RSVD, ListEntry)) ) +#define VBOX_SLE_2_PKTRSVD_PT(_pEntry) \ + ( (PVBOXNETFLT_PKTRSVD_PT)((uint8_t *)(_pEntry) - RT_OFFSETOF(VBOXNETFLT_PKTRSVD_PT, ListEntry)) ) #define VBOX_SLE_2_SENDPACKET(_pEntry) \ - ( (PNDIS_PACKET)((uint8_t *)(VBOX_SLE_2_SEND_RSVD(_pEntry)) - RT_OFFSETOF(NDIS_PACKET, ProtocolReserved)) ) + ( (PNDIS_PACKET)((uint8_t *)(VBOX_SLE_2_PKTRSVD_PT(_pEntry)) - RT_OFFSETOF(NDIS_PACKET, ProtocolReserved)) ) #endif /** * enqueus the packet info to the tail of the queue */ -DECLINLINE(void) vboxNetFltWinQuEnqueueTail(PPACKET_QUEUE pQueue, PPACKET_INFO pPacketInfo) +DECLINLINE(void) vboxNetFltWinQuEnqueueTail(PVBOXNETFLT_PACKET_QUEUE pQueue, PVBOXNETFLT_PACKET_INFO pPacketInfo) { InsertTailList(pQueue, &pPacketInfo->ListEntry); } -DECLINLINE(void) vboxNetFltWinQuEnqueueHead(PPACKET_QUEUE pQueue, PPACKET_INFO pPacketInfo) +DECLINLINE(void) vboxNetFltWinQuEnqueueHead(PVBOXNETFLT_PACKET_QUEUE pQueue, PVBOXNETFLT_PACKET_INFO pPacketInfo) { Assert(pPacketInfo->pPool); InsertHeadList(pQueue, &pPacketInfo->ListEntry); @@ -95,7 +59,7 @@ DECLINLINE(void) vboxNetFltWinQuEnqueueHead(PPACKET_QUEUE pQueue, PPACKET_INFO p /** * enqueus the packet info to the tail of the queue */ -DECLINLINE(void) vboxNetFltWinQuInterlockedEnqueueTail(PINTERLOCKED_PACKET_QUEUE pQueue, PPACKET_INFO pPacketInfo) +DECLINLINE(void) vboxNetFltWinQuInterlockedEnqueueTail(PVBOXNETFLT_INTERLOCKED_PACKET_QUEUE pQueue, PVBOXNETFLT_PACKET_INFO pPacketInfo) { Assert(pPacketInfo->pPool); NdisAcquireSpinLock(&pQueue->Lock); @@ -103,7 +67,7 @@ DECLINLINE(void) vboxNetFltWinQuInterlockedEnqueueTail(PINTERLOCKED_PACKET_QUEUE NdisReleaseSpinLock(&pQueue->Lock); } -DECLINLINE(void) vboxNetFltWinQuInterlockedEnqueueHead(PINTERLOCKED_PACKET_QUEUE pQueue, PPACKET_INFO pPacketInfo) +DECLINLINE(void) vboxNetFltWinQuInterlockedEnqueueHead(PVBOXNETFLT_INTERLOCKED_PACKET_QUEUE pQueue, PVBOXNETFLT_PACKET_INFO pPacketInfo) { NdisAcquireSpinLock(&pQueue->Lock); vboxNetFltWinQuEnqueueHead(&pQueue->Queue, pPacketInfo); @@ -113,54 +77,54 @@ DECLINLINE(void) vboxNetFltWinQuInterlockedEnqueueHead(PINTERLOCKED_PACKET_QUEUE /** * dequeus the packet info from the head of the queue */ -DECLINLINE(PPACKET_INFO) vboxNetFltWinQuDequeueHead(PPACKET_QUEUE pQueue) +DECLINLINE(PVBOXNETFLT_PACKET_INFO) vboxNetFltWinQuDequeueHead(PVBOXNETFLT_PACKET_QUEUE pQueue) { PLIST_ENTRY pListEntry = RemoveHeadList(pQueue); if(pListEntry != pQueue) { - PPACKET_INFO pInfo = LIST_ENTRY_2_PACKET_INFO(pListEntry); + PVBOXNETFLT_PACKET_INFO pInfo = LIST_ENTRY_2_PACKET_INFO(pListEntry); Assert(pInfo->pPool); return pInfo; } return NULL; } -DECLINLINE(PPACKET_INFO) vboxNetFltWinQuDequeueTail(PPACKET_QUEUE pQueue) +DECLINLINE(PVBOXNETFLT_PACKET_INFO) vboxNetFltWinQuDequeueTail(PVBOXNETFLT_PACKET_QUEUE pQueue) { PLIST_ENTRY pListEntry = RemoveTailList(pQueue); if(pListEntry != pQueue) { - PPACKET_INFO pInfo = LIST_ENTRY_2_PACKET_INFO(pListEntry); + PVBOXNETFLT_PACKET_INFO pInfo = LIST_ENTRY_2_PACKET_INFO(pListEntry); Assert(pInfo->pPool); return pInfo; } return NULL; } -DECLINLINE(PPACKET_INFO) vboxNetFltWinQuInterlockedDequeueHead(PINTERLOCKED_PACKET_QUEUE pInterlockedQueue) +DECLINLINE(PVBOXNETFLT_PACKET_INFO) vboxNetFltWinQuInterlockedDequeueHead(PVBOXNETFLT_INTERLOCKED_PACKET_QUEUE pInterlockedQueue) { - PPACKET_INFO pInfo; + PVBOXNETFLT_PACKET_INFO pInfo; NdisAcquireSpinLock(&pInterlockedQueue->Lock); pInfo = vboxNetFltWinQuDequeueHead(&pInterlockedQueue->Queue); NdisReleaseSpinLock(&pInterlockedQueue->Lock); return pInfo; } -DECLINLINE(PPACKET_INFO) vboxNetFltWinQuInterlockedDequeueTail(PINTERLOCKED_PACKET_QUEUE pInterlockedQueue) +DECLINLINE(PVBOXNETFLT_PACKET_INFO) vboxNetFltWinQuInterlockedDequeueTail(PVBOXNETFLT_INTERLOCKED_PACKET_QUEUE pInterlockedQueue) { - PPACKET_INFO pInfo; + PVBOXNETFLT_PACKET_INFO pInfo; NdisAcquireSpinLock(&pInterlockedQueue->Lock); pInfo = vboxNetFltWinQuDequeueTail(&pInterlockedQueue->Queue); NdisReleaseSpinLock(&pInterlockedQueue->Lock); return pInfo; } -DECLINLINE(void) vboxNetFltWinQuDequeue(PPACKET_INFO pInfo) +DECLINLINE(void) vboxNetFltWinQuDequeue(PVBOXNETFLT_PACKET_INFO pInfo) { RemoveEntryList(&pInfo->ListEntry); } -DECLINLINE(void) vboxNetFltWinQuInterlockedDequeue(PINTERLOCKED_PACKET_QUEUE pInterlockedQueue, PPACKET_INFO pInfo) +DECLINLINE(void) vboxNetFltWinQuInterlockedDequeue(PVBOXNETFLT_INTERLOCKED_PACKET_QUEUE pInterlockedQueue, PVBOXNETFLT_PACKET_INFO pInfo) { NdisAcquireSpinLock(&pInterlockedQueue->Lock); vboxNetFltWinQuDequeue(pInfo); @@ -170,7 +134,7 @@ DECLINLINE(void) vboxNetFltWinQuInterlockedDequeue(PINTERLOCKED_PACKET_QUEUE pIn /** * allocates the packet info from the pool */ -DECLINLINE(PPACKET_INFO) vboxNetFltWinPpAllocPacketInfo(PPACKET_INFO_POOL pPool) +DECLINLINE(PVBOXNETFLT_PACKET_INFO) vboxNetFltWinPpAllocPacketInfo(PVBOXNETFLT_PACKET_INFO_POOL pPool) { return vboxNetFltWinQuInterlockedDequeueHead(&pPool->Queue); } @@ -178,9 +142,9 @@ DECLINLINE(PPACKET_INFO) vboxNetFltWinPpAllocPacketInfo(PPACKET_INFO_POOL pPool) /** * returns the packet info to the pool */ -DECLINLINE(void) vboxNetFltWinPpFreePacketInfo(PPACKET_INFO pInfo) +DECLINLINE(void) vboxNetFltWinPpFreePacketInfo(PVBOXNETFLT_PACKET_INFO pInfo) { - PPACKET_INFO_POOL pPool = pInfo->pPool; + PVBOXNETFLT_PACKET_INFO_POOL pPool = pInfo->pPool; vboxNetFltWinQuInterlockedEnqueueHead(&pPool->Queue, pInfo); } @@ -213,13 +177,8 @@ DECLINLINE(void) vboxNetFltWinPpFreePacketInfo(PPACKET_INFO pInfo) DECLHIDDEN(bool) vboxNetFltWinPostIntnet(PVBOXNETFLTINS pInstance, PVOID pvPacket, const UINT fFlags); #else DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQuEnqueuePacket(PVBOXNETFLTINS pInstance, PVOID pPacket, const UINT fPacketFlags); - -#ifndef VBOX_NETFLT_ONDEMAND_BIND DECLHIDDEN(void) vboxNetFltWinQuFiniPacketQueue(PVBOXNETFLTINS pInstance); - DECLHIDDEN(NTSTATUS) vboxNetFltWinQuInitPacketQueue(PVBOXNETFLTINS pInstance); -#endif - #endif /* #ifndef VBOXNETFLT_NO_PACKET_QUEUE */ @@ -227,7 +186,7 @@ DECLHIDDEN(NTSTATUS) vboxNetFltWinQuInitPacketQueue(PVBOXNETFLTINS pInstance); /** * searches the list entry in a single-linked list */ -DECLINLINE(bool) vboxNetFltWinSearchListEntry(PSINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry2Search, bool bRemove) +DECLINLINE(bool) vboxNetFltWinSearchListEntry(PVBOXNETFLT_SINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry2Search, bool bRemove) { PSINGLE_LIST_ENTRY pHead = &pList->Head; PSINGLE_LIST_ENTRY pCur; @@ -252,7 +211,7 @@ DECLINLINE(bool) vboxNetFltWinSearchListEntry(PSINGLE_LIST pList, PSINGLE_LIST_E #if !defined(VBOX_LOOPBACK_USEFLAGS) || defined(DEBUG_NETFLT_PACKETS) -DECLINLINE(PNDIS_PACKET) vboxNetFltWinSearchPacket(PSINGLE_LIST pList, PNDIS_PACKET pPacket2Search, int cbMatch, bool bRemove) +DECLINLINE(PNDIS_PACKET) vboxNetFltWinSearchPacket(PVBOXNETFLT_SINGLE_LIST pList, PNDIS_PACKET pPacket2Search, int cbMatch, bool bRemove) { PSINGLE_LIST_ENTRY pHead = &pList->Head; PSINGLE_LIST_ENTRY pCur; @@ -277,7 +236,7 @@ DECLINLINE(PNDIS_PACKET) vboxNetFltWinSearchPacket(PSINGLE_LIST pList, PNDIS_PAC return NULL; } -DECLINLINE(PNDIS_PACKET) vboxNetFltWinSearchPacketBySG(PSINGLE_LIST pList, PINTNETSG pSG, int cbMatch, bool bRemove) +DECLINLINE(PNDIS_PACKET) vboxNetFltWinSearchPacketBySG(PVBOXNETFLT_SINGLE_LIST pList, PINTNETSG pSG, int cbMatch, bool bRemove) { PSINGLE_LIST_ENTRY pHead = &pList->Head; PSINGLE_LIST_ENTRY pCur; @@ -304,19 +263,19 @@ DECLINLINE(PNDIS_PACKET) vboxNetFltWinSearchPacketBySG(PSINGLE_LIST pList, PINTN #endif /* #if !defined(VBOX_LOOPBACK_USEFLAGS) || defined(DEBUG_NETFLT_PACKETS) */ -DECLINLINE(bool) vboxNetFltWinSListIsEmpty(PSINGLE_LIST pList) +DECLINLINE(bool) vboxNetFltWinSListIsEmpty(PVBOXNETFLT_SINGLE_LIST pList) { return !pList->Head.Next; } -DECLINLINE(void) vboxNetFltWinPutTail(PSINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry) +DECLINLINE(void) vboxNetFltWinPutTail(PVBOXNETFLT_SINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry) { pList->pTail->Next = pEntry; pList->pTail = pEntry; pEntry->Next = NULL; } -DECLINLINE(void) vboxNetFltWinPutHead(PSINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry) +DECLINLINE(void) vboxNetFltWinPutHead(PVBOXNETFLT_SINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry) { pEntry->Next = pList->Head.Next; pList->Head.Next = pEntry; @@ -324,7 +283,7 @@ DECLINLINE(void) vboxNetFltWinPutHead(PSINGLE_LIST pList, PSINGLE_LIST_ENTRY pEn pList->pTail = pEntry; } -DECLINLINE(PSINGLE_LIST_ENTRY) vboxNetFltWinGetHead(PSINGLE_LIST pList) +DECLINLINE(PSINGLE_LIST_ENTRY) vboxNetFltWinGetHead(PVBOXNETFLT_SINGLE_LIST pList) { PSINGLE_LIST_ENTRY pEntry = pList->Head.Next; if(pEntry && pEntry == pList->pTail) @@ -335,7 +294,7 @@ DECLINLINE(PSINGLE_LIST_ENTRY) vboxNetFltWinGetHead(PSINGLE_LIST pList) return pEntry; } -DECLINLINE(bool) vboxNetFltWinInterlockedSearchListEntry(PINTERLOCKED_SINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry2Search, bool bRemove) +DECLINLINE(bool) vboxNetFltWinInterlockedSearchListEntry(PVBOXNETFLT_INTERLOCKED_SINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry2Search, bool bRemove) { bool bFound; NdisAcquireSpinLock(&pList->Lock); @@ -346,7 +305,7 @@ DECLINLINE(bool) vboxNetFltWinInterlockedSearchListEntry(PINTERLOCKED_SINGLE_LIS #if !defined(VBOX_LOOPBACK_USEFLAGS) || defined(DEBUG_NETFLT_PACKETS) -DECLINLINE(PNDIS_PACKET) vboxNetFltWinInterlockedSearchPacket(PINTERLOCKED_SINGLE_LIST pList, PNDIS_PACKET pPacket2Search, int cbMatch, bool bRemove) +DECLINLINE(PNDIS_PACKET) vboxNetFltWinInterlockedSearchPacket(PVBOXNETFLT_INTERLOCKED_SINGLE_LIST pList, PNDIS_PACKET pPacket2Search, int cbMatch, bool bRemove) { PNDIS_PACKET pFound; NdisAcquireSpinLock(&pList->Lock); @@ -355,7 +314,7 @@ DECLINLINE(PNDIS_PACKET) vboxNetFltWinInterlockedSearchPacket(PINTERLOCKED_SINGL return pFound; } -DECLINLINE(PNDIS_PACKET) vboxNetFltWinInterlockedSearchPacketBySG(PINTERLOCKED_SINGLE_LIST pList, PINTNETSG pSG, int cbMatch, bool bRemove) +DECLINLINE(PNDIS_PACKET) vboxNetFltWinInterlockedSearchPacketBySG(PVBOXNETFLT_INTERLOCKED_SINGLE_LIST pList, PINTNETSG pSG, int cbMatch, bool bRemove) { PNDIS_PACKET pFound; NdisAcquireSpinLock(&pList->Lock); @@ -365,21 +324,21 @@ DECLINLINE(PNDIS_PACKET) vboxNetFltWinInterlockedSearchPacketBySG(PINTERLOCKED_S } #endif /* #if !defined(VBOX_LOOPBACK_USEFLAGS) || defined(DEBUG_NETFLT_PACKETS) */ -DECLINLINE(void) vboxNetFltWinInterlockedPutTail(PINTERLOCKED_SINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry) +DECLINLINE(void) vboxNetFltWinInterlockedPutTail(PVBOXNETFLT_INTERLOCKED_SINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry) { NdisAcquireSpinLock(&pList->Lock); vboxNetFltWinPutTail(&pList->List, pEntry); NdisReleaseSpinLock(&pList->Lock); } -DECLINLINE(void) vboxNetFltWinInterlockedPutHead(PINTERLOCKED_SINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry) +DECLINLINE(void) vboxNetFltWinInterlockedPutHead(PVBOXNETFLT_INTERLOCKED_SINGLE_LIST pList, PSINGLE_LIST_ENTRY pEntry) { NdisAcquireSpinLock(&pList->Lock); vboxNetFltWinPutHead(&pList->List, pEntry); NdisReleaseSpinLock(&pList->Lock); } -DECLINLINE(PSINGLE_LIST_ENTRY) vboxNetFltWinInterlockedGetHead(PINTERLOCKED_SINGLE_LIST pList) +DECLINLINE(PSINGLE_LIST_ENTRY) vboxNetFltWinInterlockedGetHead(PVBOXNETFLT_INTERLOCKED_SINGLE_LIST pList) { PSINGLE_LIST_ENTRY pEntry; NdisAcquireSpinLock(&pList->Lock); @@ -389,35 +348,34 @@ DECLINLINE(PSINGLE_LIST_ENTRY) vboxNetFltWinInterlockedGetHead(PINTERLOCKED_SING } # if defined(DEBUG_NETFLT_PACKETS) || !defined(VBOX_LOOPBACK_USEFLAGS) -DECLINLINE(void) vboxNetFltWinLbPutSendPacket(PADAPT pAdapt, PNDIS_PACKET pPacket, bool bFromIntNet) +DECLINLINE(void) vboxNetFltWinLbPutSendPacket(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket, bool bFromIntNet) { - PSEND_RSVD pSrv = (PSEND_RSVD)pPacket->ProtocolReserved; + PVBOXNETFLT_PKTRSVD_PT pSrv = (PVBOXNETFLT_PKTRSVD_PT)pPacket->ProtocolReserved; pSrv->bFromIntNet = bFromIntNet; - vboxNetFltWinInterlockedPutHead(&pAdapt->SendPacketQueue, &pSrv->ListEntry); + vboxNetFltWinInterlockedPutHead(&pNetFlt->u.s.WinIf.SendPacketQueue, &pSrv->ListEntry); } DECLINLINE(bool) vboxNetFltWinLbIsFromIntNet(PNDIS_PACKET pPacket) { - PSEND_RSVD pSrv = (PSEND_RSVD)pPacket->ProtocolReserved; + PVBOXNETFLT_PKTRSVD_PT pSrv = (PVBOXNETFLT_PKTRSVD_PT)pPacket->ProtocolReserved; return pSrv->bFromIntNet; } -DECLINLINE(PNDIS_PACKET) vboxNetFltWinLbSearchLoopBack(PADAPT pAdapt, PNDIS_PACKET pPacket, bool bRemove) +DECLINLINE(PNDIS_PACKET) vboxNetFltWinLbSearchLoopBack(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket, bool bRemove) { - return vboxNetFltWinInterlockedSearchPacket(&pAdapt->SendPacketQueue, pPacket, VBOXNETFLT_PACKETMATCH_LENGTH, bRemove); + return vboxNetFltWinInterlockedSearchPacket(&pNetFlt->u.s.WinIf.SendPacketQueue, pPacket, VBOXNETFLT_PACKETMATCH_LENGTH, bRemove); } -DECLINLINE(PNDIS_PACKET) vboxNetFltWinLbSearchLoopBackBySG(PADAPT pAdapt, PINTNETSG pSG, bool bRemove) +DECLINLINE(PNDIS_PACKET) vboxNetFltWinLbSearchLoopBackBySG(PVBOXNETFLTINS pNetFlt, PINTNETSG pSG, bool bRemove) { - return vboxNetFltWinInterlockedSearchPacketBySG(&pAdapt->SendPacketQueue, pSG, VBOXNETFLT_PACKETMATCH_LENGTH, bRemove); + return vboxNetFltWinInterlockedSearchPacketBySG(&pNetFlt->u.s.WinIf.SendPacketQueue, pSG, VBOXNETFLT_PACKETMATCH_LENGTH, bRemove); } -DECLINLINE(bool) vboxNetFltWinLbRemoveSendPacket(PADAPT pAdapt, PNDIS_PACKET pPacket) +DECLINLINE(bool) vboxNetFltWinLbRemoveSendPacket(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket) { - PSEND_RSVD pSrv = (PSEND_RSVD)pPacket->ProtocolReserved; - bool bRet = vboxNetFltWinInterlockedSearchListEntry(&pAdapt->SendPacketQueue, &pSrv->ListEntry, true); + PVBOXNETFLT_PKTRSVD_PT pSrv = (PVBOXNETFLT_PKTRSVD_PT)pPacket->ProtocolReserved; + bool bRet = vboxNetFltWinInterlockedSearchListEntry(&pNetFlt->u.s.WinIf.SendPacketQueue, &pSrv->ListEntry, true); #ifdef DEBUG_misha - PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt); Assert(bRet == (pNetFlt->enmTrunkState == INTNETTRUNKIFSTATE_ACTIVE)); #endif return bRet; @@ -472,19 +430,12 @@ extern RTMAC g_vboxNetFltWinVerifyMACGuest; } while(0) -/** obtains the PTRANSFERDATA_RSVD given a single list entry it contains */ -//#define PT_SLE_2_TRANSFERDATA_RSVD(_pl) \ -// ( (PTRANSFERDATA_RSVD)((uint8_t *)(_pl) - RT_OFFSETOF(TRANSFERDATA_RSVD, ListEntry))) - -///** obtains the ndis packet given a single list entry assuming it is stored in ProtocolReserved field of the packet */ -//#define PT_SLE_2_NDIS_PACKET(_pl) \ -// ( (PNDIS_PACKET)((uint8_t *)PT_SLE_2_TRANSFERDATA_RSVD(_pl) - RT_OFFSETOF(NDIS_PACKET, ProtocolReserved))) - /************************************************************************** - * PADAPT, PVBOXNETFLTINS reference/dereference (i.e. retain/release) API * + * PVBOXNETFLTINS , WinIf reference/dereference (i.e. retain/release) API * **************************************************************************/ -DECLHIDDEN(void) vboxNetFltWinWaitDereference(PADAPT_DEVICE pState); + +DECLHIDDEN(void) vboxNetFltWinWaitDereference(PVBOXNETFLT_WINIF_DEVICE pState); DECLINLINE(void) vboxNetFltWinReferenceModeNetFlt(PVBOXNETFLTINS pIns) { @@ -528,27 +479,27 @@ DECLINLINE(void) vboxNetFltWinDecReferenceModePassThru(PVBOXNETFLTINS pIns, uint ASMAtomicAddU32((volatile uint32_t *)&pIns->u.s.cModePassThruRefs, (uint32_t)(-((int32_t)v))); } -DECLINLINE(void) vboxNetFltWinSetPowerState(PADAPT_DEVICE pState, NDIS_DEVICE_POWER_STATE State) +DECLINLINE(void) vboxNetFltWinSetPowerState(PVBOXNETFLT_WINIF_DEVICE pState, NDIS_DEVICE_POWER_STATE State) { ASMAtomicUoWriteU32((volatile uint32_t *)&pState->PowerState, State); } -DECLINLINE(NDIS_DEVICE_POWER_STATE) vboxNetFltWinGetPowerState(PADAPT_DEVICE pState) +DECLINLINE(NDIS_DEVICE_POWER_STATE) vboxNetFltWinGetPowerState(PVBOXNETFLT_WINIF_DEVICE pState) { return (NDIS_DEVICE_POWER_STATE)ASMAtomicUoReadU32((volatile uint32_t *)&pState->PowerState); } -DECLINLINE(void) vboxNetFltWinSetOpState(PADAPT_DEVICE pState, VBOXNETDEVOPSTATE State) +DECLINLINE(void) vboxNetFltWinSetOpState(PVBOXNETFLT_WINIF_DEVICE pState, VBOXNETDEVOPSTATE State) { ASMAtomicUoWriteU32((volatile uint32_t *)&pState->OpState, State); } -DECLINLINE(VBOXNETDEVOPSTATE) vboxNetFltWinGetOpState(PADAPT_DEVICE pState) +DECLINLINE(VBOXNETDEVOPSTATE) vboxNetFltWinGetOpState(PVBOXNETFLT_WINIF_DEVICE pState) { return (VBOXNETDEVOPSTATE)ASMAtomicUoReadU32((volatile uint32_t *)&pState->OpState); } -DECLINLINE(bool) vboxNetFltWinDoReferenceDevice(PADAPT pAdapt, PADAPT_DEVICE pState) +DECLINLINE(bool) vboxNetFltWinDoReferenceDevice(PVBOXNETFLT_WINIF_DEVICE pState) { if (vboxNetFltWinGetPowerState(pState) == NdisDeviceStateD0 && vboxNetFltWinGetOpState(pState) == kVBoxNetDevOpState_Initialized) { @@ -561,7 +512,7 @@ DECLINLINE(bool) vboxNetFltWinDoReferenceDevice(PADAPT pAdapt, PADAPT_DEVICE pSt } #ifndef VBOXNETADP -DECLINLINE(bool) vboxNetFltWinDoReferenceDevices(PADAPT pAdapt, PADAPT_DEVICE pState1, PADAPT_DEVICE pState2) +DECLINLINE(bool) vboxNetFltWinDoReferenceDevices(PVBOXNETFLT_WINIF_DEVICE pState1, PVBOXNETFLT_WINIF_DEVICE pState2) { if (vboxNetFltWinGetPowerState(pState1) == NdisDeviceStateD0 && vboxNetFltWinGetOpState(pState1) == kVBoxNetDevOpState_Initialized @@ -576,40 +527,36 @@ DECLINLINE(bool) vboxNetFltWinDoReferenceDevices(PADAPT pAdapt, PADAPT_DEVICE pS } #endif -DECLINLINE(void) vboxNetFltWinDereferenceDevice(PADAPT pAdapt, PADAPT_DEVICE pState) +DECLINLINE(void) vboxNetFltWinDereferenceDevice(PVBOXNETFLT_WINIF_DEVICE pState) { -/* NdisAcquireSpinLock(&pAdapt->Lock); */ ASMAtomicDecU32((uint32_t volatile *)&pState->cReferences); /** @todo r=bird: Add comment explaining why these cannot hit 0 or why * reference are counted */ -/* NdisReleaseSpinLock(&pAdapt->Lock); */ } #ifndef VBOXNETADP -DECLINLINE(void) vboxNetFltWinDereferenceDevices(PADAPT pAdapt, PADAPT_DEVICE pState1, PADAPT_DEVICE pState2) +DECLINLINE(void) vboxNetFltWinDereferenceDevices(PVBOXNETFLT_WINIF_DEVICE pState1, PVBOXNETFLT_WINIF_DEVICE pState2) { -/* NdisAcquireSpinLock(&pAdapt->Lock); */ ASMAtomicDecU32((uint32_t volatile *)&pState1->cReferences); ASMAtomicDecU32((uint32_t volatile *)&pState2->cReferences); -/* NdisReleaseSpinLock(&pAdapt->Lock); */ } #endif -DECLINLINE(void) vboxNetFltWinDecReferenceDevice(PADAPT pAdapt, PADAPT_DEVICE pState, uint32_t v) +DECLINLINE(void) vboxNetFltWinDecReferenceDevice(PVBOXNETFLT_WINIF_DEVICE pState, uint32_t v) { Assert(v); ASMAtomicAddU32((uint32_t volatile *)&pState->cReferences, (uint32_t)(-((int32_t)v))); } #ifndef VBOXNETADP -DECLINLINE(void) vboxNetFltWinDecReferenceDevices(PADAPT pAdapt, PADAPT_DEVICE pState1, PADAPT_DEVICE pState2, uint32_t v) +DECLINLINE(void) vboxNetFltWinDecReferenceDevices(PVBOXNETFLT_WINIF_DEVICE pState1, PVBOXNETFLT_WINIF_DEVICE pState2, uint32_t v) { ASMAtomicAddU32((uint32_t volatile *)&pState1->cReferences, (uint32_t)(-((int32_t)v))); ASMAtomicAddU32((uint32_t volatile *)&pState2->cReferences, (uint32_t)(-((int32_t)v))); } #endif -DECLINLINE(bool) vboxNetFltWinDoIncReferenceDevice(PADAPT pAdapt, PADAPT_DEVICE pState, uint32_t v) +DECLINLINE(bool) vboxNetFltWinDoIncReferenceDevice(PVBOXNETFLT_WINIF_DEVICE pState, uint32_t v) { Assert(v); if (vboxNetFltWinGetPowerState(pState) == NdisDeviceStateD0 && vboxNetFltWinGetOpState(pState) == kVBoxNetDevOpState_Initialized) @@ -621,7 +568,7 @@ DECLINLINE(bool) vboxNetFltWinDoIncReferenceDevice(PADAPT pAdapt, PADAPT_DEVICE } #ifndef VBOXNETADP -DECLINLINE(bool) vboxNetFltWinDoIncReferenceDevices(PADAPT pAdapt, PADAPT_DEVICE pState1, PADAPT_DEVICE pState2, uint32_t v) +DECLINLINE(bool) vboxNetFltWinDoIncReferenceDevices(PVBOXNETFLT_WINIF_DEVICE pState1, PVBOXNETFLT_WINIF_DEVICE pState2, uint32_t v) { if (vboxNetFltWinGetPowerState(pState1) == NdisDeviceStateD0 && vboxNetFltWinGetOpState(pState1) == kVBoxNetDevOpState_Initialized @@ -636,43 +583,16 @@ DECLINLINE(bool) vboxNetFltWinDoIncReferenceDevices(PADAPT pAdapt, PADAPT_DEVICE } #endif -#ifdef VBOX_NETFLT_ONDEMAND_BIND -DECLINLINE(PVBOXNETFLTINS) vboxNetFltWinReferenceAdaptNetFltFromAdapt(PADAPT pAdapt) -{ - RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; - PVBOXNETFLTINS pNetFlt; - - pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt); - - RTSpinlockAcquireNoInts((pNetFlt)->hSpinlock, &Tmp); - if(pNetFlt->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE) - { - RTSpinlockReleaseNoInts((pNetFlt)->hSpinlock, &Tmp); - return NULL; - } - - if(!vboxNetFltWinDoReferenceDevice(pAdapt, &pAdapt->PTState)) - { - RTSpinlockReleaseNoInts((pNetFlt)->hSpinlock, &Tmp); - return NULL; - } - vboxNetFltRetain((pNetFlt), true /* fBusy */); - - RTSpinlockReleaseNoInts((pNetFlt)->hSpinlock, &Tmp); - - return pNetFlt; -} -#else -DECLINLINE(bool) vboxNetFltWinReferenceAdaptNetFlt(PVBOXNETFLTINS pNetFlt, PADAPT pAdapt, bool * pbNetFltActive) +DECLINLINE(bool) vboxNetFltWinReferenceWinIfNetFlt(PVBOXNETFLTINS pNetFlt, bool * pbNetFltActive) { RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; RTSpinlockAcquireNoInts((pNetFlt)->hSpinlock, &Tmp); #ifndef VBOXNETADP - if(!vboxNetFltWinDoReferenceDevices(pAdapt, &pAdapt->MPState, &pAdapt->PTState)) + if(!vboxNetFltWinDoReferenceDevices(&pNetFlt->u.s.WinIf.MpState, &pNetFlt->u.s.WinIf.PtState)) #else - if(!vboxNetFltWinDoReferenceDevice(pAdapt, &pAdapt->MPState)) + if(!vboxNetFltWinDoReferenceDevice(&pNetFlt->u.s.WinIf.MpState)) #endif { RTSpinlockReleaseNoInts((pNetFlt)->hSpinlock, &Tmp); @@ -695,50 +615,8 @@ DECLINLINE(bool) vboxNetFltWinReferenceAdaptNetFlt(PVBOXNETFLTINS pNetFlt, PADAP *pbNetFltActive = true; return true; } -#endif - -#ifdef VBOX_NETFLT_ONDEMAND_BIND -DECLINLINE(PVBOXNETFLTINS) vboxNetFltWinIncReferenceAdaptNetFltFromAdapt(PADAPT pAdapt, uint32_t v) -{ - RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; - PVBOXNETFLTINS pNetFlt; - uint32_t i; - - Assert(v); - if(!v) - { - return NULL; - } - - pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt); - - RTSpinlockAcquireNoInts((pNetFlt)->hSpinlock, &Tmp); - if(pNetFlt->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE) - { - RTSpinlockReleaseNoInts((pNetFlt)->hSpinlock, &Tmp); - return NULL; - } - - if(!vboxNetFltWinDoIncReferenceDevice(pAdapt, &pAdapt->PTState, v)) - { - RTSpinlockReleaseNoInts((pNetFlt)->hSpinlock, &Tmp); - return NULL; - } - - vboxNetFltRetain((pNetFlt), true /* fBusy */); - RTSpinlockReleaseNoInts((pNetFlt)->hSpinlock, &Tmp); - - /* we have marked it as busy, so can do the res references outside the lock */ - for(i = 0; i < v-1; i++) - { - vboxNetFltRetain((pNetFlt), true /* fBusy */); - } - - return pNetFlt; -} -#else -DECLINLINE(bool) vboxNetFltWinIncReferenceAdaptNetFlt(PVBOXNETFLTINS pNetFlt, PADAPT pAdapt, uint32_t v, bool *pbNetFltActive) +DECLINLINE(bool) vboxNetFltWinIncReferenceWinIfNetFlt(PVBOXNETFLTINS pNetFlt, uint32_t v, bool *pbNetFltActive) { RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; uint32_t i; @@ -752,9 +630,9 @@ DECLINLINE(bool) vboxNetFltWinIncReferenceAdaptNetFlt(PVBOXNETFLTINS pNetFlt, PA RTSpinlockAcquireNoInts((pNetFlt)->hSpinlock, &Tmp); #ifndef VBOXNETADP - if(!vboxNetFltWinDoIncReferenceDevices(pAdapt, &pAdapt->MPState, &pAdapt->PTState, v)) + if(!vboxNetFltWinDoIncReferenceDevices(&pNetFlt->u.s.WinIf.MpState, &pNetFlt->u.s.WinIf.PtState, v)) #else - if(!vboxNetFltWinDoIncReferenceDevice(pAdapt, &pAdapt->MPState, v)) + if(!vboxNetFltWinDoIncReferenceDevice(&pNetFlt->u.s.WinIf.MpState, v)) #endif { RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); @@ -788,8 +666,6 @@ DECLINLINE(bool) vboxNetFltWinIncReferenceAdaptNetFlt(PVBOXNETFLTINS pNetFlt, PA return true; } -#endif - DECLINLINE(void) vboxNetFltWinDecReferenceNetFlt(PVBOXNETFLTINS pNetFlt, uint32_t n) { uint32_t i; @@ -808,31 +684,26 @@ DECLINLINE(void) vboxNetFltWinDereferenceNetFlt(PVBOXNETFLTINS pNetFlt) vboxNetFltWinDereferenceModeNetFlt(pNetFlt); } -DECLINLINE(void) vboxNetFltWinDecReferenceAdapt(PADAPT pAdapt, uint32_t v) +DECLINLINE(void) vboxNetFltWinDecReferenceWinIf(PVBOXNETFLTINS pNetFlt, uint32_t v) { -#ifdef VBOX_NETFLT_ONDEMAND_BIND - vboxNetFltWinDecReferenceDevice(pAdapt, &pAdapt->PTState, v); -#elif defined(VBOXNETADP) - vboxNetFltWinDecReferenceDevice(pAdapt, &pAdapt->MPState, v); +#ifdef VBOXNETADP + vboxNetFltWinDecReferenceDevice(&pNetFlt->u.s.WinIf.MpState, v); #else - vboxNetFltWinDecReferenceDevices(pAdapt, &pAdapt->MPState, &pAdapt->PTState, v); + vboxNetFltWinDecReferenceDevices(&pNetFlt->u.s.WinIf.MpState, &pNetFlt->u.s.WinIf.PtState, v); #endif } -DECLINLINE(void) vboxNetFltWinDereferenceAdapt(PADAPT pAdapt) +DECLINLINE(void) vboxNetFltWinDereferenceWinIf(PVBOXNETFLTINS pNetFlt) { -#ifdef VBOX_NETFLT_ONDEMAND_BIND - vboxNetFltWinDereferenceDevice(pAdapt, &pAdapt->PTState); -#elif defined(VBOXNETADP) - vboxNetFltWinDereferenceDevice(pAdapt, &pAdapt->MPState); +#ifdef VBOXNETADP + vboxNetFltWinDereferenceDevice(&pNetFlt->u.s.WinIf.MpState); #else - vboxNetFltWinDereferenceDevices(pAdapt, &pAdapt->MPState, &pAdapt->PTState); + vboxNetFltWinDereferenceDevices(&pNetFlt->u.s.WinIf.MpState, &pNetFlt->u.s.WinIf.PtState); #endif } -DECLINLINE(bool) vboxNetFltWinIncReferenceAdapt(PADAPT pAdapt, uint32_t v) +DECLINLINE(bool) vboxNetFltWinIncReferenceWinIf(PVBOXNETFLTINS pNetFlt, uint32_t v) { - PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt); RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; Assert(v); @@ -842,12 +713,10 @@ DECLINLINE(bool) vboxNetFltWinIncReferenceAdapt(PADAPT pAdapt, uint32_t v) } RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp); -#ifdef VBOX_NETFLT_ONDEMAND_BIND - if(vboxNetFltWinDoIncReferenceDevice(pAdapt, &pAdapt->PTState)) -#elif defined(VBOXNETADP) - if(vboxNetFltWinDoIncReferenceDevice(pAdapt, &pAdapt->MPState, v)) +#ifdef VBOXNETADP + if(vboxNetFltWinDoIncReferenceDevice(&pNetFlt->u.s.WinIf.MpState, v)) #else - if(vboxNetFltWinDoIncReferenceDevices(pAdapt, &pAdapt->MPState, &pAdapt->PTState, v)) + if(vboxNetFltWinDoIncReferenceDevices(&pNetFlt->u.s.WinIf.MpState, &pNetFlt->u.s.WinIf.PtState, v)) #endif { RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); @@ -858,17 +727,14 @@ DECLINLINE(bool) vboxNetFltWinIncReferenceAdapt(PADAPT pAdapt, uint32_t v) return false; } -DECLINLINE(bool) vboxNetFltWinReferenceAdapt(PADAPT pAdapt) +DECLINLINE(bool) vboxNetFltWinReferenceWinIf(PVBOXNETFLTINS pNetFlt) { - PVBOXNETFLTINS pNetFlt = PADAPT_2_PVBOXNETFLTINS(pAdapt); RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; RTSpinlockAcquireNoInts(pNetFlt->hSpinlock, &Tmp); -#ifdef VBOX_NETFLT_ONDEMAND_BIND - if(vboxNetFltWinDoReferenceDevice(pAdapt, &pAdapt->PTState)) -#elif defined(VBOXNETADP) - if(vboxNetFltWinDoReferenceDevice(pAdapt, &pAdapt->MPState)) +#ifdef VBOXNETADP + if(vboxNetFltWinDoReferenceDevice(&pNetFlt->u.s.WinIf.MpState)) #else - if(vboxNetFltWinDoReferenceDevices(pAdapt, &pAdapt->MPState, &pAdapt->PTState)) + if(vboxNetFltWinDoReferenceDevices(&pNetFlt->u.s.WinIf.MpState, &pNetFlt->u.s.WinIf.PtState)) #endif { RTSpinlockReleaseNoInts(pNetFlt->hSpinlock, &Tmp); @@ -883,10 +749,10 @@ DECLINLINE(bool) vboxNetFltWinReferenceAdapt(PADAPT pAdapt) * methods for accessing the network card info * ***********************************************/ -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinGetMacAddress(PADAPT pAdapt, PRTMAC pMac); -DECLHIDDEN(bool) vboxNetFltWinIsPromiscuous(PADAPT pAdapt); -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinSetPromiscuous(PADAPT pAdapt, bool bYes); -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQueryPhysicalMedium(PADAPT pAdapt, NDIS_PHYSICAL_MEDIUM * pMedium); +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinGetMacAddress(PVBOXNETFLTINS pNetFlt, PRTMAC pMac); +DECLHIDDEN(bool) vboxNetFltWinIsPromiscuous(PVBOXNETFLTINS pNetFlt); +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinSetPromiscuous(PVBOXNETFLTINS pNetFlt, bool bYes); +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinQueryPhysicalMedium(PVBOXNETFLTINS pNetFlt, NDIS_PHYSICAL_MEDIUM * pMedium); /********************* * mem alloc API * @@ -906,56 +772,30 @@ DECLHIDDEN(void) vboxNetFltWinMemFree(PVOID pMemBuf); DECLHIDDEN(NDIS_STATUS) vboxNetFltWinAllocSG(UINT cbBufSize, PINTNETSG *ppSG); /************************ - * PADAPT init/fini API * + * WinIf init/fini API * ************************/ - -#if defined(VBOX_NETFLT_ONDEMAND_BIND) -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PADAPT pAdapt); -#elif defined(VBOXNETADP) -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PADAPT *ppAdapt, NDIS_HANDLE hMiniportAdapter, PNDIS_STRING pBindToMiniportName /* actually this is our miniport name*/, NDIS_HANDLE hWrapperConfigurationContext); +#if defined(VBOXNETADP) +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PVBOXNETFLTINS *ppNetFlt, NDIS_HANDLE hMiniportAdapter, PNDIS_STRING pBindToMiniportName /* actually this is our miniport name*/, NDIS_HANDLE hWrapperConfigurationContext); +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitWinIf(PVBOXNETFLTWIN pWinIf); #else -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PADAPT *ppAdapt, PNDIS_STRING pOurMiniportName, PNDIS_STRING pBindToMiniportName); +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitBind(PVBOXNETFLTINS *ppNetFlt, PNDIS_STRING pOurMiniportName, PNDIS_STRING pBindToMiniportName); +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitWinIf(PVBOXNETFLTWIN pWinIf, PNDIS_STRING pOurDeviceName); #endif -#ifdef VBOX_NETFLT_ONDEMAND_BIND -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtAllocInitPADAPT(PADAPT pAdapt); -#else -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtAllocInitPADAPT(PADAPT *ppAdapt, PNDIS_STRING pOurMiniportName, PNDIS_STRING pBindToMiniportName); -#endif - -DECLHIDDEN(VOID) vboxNetFltWinPtFiniPADAPT(PADAPT pAdapt); -#ifndef VBOXNETADP -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitPADAPT(IN PADAPT pAdapt, IN PNDIS_STRING pOurDeviceName); -#else -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPtInitPADAPT(IN PADAPT pAdapt); -#endif +DECLHIDDEN(VOID) vboxNetFltWinPtFiniWinIf(PVBOXNETFLTWIN pWinIf); /************************************ * Execute Job at passive level API * ************************************/ -typedef VOID (*JOB_ROUTINE) (PVOID pContext); +typedef VOID (*PFNVBOXNETFLT_JOB_ROUTINE) (PVOID pContext); -DECLHIDDEN(VOID) vboxNetFltWinJobSynchExecAtPassive(JOB_ROUTINE pRoutine, PVOID pContext); +DECLHIDDEN(VOID) vboxNetFltWinJobSynchExecAtPassive(PFNVBOXNETFLT_JOB_ROUTINE pfnRoutine, PVOID pContext); /******************************* * Ndis Packets processing API * *******************************/ - -#ifndef NDIS_PACKET_FIRST_NDIS_BUFFER -#define NDIS_PACKET_FIRST_NDIS_BUFFER(_Packet) ((_Packet)->Private.Head) -#endif - -#ifndef NDIS_PACKET_LAST_NDIS_BUFFER -#define NDIS_PACKET_LAST_NDIS_BUFFER(_Packet) ((_Packet)->Private.Tail) -#endif - -#ifndef NDIS_PACKET_VALID_COUNTS -#define NDIS_PACKET_VALID_COUNTS(_Packet) ((_Packet)->Private.ValidCounts) -#endif - - -DECLHIDDEN(PNDIS_PACKET) vboxNetFltWinNdisPacketFromSG(PADAPT pAdapt, PINTNETSG pSG, PVOID pBufToFree, bool bToWire, bool bCopyMemory); +DECLHIDDEN(PNDIS_PACKET) vboxNetFltWinNdisPacketFromSG(PVBOXNETFLTINS pNetFlt, PINTNETSG pSG, PVOID pBufToFree, bool bToWire, bool bCopyMemory); DECLHIDDEN(void) vboxNetFltWinFreeSGNdisPacket(PNDIS_PACKET pPacket, bool bFreeMem); @@ -1009,96 +849,53 @@ DECLINLINE(bool) vboxNetFltWinIsLoopedBackPacket(PNDIS_PACKET pPacket) #define VBOXNETFLT_OOB_INIT(_p) \ { \ NdisZeroMemory(NDIS_OOB_DATA_FROM_PACKET(_p), sizeof(NDIS_PACKET_OOB_DATA)); \ - NDIS_SET_PACKET_HEADER_SIZE(_p, ETH_HEADER_SIZE); \ + NDIS_SET_PACKET_HEADER_SIZE(_p, VBOXNETFLT_PACKET_ETHEADER_SIZE); \ } -#if !defined(VBOX_NETFLT_ONDEMAND_BIND) && !defined(VBOXNETADP) +#ifndef VBOXNETADP -DECLINLINE(NDIS_STATUS) vboxNetFltWinCopyPacketInfoOnRecv(PNDIS_PACKET pDstPacket, PNDIS_PACKET pSrcPacket) +DECLINLINE(NDIS_STATUS) vboxNetFltWinCopyPacketInfoOnRecv(PNDIS_PACKET pDstPacket, PNDIS_PACKET pSrcPacket, bool bForceStatusResources) { - NDIS_STATUS fStatus; - - /* - * Get the original packet (it could be the same packet as the one - * received or a different one based on the number of layered miniports - * below) and set it on the indicated packet so the OOB data is visible - * correctly to protocols above us. - */ - NDIS_SET_ORIGINAL_PACKET(pDstPacket, NDIS_GET_ORIGINAL_PACKET(pSrcPacket)); + NDIS_STATUS Status = bForceStatusResources ? NDIS_STATUS_RESOURCES : NDIS_GET_PACKET_STATUS(pSrcPacket); + NDIS_SET_PACKET_STATUS(pDstPacket, Status); - /* - * Set Packet Flags - */ - NdisGetPacketFlags(pDstPacket) = NdisGetPacketFlags(pSrcPacket); + NDIS_PACKET_FIRST_NDIS_BUFFER(pDstPacket) = NDIS_PACKET_FIRST_NDIS_BUFFER(pSrcPacket); + NDIS_PACKET_LAST_NDIS_BUFFER(pDstPacket) = NDIS_PACKET_LAST_NDIS_BUFFER(pSrcPacket); - fStatus = NDIS_GET_PACKET_STATUS(pSrcPacket); + NdisGetPacketFlags(pDstPacket) = NdisGetPacketFlags(pSrcPacket); - NDIS_SET_PACKET_STATUS(pDstPacket, fStatus); + NDIS_SET_ORIGINAL_PACKET(pDstPacket, NDIS_GET_ORIGINAL_PACKET(pSrcPacket)); NDIS_SET_PACKET_HEADER_SIZE(pDstPacket, NDIS_GET_PACKET_HEADER_SIZE(pSrcPacket)); - return fStatus; + return Status; } DECLINLINE(void) vboxNetFltWinCopyPacketInfoOnSend(PNDIS_PACKET pDstPacket, PNDIS_PACKET pSrcPacket) { - PVOID pMediaSpecificInfo = NULL; - UINT fMediaSpecificInfoSize = 0; + NDIS_PACKET_FIRST_NDIS_BUFFER(pDstPacket) = NDIS_PACKET_FIRST_NDIS_BUFFER(pSrcPacket); + NDIS_PACKET_LAST_NDIS_BUFFER(pDstPacket) = NDIS_PACKET_LAST_NDIS_BUFFER(pSrcPacket); NdisGetPacketFlags(pDstPacket) = NdisGetPacketFlags(pSrcPacket); -#ifdef WIN9X - /* - * Work around the fact that NDIS does not initialize this - * to FALSE on Win9x. - */ - NDIS_PACKET_VALID_COUNTS(pDstPacket) = FALSE; -#endif /* WIN9X */ - - /* - * Copy the OOB data from the original packet to the new - * packet. - */ NdisMoveMemory(NDIS_OOB_DATA_FROM_PACKET(pDstPacket), - NDIS_OOB_DATA_FROM_PACKET(pSrcPacket), - sizeof(NDIS_PACKET_OOB_DATA)); - /* - * Copy relevant parts of the per packet info into the new packet - */ -#ifndef WIN9X + NDIS_OOB_DATA_FROM_PACKET(pSrcPacket), + sizeof (NDIS_PACKET_OOB_DATA)); + NdisIMCopySendPerPacketInfo(pDstPacket, pSrcPacket); -#endif - /* - * Copy the Media specific information - */ - NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO(pSrcPacket, - &pMediaSpecificInfo, - &fMediaSpecificInfoSize); + PVOID pMediaSpecificInfo = NULL; + UINT fMediaSpecificInfoSize = 0; + + NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO(pSrcPacket, &pMediaSpecificInfo, &fMediaSpecificInfoSize); if (pMediaSpecificInfo || fMediaSpecificInfoSize) { - NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO(pDstPacket, - pMediaSpecificInfo, - fMediaSpecificInfoSize); + NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO(pDstPacket, pMediaSpecificInfo, fMediaSpecificInfoSize); } } -DECLHIDDEN(NDIS_STATUS) -vboxNetFltWinPrepareSendPacket( - IN PADAPT pAdapt, - IN PNDIS_PACKET pPacket, - OUT PNDIS_PACKET *ppMyPacket - /*, IN bool bNetFltActive*/ - ); - - -DECLHIDDEN(NDIS_STATUS) -vboxNetFltWinPrepareRecvPacket( - IN PADAPT pAdapt, - IN PNDIS_PACKET pPacket, - OUT PNDIS_PACKET *ppMyPacket, - IN bool bDpr - ); +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPrepareSendPacket(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket, PNDIS_PACKET *ppMyPacket); +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinPrepareRecvPacket(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket, PNDIS_PACKET *ppMyPacket, bool bDpr); #endif DECLHIDDEN(void) vboxNetFltWinSleep(ULONG milis); @@ -1109,7 +906,7 @@ DECLHIDDEN(void) vboxNetFltWinSleep(ULONG milis); && (_m1).au16[2] == (_m2).au16[2]) -DECLHIDDEN(NDIS_STATUS) vboxNetFltWinDetachFromInterface(PADAPT pAdapt, bool bOnUnbind); +DECLHIDDEN(NDIS_STATUS) vboxNetFltWinDetachFromInterface(PVBOXNETFLTINS pNetFlt, bool bOnUnbind); DECLHIDDEN(NDIS_STATUS) vboxNetFltWinCopyString(PNDIS_STRING pDst, PNDIS_STRING pSrc); @@ -1121,9 +918,9 @@ DECLHIDDEN(NDIS_STATUS) vboxNetFltWinCopyString(PNDIS_STRING pDst, PNDIS_STRING * @param pThis The instance. * @param enmNewState The new value. */ -DECLINLINE(void) vboxNetFltWinSetAdaptState(PADAPT pAdapt, VBOXADAPTSTATE enmNewState) +DECLINLINE(void) vboxNetFltWinSetWinIfState(PVBOXNETFLTINS pNetFlt, VBOXNETFLT_WINIFSTATE enmNewState) { - ASMAtomicWriteU32((uint32_t volatile *)&pAdapt->enmState, enmNewState); + ASMAtomicWriteU32((uint32_t volatile *)&pNetFlt->u.s.WinIf.enmState, enmNewState); } /** @@ -1134,21 +931,19 @@ DECLINLINE(void) vboxNetFltWinSetAdaptState(PADAPT pAdapt, VBOXADAPTSTATE enmNew * @returns The enmState value. * @param pThis The instance. */ -DECLINLINE(VBOXADAPTSTATE) vboxNetFltWinGetAdaptState(PADAPT pAdapt) +DECLINLINE(VBOXNETFLT_WINIFSTATE) vboxNetFltWinGetWinIfState(PVBOXNETFLTINS pNetFlt) { - return (VBOXADAPTSTATE)ASMAtomicUoReadU32((uint32_t volatile *)&pAdapt->enmState); + return (VBOXNETFLT_WINIFSTATE)ASMAtomicUoReadU32((uint32_t volatile *)&pNetFlt->u.s.WinIf.enmState); } +/* reference the driver module to prevent driver unload */ +DECLHIDDEN(void) vboxNetFltWinDrvReference(); +/* dereference the driver module to prevent driver unload */ +DECLHIDDEN(void) vboxNetFltWinDrvDereference(); + #ifndef VBOXNETADP -# define VBOXNETFLT_PROMISCUOUS_SUPPORTED(_pAdapt) \ - (!PADAPT_2_PVBOXNETFLTINS(_pAdapt)->fDisablePromiscuous) -// (!((_pAdapt)->PhMedium == NdisPhysicalMediumWirelessWan \ -// || (_pAdapt)->PhMedium == NdisPhysicalMediumWirelessLan \ -// || (_pAdapt)->PhMedium == NdisPhysicalMediumNative802_11 \ -// || (_pAdapt)->PhMedium == NdisPhysicalMediumBluetooth \ -// /*|| (_pAdapt)->PhMedium == NdisPhysicalMediumWiMax */ \ -// )) +# define VBOXNETFLT_PROMISCUOUS_SUPPORTED(_pNetFlt) (!(_pNetFlt)->fDisablePromiscuous) #else # define STATISTIC_INCREASE(_s) ASMAtomicIncU32((uint32_t volatile *)&(_s)); @@ -1157,4 +952,4 @@ DECLHIDDEN(int) vboxNetFltWinMAC2NdisString(RTMAC *pMac, PNDIS_STRING pNdisStrin DECLHIDDEN(int) vboxNetFltWinMACFromNdisString(RTMAC *pMac, PNDIS_STRING pNdisString); #endif -#endif +#endif /* #ifndef ___VBoxNetFltRt_win_h___ */ diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/Makefile.kup b/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/Makefile.kup new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/Makefile.kup diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.cpp b/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.cpp new file mode 100644 index 000000000..d0a7ac23a --- /dev/null +++ b/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.cpp @@ -0,0 +1,585 @@ +/* $Id: VBoxNetFltNobj.cpp 36184 2011-03-07 10:57:04Z vboxsync $ */ +/** @file + * VBoxNetFltNobj.cpp - Notify Object for Bridged Networking Driver. + * Used to filter Bridged Networking Driver bindings + */ +/* + * Copyright (C) 2011 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + */ +#include "VBoxNetFltNobj.h" +#include <Ntddndis.h> +#include <assert.h> +#include <stdio.h> + +#include <VBoxNetFltNobjT_i.c> + +//# define VBOXNETFLTNOTIFY_DEBUG_BIND + +#ifdef DEBUG +# define Assert(a) assert(a) +# define AssertBreakpoint() assert(0) + +#else +# define Assert(a) do{}while (0) +# define AssertBreakpoint() do{}while (0) + +#endif + +VBoxNetFltNobj::VBoxNetFltNobj() : + mpNetCfg(NULL), + mpNetCfgComponent(NULL), + mbInstalling(FALSE) +{ +} + +VBoxNetFltNobj::~VBoxNetFltNobj() +{ + cleanup(); +} + +void VBoxNetFltNobj::cleanup() +{ + if (mpNetCfg) + { + mpNetCfg->Release(); + mpNetCfg = NULL; + } + + if (mpNetCfgComponent) + { + mpNetCfgComponent->Release(); + mpNetCfgComponent = NULL; + } +} + +void VBoxNetFltNobj::init(IN INetCfgComponent *pNetCfgComponent, IN INetCfg *pNetCfg, IN BOOL bInstalling) +{ + cleanup(); + + Assert(pNetCfg); + Assert(pNetCfgComponent); + if (pNetCfg) + { + pNetCfg->AddRef(); + mpNetCfg = pNetCfg; + } + + if (pNetCfgComponent) + { + pNetCfgComponent->AddRef(); + mpNetCfgComponent = pNetCfgComponent; + } + + mbInstalling = bInstalling; +} + +/* INetCfgComponentControl methods */ +STDMETHODIMP VBoxNetFltNobj::Initialize(IN INetCfgComponent *pNetCfgComponent, IN INetCfg *pNetCfg, IN BOOL bInstalling) +{ + init(pNetCfgComponent, pNetCfg, bInstalling); + return S_OK; +} + +STDMETHODIMP VBoxNetFltNobj::ApplyRegistryChanges() +{ + return S_OK; +} + +STDMETHODIMP VBoxNetFltNobj::ApplyPnpChanges(IN INetCfgPnpReconfigCallback *pCallback) +{ + return S_OK; +} + +STDMETHODIMP VBoxNetFltNobj::CancelChanges() +{ + return S_OK; +} + +static HRESULT vboxNetFltWinQueryInstanceKey(IN INetCfgComponent *pComponent, OUT PHKEY phKey) +{ + LPWSTR pPnpId; + HRESULT hr = pComponent->GetPnpDevNodeId(&pPnpId); + if (hr == S_OK) + { + WCHAR KeyName[MAX_PATH]; + wcscpy(KeyName, L"SYSTEM\\CurrentControlSet\\Enum\\"); + wcscat(KeyName,pPnpId); + + LONG winEr = RegOpenKeyExW(HKEY_LOCAL_MACHINE, KeyName, + 0, /*__reserved DWORD ulOptions*/ + KEY_READ, /*__in REGSAM samDesired*/ + phKey); + + if (winEr != ERROR_SUCCESS) + { + hr = HRESULT_FROM_WIN32(winEr); + AssertBreakpoint(); + } + + CoTaskMemFree(pPnpId); + } + else + { + AssertBreakpoint(); + } + + return hr; +} + +static HRESULT vboxNetFltWinQueryDriverKey(IN HKEY InstanceKey, OUT PHKEY phKey) +{ + DWORD Type = REG_SZ; + WCHAR Value[MAX_PATH]; + DWORD cbValue = sizeof(Value); + HRESULT hr = S_OK; + LONG winEr = RegQueryValueExW(InstanceKey, + L"Driver", /*__in_opt LPCTSTR lpValueName*/ + 0, /*__reserved LPDWORD lpReserved*/ + &Type, /*__out_opt LPDWORD lpType*/ + (LPBYTE)Value, /*__out_opt LPBYTE lpData*/ + &cbValue/*__inout_opt LPDWORD lpcbData*/ + ); + + if (winEr == ERROR_SUCCESS) + { + WCHAR KeyName[MAX_PATH]; + wcscpy(KeyName, L"SYSTEM\\CurrentControlSet\\Control\\Class\\"); + wcscat(KeyName,Value); + + winEr = RegOpenKeyExW(HKEY_LOCAL_MACHINE, KeyName, + 0, /*__reserved DWORD ulOptions*/ + KEY_READ, /*__in REGSAM samDesired*/ + phKey); + + if (winEr != ERROR_SUCCESS) + { + hr = HRESULT_FROM_WIN32(winEr); + AssertBreakpoint(); + } + } + else + { + hr = HRESULT_FROM_WIN32(winEr); + AssertBreakpoint(); + } + + return hr; +} + +static HRESULT vboxNetFltWinQueryDriverKey(IN INetCfgComponent *pComponent, OUT PHKEY phKey) +{ + HKEY InstanceKey; + HRESULT hr = vboxNetFltWinQueryInstanceKey(pComponent, &InstanceKey); + if (hr == S_OK) + { + hr = vboxNetFltWinQueryDriverKey(InstanceKey, phKey); + if (hr != S_OK) + { + AssertBreakpoint(); + } + RegCloseKey(InstanceKey); + } + else + { + AssertBreakpoint(); + } + + return hr; +} + +static HRESULT vboxNetFltWinNotifyCheckNetAdp(IN INetCfgComponent *pComponent, OUT bool * pbShouldBind) +{ + HRESULT hr; + LPWSTR pDevId; + hr = pComponent->GetId(&pDevId); + if (hr == S_OK) + { + if (!_wcsnicmp(pDevId, L"sun_VBoxNetAdp", sizeof(L"sun_VBoxNetAdp")/2)) + { + *pbShouldBind = false; + } + else + { + hr = S_FALSE; + } + CoTaskMemFree(pDevId); + } + else + { + AssertBreakpoint(); + } + + return hr; +} + +static HRESULT vboxNetFltWinNotifyCheckMsLoop(IN INetCfgComponent *pComponent, OUT bool * pbShouldBind) +{ + HRESULT hr; + LPWSTR pDevId; + hr = pComponent->GetId(&pDevId); + if (hr == S_OK) + { + if (!_wcsnicmp(pDevId, L"*msloop", sizeof(L"*msloop")/2)) + { + /* we need to detect the medium the adapter is presenting + * to do that we could examine in the registry the *msloop params */ + HKEY DriverKey; + hr = vboxNetFltWinQueryDriverKey(pComponent, &DriverKey); + if (hr == S_OK) + { + DWORD Type = REG_SZ; + WCHAR Value[64]; /* 2 should be enough actually, paranoid check for extra spaces */ + DWORD cbValue = sizeof(Value); + LONG winEr = RegQueryValueExW(DriverKey, + L"Medium", /*__in_opt LPCTSTR lpValueName*/ + 0, /*__reserved LPDWORD lpReserved*/ + &Type, /*__out_opt LPDWORD lpType*/ + (LPBYTE)Value, /*__out_opt LPBYTE lpData*/ + &cbValue/*__inout_opt LPDWORD lpcbData*/ + ); + if (winEr == ERROR_SUCCESS) + { + PWCHAR endPrt; + ULONG enmMedium = wcstoul(Value, + &endPrt, + 0 /* base*/); + + winEr = errno; + if (winEr == ERROR_SUCCESS) + { + if (enmMedium == 0) /* 0 is Ethernet */ + { + *pbShouldBind = true; + } + else + { + *pbShouldBind = false; + } + } + else + { + AssertBreakpoint(); + *pbShouldBind = true; + } + } + else + { + /* TODO: we should check the default medium in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002bE10318}\<driver_id>\Ndi\Params\Medium, REG_SZ "Default" value */ + AssertBreakpoint(); + *pbShouldBind = true; + } + + RegCloseKey(DriverKey); + } + else + { + AssertBreakpoint(); + } + } + else + { + hr = S_FALSE; + } + CoTaskMemFree(pDevId); + } + else + { + AssertBreakpoint(); + } + + return hr; +} + +static HRESULT vboxNetFltWinNotifyCheckLowerRange(IN INetCfgComponent *pComponent, OUT bool * pbShouldBind) +{ + HKEY DriverKey; + HKEY InterfacesKey; + HRESULT hr = vboxNetFltWinQueryDriverKey(pComponent, &DriverKey); + if (hr == S_OK) + { + LONG winEr = RegOpenKeyExW(DriverKey, L"Ndi\\Interfaces", + 0, /*__reserved DWORD ulOptions*/ + KEY_READ, /*__in REGSAM samDesired*/ + &InterfacesKey); + if (winEr == ERROR_SUCCESS) + { + DWORD Type = REG_SZ; + WCHAR Value[MAX_PATH]; + DWORD cbValue = sizeof(Value); + winEr = RegQueryValueExW(InterfacesKey, + L"LowerRange", /*__in_opt LPCTSTR lpValueName*/ + 0, /*__reserved LPDWORD lpReserved*/ + &Type, /*__out_opt LPDWORD lpType*/ + (LPBYTE)Value, /*__out_opt LPBYTE lpData*/ + &cbValue/*__inout_opt LPDWORD lpcbData*/ + ); + if (winEr == ERROR_SUCCESS) + { + if (wcsstr(Value,L"ethernet") || wcsstr(Value, L"wan")) + { + *pbShouldBind = true; + } + else + { + *pbShouldBind = false; + } + } + else + { + /* do not set err status to it */ + *pbShouldBind = false; + AssertBreakpoint(); + } + + RegCloseKey(InterfacesKey); + } + else + { + hr = HRESULT_FROM_WIN32(winEr); + AssertBreakpoint(); + } + + RegCloseKey(DriverKey); + } + else + { + AssertBreakpoint(); + } + + return hr; +} + +static HRESULT vboxNetFltWinNotifyShouldBind(IN INetCfgComponent *pComponent, OUT bool *pbShouldBind) +{ + DWORD fCharacteristics; + HRESULT hr; + + do + { + /* filter out only physical adapters */ + hr = pComponent->GetCharacteristics(&fCharacteristics); + if (hr != S_OK) + { + AssertBreakpoint(); + break; + } + + + if (fCharacteristics & NCF_HIDDEN) + { + /* we are not binding to hidden adapters */ + *pbShouldBind = false; + break; + } + + hr = vboxNetFltWinNotifyCheckMsLoop(pComponent, pbShouldBind); + if (hr == S_OK) + { + /* this is a loopback adapter, + * the pbShouldBind already contains the result */ + break; + } + else if (hr != S_FALSE) + { + /* error occurred */ + break; + } + + hr = vboxNetFltWinNotifyCheckNetAdp(pComponent, pbShouldBind); + if (hr == S_OK) + { + /* this is a VBoxNetAdp adapter, + * the pbShouldBind already contains the result */ + break; + } + else if (hr != S_FALSE) + { + /* error occurred */ + break; + } + + /* hr == S_FALSE means this is not a loopback adpater, set it to S_OK */ + hr = S_OK; + +// if (!(fCharacteristics & NCF_PHYSICAL)) +// { +// /* we are binding to physical adapters only */ +// *pbShouldBind = false; +// break; +// } + + hr = vboxNetFltWinNotifyCheckLowerRange(pComponent, pbShouldBind); + if (hr == S_OK) + { + /* the vboxNetFltWinNotifyCheckLowerRange ccucceeded, + * the pbShouldBind already contains the result */ + break; + } + /* we are here because of the fail, nothing else to do */ + } while (0); + + return hr; +} + + +static HRESULT vboxNetFltWinNotifyShouldBind(IN INetCfgBindingInterface *pIf, OUT bool *pbShouldBind) +{ + INetCfgComponent * pAdapterComponent; + HRESULT hr = pIf->GetLowerComponent(&pAdapterComponent); + if (hr == S_OK) + { + hr = vboxNetFltWinNotifyShouldBind(pAdapterComponent, pbShouldBind); + + pAdapterComponent->Release(); + } + else + { + AssertBreakpoint(); + } + + return hr; +} + +static HRESULT vboxNetFltWinNotifyShouldBind(IN INetCfgBindingPath *pPath, OUT bool *pbDoBind) +{ + IEnumNetCfgBindingInterface *pEnumBindingIf; + HRESULT hr = pPath->EnumBindingInterfaces(&pEnumBindingIf); + if (hr == S_OK) + { + hr = pEnumBindingIf->Reset(); + if (hr == S_OK) + { + ULONG ulCount; + INetCfgBindingInterface *pBindingIf; + do + { + hr = pEnumBindingIf->Next(1, &pBindingIf, &ulCount); + if (hr == S_OK) + { + hr = vboxNetFltWinNotifyShouldBind(pBindingIf, pbDoBind); + + pBindingIf->Release(); + + if (hr == S_OK) + { + if (!(*pbDoBind)) + { + break; + } + } + else + { + /* break on failure */ + break; + } + } + else if (hr == S_FALSE) + { + /* no more elements */ + hr = S_OK; + break; + } + else + { + AssertBreakpoint(); + /* break on falure */ + break; + } + } while (true); + } + else + { + AssertBreakpoint(); + } + + pEnumBindingIf->Release(); + } + else + { + AssertBreakpoint(); + } + + return hr; +} + +static bool vboxNetFltWinNotifyShouldBind(IN INetCfgBindingPath *pPath) +{ +#ifdef VBOXNETFLTNOTIFY_DEBUG_BIND + return VBOXNETFLTNOTIFY_DEBUG_BIND; +#else + bool bShouldBind; + HRESULT hr = vboxNetFltWinNotifyShouldBind(pPath, &bShouldBind) ; + if (hr != S_OK) + { + bShouldBind = VBOXNETFLTNOTIFY_ONFAIL_BINDDEFAULT; + } + + return bShouldBind; +#endif +} + + +/* INetCfgComponentNotifyBinding methods */ +STDMETHODIMP VBoxNetFltNobj::NotifyBindingPath(IN DWORD dwChangeFlag, IN INetCfgBindingPath *pNetCfgBP) +{ + if (!(dwChangeFlag & NCN_ENABLE) || (dwChangeFlag & NCN_REMOVE) || vboxNetFltWinNotifyShouldBind(pNetCfgBP)) + return S_OK; + return NETCFG_S_DISABLE_QUERY; +} + +STDMETHODIMP VBoxNetFltNobj::QueryBindingPath(IN DWORD dwChangeFlag, IN INetCfgBindingPath *pNetCfgBP) +{ + if (vboxNetFltWinNotifyShouldBind(pNetCfgBP)) + return S_OK; + return NETCFG_S_DISABLE_QUERY; +} + + +CComModule _Module; + +BEGIN_OBJECT_MAP(ObjectMap) + OBJECT_ENTRY(CLSID_VBoxNetFltNobj, VBoxNetFltNobj) +END_OBJECT_MAP() + +extern "C" +BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) +{ + if (dwReason == DLL_PROCESS_ATTACH) + { + _Module.Init(ObjectMap, hInstance); + DisableThreadLibraryCalls(hInstance); + } + else if (dwReason == DLL_PROCESS_DETACH) + { + _Module.Term(); + } + return TRUE; +} + +STDAPI DllCanUnloadNow() +{ + return (_Module.GetLockCount() == 0) ? S_OK : S_FALSE; +} + +STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) +{ + return _Module.GetClassObject(rclsid, riid, ppv); +} + +STDAPI DllRegisterServer() +{ + return _Module.RegisterServer(TRUE); +} + +STDAPI DllUnregisterServer() +{ + return _Module.UnregisterServer(TRUE); +} diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.def b/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.def new file mode 100644 index 000000000..6512eefc6 --- /dev/null +++ b/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.def @@ -0,0 +1,22 @@ +; $Id: VBoxNetFltNobj.def 36184 2011-03-07 10:57:04Z vboxsync $ +; @file +; VBoxNetFltNobj.def - Notify Object for Bridged Networking Driver. +; Library def file +; +; +; Copyright (C) 2011 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +LIBRARY VBoxNetFltNobj +EXPORTS + DllCanUnloadNow PRIVATE + DllGetClassObject PRIVATE + DllRegisterServer PRIVATE + DllUnregisterServer PRIVATE
\ No newline at end of file diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.h b/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.h new file mode 100644 index 000000000..036df1dee --- /dev/null +++ b/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.h @@ -0,0 +1,73 @@ +/* $Id: VBoxNetFltNobj.h 36184 2011-03-07 10:57:04Z vboxsync $ */ +/** @file + * VBoxNetFltNobj.h - Notify Object for Bridged Networking Driver. + * Used to filter Bridged Networking Driver bindings + */ +/* + * Copyright (C) 2011 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + */ +#ifndef ___VboxNetFltNobj_h___ +#define ___VboxNetFltNobj_h___ + +#include <windows.h> +/* atl stuff */ +#include <atlbase.h> +extern CComModule _Module; +#include <atlcom.h> + +#include "VBoxNetFltNobjT.h" +#include "VBoxNetFltNobjRc.h" + +#define VBOXNETFLTNOTIFY_ONFAIL_BINDDEFAULT false + +/* + * VirtualBox Bridging driver notify object. + * Needed to make our driver bind to "real" host adapters only + */ +class ATL_NO_VTABLE VBoxNetFltNobj : + public CComObjectRootEx<CComObjectThreadModel>, + public CComCoClass<VBoxNetFltNobj, &CLSID_VBoxNetFltNobj>, + public INetCfgComponentControl, + public INetCfgComponentNotifyBinding +{ +public: + VBoxNetFltNobj(); + ~VBoxNetFltNobj(); + + BEGIN_COM_MAP(VBoxNetFltNobj) + COM_INTERFACE_ENTRY(INetCfgComponentControl) + COM_INTERFACE_ENTRY(INetCfgComponentNotifyBinding) + END_COM_MAP() + + DECLARE_REGISTRY_RESOURCEID(IDR_VBOXNETFLT_NOBJ) + + /* INetCfgComponentControl methods */ + STDMETHOD(Initialize)(IN INetCfgComponent *pNetCfgComponent, IN INetCfg *pNetCfg, IN BOOL bInstalling); + STDMETHOD(ApplyRegistryChanges)(); + STDMETHOD(ApplyPnpChanges)(IN INetCfgPnpReconfigCallback *pCallback); + STDMETHOD(CancelChanges)(); + + /* INetCfgComponentNotifyBinding methods */ + STDMETHOD(NotifyBindingPath)(IN DWORD dwChangeFlag, IN INetCfgBindingPath *pNetCfgBP); + STDMETHOD(QueryBindingPath)(IN DWORD dwChangeFlag, IN INetCfgBindingPath *pNetCfgBP); +private: + + void init(IN INetCfgComponent *pNetCfgComponent, IN INetCfg *pNetCfg, IN BOOL bInstalling); + void cleanup(); + + /* these two used to maintain the component info passed to + * INetCfgComponentControl::Initialize */ + INetCfg *mpNetCfg; + INetCfgComponent *mpNetCfgComponent; + BOOL mbInstalling; +}; + +#endif /* #ifndef ___VboxNetFltNobj_h___ */ diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.rc b/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.rc index 165b50bd0..57f92364c 100644 --- a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.rc +++ b/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.rc @@ -1,10 +1,10 @@ -/* $Id: VBoxNetFltNotify.rc $ */ +/* $Id: VBoxNetFltNobj.rc 36184 2011-03-07 10:57:04Z vboxsync $ */ /** @file - * VBoxNetFltNotify - Resource file containing version info and icon. + * VBoxNetFltNobj.h - Notify Object for Bridged Networking Driver. + * Resource file */ - /* - * Copyright (C) 2009-2010 Oracle Corporation + * Copyright (C) 2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -18,13 +18,7 @@ #include <windows.h> #include <VBox/version.h> -#include "VBoxNetFltNotifyRc.h" -///////////////////////////////////////////////////////////////////////////// -// -// REGISTRY -// -1 TYPELIB "VBoxNetFltNotifyn.tlb" -IDR_REG_VBOXNETFLT_NOTIFY REGISTRY "VBoxNetFltNotify.rgs" +#include "VBoxNetFltNobjRc.h" VS_VERSION_INFO VERSIONINFO FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0 @@ -44,11 +38,11 @@ BEGIN BLOCK "040904E4" // Lang=US English, CharSet=Windows Multilingual BEGIN VALUE "CompanyName", VBOX_RC_COMPANY_NAME - VALUE "FileDescription", "VirtualBox Bridged Networking Driver Notify Object\0" + VALUE "FileDescription", "VirtualBox Bridged Networking Driver Notify Object v1.1\0" VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0" - VALUE "InternalName", "VBoxNetFltNotify.dll\0" + VALUE "InternalName", "VBoxNetFltNobj.dll\0" VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT - VALUE "OriginalFilename","VBoxNetFltNotify.dll\0" + VALUE "OriginalFilename","VBoxNetFltNobj.dll\0" VALUE "ProductName", VBOX_PRODUCT "\0" VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0" END @@ -59,3 +53,11 @@ BEGIN END END +///////////////////////////////////////////////////////////////////////////// +// +// REGISTRY +// + +IDR_VBOXNETFLT_NOBJ REGISTRY "VBoxNetFltNobj.rgs" + +1 TYPELIB "VBoxNetFltNobjT.tlb" diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.rgs b/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.rgs index 2cc93c88d..d6f9bae32 100644 --- a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.rgs +++ b/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.rgs @@ -2,7 +2,7 @@ HKCR { NoRemove CLSID { - ForceRemove {c631480a-acbe-4add-bb1d-3ed8aa52b5d9} = s 'VirtualBox Bridged Networking Driver Notify Object' + ForceRemove {f374d1a0-bf08-4bdc-9cb2-c15ddaeef955} = s 'VirtualBox Bridged Networking Driver Notify Object v1.1' { InProcServer32 = s '%MODULE%' { diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobjRc.h b/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobjRc.h new file mode 100644 index 000000000..cedcda7f3 --- /dev/null +++ b/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobjRc.h @@ -0,0 +1,23 @@ +/* $Id: VBoxNetFltNobjRc.h 36184 2011-03-07 10:57:04Z vboxsync $ */ +/** @file + * VBoxNetFltNobjRc.h - Notify Object for Bridged Networking Driver. + * Resource definitions + */ +/* + * Copyright (C) 2011 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + */ +#ifndef ___VboxNetFltNobjRc_h___ +#define ___VboxNetFltNobjRc_h___ + +/* registry script rc ID */ +#define IDR_VBOXNETFLT_NOBJ 101 + +#endif /* #ifndef ___VboxNetFltNobjRc_h___ */ diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotifyn.idl b/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobjT.idl index 089b79ee2..22b6f2bfe 100644 --- a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotifyn.idl +++ b/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobjT.idl @@ -1,10 +1,10 @@ -/* $Id: VBoxNetFltNotifyn.idl $ */ +/* $Id: VBoxNetFltNobjT.idl 36184 2011-03-07 10:57:04Z vboxsync $ */ /** @file - * VBoxNetFltNotify.idl - Network Filter Driver (Host), Windows Specific Code. Integration with IntNet/NetFlt + * VBoxNetFltNobjT.idl - Notify Object for Bridged Networking Driver. + * Type lib definition */ - /* - * Copyright (C) 2008 Oracle Corporation + * Copyright (C) 2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -14,29 +14,20 @@ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. */ -/* - * Based in part on Microsoft DDK sample code for Sample Notify Object - *+--------------------------------------------------------------------------- - * - * Microsoft Windows - * Copyright (C) Microsoft Corporation, 1992-2001. - * - *---------------------------------------------------------------------------- - */ #include <netcfgn.idl> [ - uuid(1ea703af-a150-4fdd-83dc-c07a7a460c7e), - version(1.0), - helpstring("VirtualBox Bridged Networking Driver Notify Object 1.0 Type Library") + uuid(2a0c94d1-40e1-439c-8fe8-24107cab0840), + version(1.1), + helpstring("VirtualBox Bridged Networking Driver Notify Object v1.1 Type Library") ] -library VBoxNetFltNotifyLib +library VBoxNetFltNobjLib { [ - uuid(c631480a-acbe-4add-bb1d-3ed8aa52b5d9), + uuid(f374d1a0-bf08-4bdc-9cb2-c15ddaeef955), helpstring("VirtualBox Bridged Networking Driver Notify Object Class") ] - coclass VBoxNetFltNotify + coclass VBoxNetFltNobj { [restricted] interface INetCfgComponentControl; [restricted] interface INetCfgComponentNotifyBinding; diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.cpp b/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.cpp deleted file mode 100644 index b5c57ea36..000000000 --- a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.cpp +++ /dev/null @@ -1,769 +0,0 @@ -/* - * Copyright (C) 2008 Oracle Corporation - * - * This file is part of VirtualBox Open Source Edition (OSE), as - * available from http://www.virtualbox.org. This file is free software; - * you can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) as published by the Free Software - * Foundation, in version 2 as it comes in the "COPYING" file of the - * VirtualBox OSE distribution. VirtualBox OSE is distributed in the - * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. - */ -/* - * Based in part on Microsoft DDK sample code for Sample Notify Object - *+--------------------------------------------------------------------------- - * - * Microsoft Windows - * Copyright (C) Microsoft Corporation, 1992-2001. - * - * Author: Alok Sinha - * - *---------------------------------------------------------------------------- - */ -#include "VBoxNetFltNotify.h" -#include <Ntddndis.h> -#include <assert.h> -#include <stdio.h> - -#include <VBoxNetFltNotifyn_i.c> - -CComModule _Module; - -BEGIN_OBJECT_MAP(ObjectMap) - OBJECT_ENTRY(CLSID_VBoxNetFltNotify, VBoxNetFltNotify) -END_OBJECT_MAP() - -#define ReleaseObj( x ) if ( x ) \ - ((IUnknown*)(x))->Release(); - -//# define VBOXNETFLTNOTIFY_DEBUG_BIND true - -#ifdef DEBUG -# define Assert(a) assert(a) -# define AssertBreakpoint() assert(0) - -# define TraceMsg DbgTraceMsg -#else -# define Assert(a) do{}while(0) -# define AssertBreakpoint() do{}while(0) - -# define TraceMsg -#endif - - -static void DbgTraceMsg (LPWSTR szFormat, ...) -{ - static WCHAR szTempBuf[4096]; - - va_list arglist; - - va_start(arglist, szFormat); - - vswprintf( szTempBuf, szFormat, arglist ); - - OutputDebugStringW( szTempBuf ); - - va_end(arglist); -} - -VBoxNetFltNotify::VBoxNetFltNotify (VOID) : m_pncc (NULL), - m_pnc(NULL) - /*, - m_eApplyAction(eActUnknown), - m_pUnkContext(NULL)*/ -{ - TraceMsg(L"VBoxNetFltNotify\n"); -} - -VBoxNetFltNotify::~VBoxNetFltNotify (VOID) -{ - TraceMsg(L"-->~VBoxNetFltNotify (destructor)\n"); - ReleaseObj( m_pncc ); - ReleaseObj( m_pnc ); - TraceMsg(L"<--~VBoxNetFltNotify (destructor)\n"); -} - -/* - * NOTIFY OBJECT FUNCTIONS - */ - -/* - * INetCfgComponentControl - * - * The following functions provide the INetCfgComponentControl interface. - */ - -/** - * Initialize the notify object - * - * @param pnccItem Pointer to INetCfgComponent object - * @param pnc Pointer to INetCfg object - * @param fInstalling TRUE if we are being installed - * @return S_OK on success, otherwise an error code - */ -STDMETHODIMP VBoxNetFltNotify::Initialize (INetCfgComponent* pncc, - INetCfg* pnc, - BOOL fInstalling) -{ - HRESULT hr = S_OK; - - TraceMsg(L"-->Initialize\n"); - - m_pncc = pncc; - m_pnc = pnc; - - if (m_pncc) - { - m_pncc->AddRef(); - } - - if (m_pnc) - { - m_pnc->AddRef(); - } - - TraceMsg(L"<--Initialize\n"); - - return hr; -} - -/** - * Cancel any changes made to internal data - * @return S_OK on success, otherwise an error code - */ -STDMETHODIMP VBoxNetFltNotify::CancelChanges (VOID) -{ - TraceMsg(L"CancelChanges\n"); - return S_OK; -} - -/* - * Apply changes. We can make changes to registry etc. here. - * @return S_OK on success, otherwise an error code - */ -STDMETHODIMP VBoxNetFltNotify::ApplyRegistryChanges(VOID) -{ - TraceMsg(L"ApplyRegistryChanges\n"); - return S_OK; -} - -/** - * Apply changes. - * @param pfCallback PnPConfigCallback interface. - * @return S_OK on success, otherwise an error code - */ -STDMETHODIMP VBoxNetFltNotify::ApplyPnpChanges ( - INetCfgPnpReconfigCallback* pfCallback) -{ - TraceMsg(L"ApplyPnpChanges\n"); - return S_OK; -} - -static HRESULT vboxNetFltWinQueryInstanceKey(IN INetCfgComponent *pComponent, OUT PHKEY phKey) -{ - LPWSTR pPnpId; - HRESULT hr = pComponent->GetPnpDevNodeId(&pPnpId); - if(hr == S_OK) - { - WCHAR KeyName[MAX_PATH]; - wcscpy(KeyName, L"SYSTEM\\CurrentControlSet\\Enum\\"); - wcscat(KeyName,pPnpId); - - LONG winEr = RegOpenKeyExW(HKEY_LOCAL_MACHINE, KeyName, - 0, /*__reserved DWORD ulOptions*/ - KEY_READ, /*__in REGSAM samDesired*/ - phKey); - - if(winEr != ERROR_SUCCESS) - { - hr = HRESULT_FROM_WIN32(winEr); - TraceMsg(L"vboxNetFltWinQueryInstanceKey: RegOpenKeyExW error, hr (0x%x)\n", hr); - AssertBreakpoint(); - } - - CoTaskMemFree(pPnpId); - } - else - { - TraceMsg(L"vboxNetFltWinQueryInstanceKey: GetPnpDevNodeId error, hr (0x%x)\n", hr); - AssertBreakpoint(); - } - - return hr; -} - -static HRESULT vboxNetFltWinQueryDriverKey(IN HKEY InstanceKey, OUT PHKEY phKey) -{ - DWORD Type = REG_SZ; - WCHAR Value[MAX_PATH]; - DWORD cbValue = sizeof(Value); - HRESULT hr = S_OK; - LONG winEr = RegQueryValueExW(InstanceKey, - L"Driver", /*__in_opt LPCTSTR lpValueName*/ - 0, /*__reserved LPDWORD lpReserved*/ - &Type, /*__out_opt LPDWORD lpType*/ - (LPBYTE)Value, /*__out_opt LPBYTE lpData*/ - &cbValue/*__inout_opt LPDWORD lpcbData*/ - ); - - if(winEr == ERROR_SUCCESS) - { - WCHAR KeyName[MAX_PATH]; - wcscpy(KeyName, L"SYSTEM\\CurrentControlSet\\Control\\Class\\"); - wcscat(KeyName,Value); - - winEr = RegOpenKeyExW(HKEY_LOCAL_MACHINE, KeyName, - 0, /*__reserved DWORD ulOptions*/ - KEY_READ, /*__in REGSAM samDesired*/ - phKey); - - if(winEr != ERROR_SUCCESS) - { - hr = HRESULT_FROM_WIN32(winEr); - TraceMsg(L"vboxNetFltWinQueryDriverKey from instance key: RegOpenKeyExW error, hr (0x%x)\n", hr); - AssertBreakpoint(); - } - } - else - { - hr = HRESULT_FROM_WIN32(winEr); - TraceMsg(L"vboxNetFltWinQueryDriverKey from instance key: RegQueryValueExW error, hr (0x%x)\n", hr); - AssertBreakpoint(); - } - - return hr; -} - -static HRESULT vboxNetFltWinQueryDriverKey(IN INetCfgComponent *pComponent, OUT PHKEY phKey) -{ - HKEY InstanceKey; - HRESULT hr = vboxNetFltWinQueryInstanceKey(pComponent, &InstanceKey); - if(hr == S_OK) - { - hr = vboxNetFltWinQueryDriverKey(InstanceKey, phKey); - if(hr != S_OK) - { - TraceMsg(L"vboxNetFltWinQueryDriverKey from Component: vboxNetFltWinQueryDriverKey error, hr (0x%x)\n", hr); - AssertBreakpoint(); - } - RegCloseKey(InstanceKey); - } - else - { - TraceMsg(L"vboxNetFltWinQueryDriverKey from Component: vboxNetFltWinQueryInstanceKey error, hr (0x%x)\n", hr); - AssertBreakpoint(); - } - - return hr; -} - -static HRESULT vboxNetFltWinNotifyCheckNetAdp(IN INetCfgComponent *pComponent, OUT bool * pbShouldBind) -{ - HRESULT hr; - LPWSTR pDevId; - hr = pComponent->GetId(&pDevId); - if(hr == S_OK) - { - if(!_wcsnicmp(pDevId, L"sun_VBoxNetAdp", sizeof(L"sun_VBoxNetAdp")/2)) - { - *pbShouldBind = false; - } - else - { - hr = S_FALSE; - } - CoTaskMemFree(pDevId); - } - else - { - TraceMsg(L"vboxNetFltWinNotifyCheckNetAdp: GetId failed, hr (0x%x)\n", hr); - AssertBreakpoint(); - } - - return hr; -} - -static HRESULT vboxNetFltWinNotifyCheckMsLoop(IN INetCfgComponent *pComponent, OUT bool * pbShouldBind) -{ - HRESULT hr; - LPWSTR pDevId; - hr = pComponent->GetId(&pDevId); - if(hr == S_OK) - { - if(!_wcsnicmp(pDevId, L"*msloop", sizeof(L"*msloop")/2)) - { - /* we need to detect the medium the adapter is presenting - * to do that we could examine in the registry the *msloop params */ - HKEY DriverKey; - hr = vboxNetFltWinQueryDriverKey(pComponent, &DriverKey); - if(hr == S_OK) - { - DWORD Type = REG_SZ; - WCHAR Value[64]; /* 2 should be enough actually, paranoid check for extra spaces */ - DWORD cbValue = sizeof(Value); - LONG winEr = RegQueryValueExW(DriverKey, - L"Medium", /*__in_opt LPCTSTR lpValueName*/ - 0, /*__reserved LPDWORD lpReserved*/ - &Type, /*__out_opt LPDWORD lpType*/ - (LPBYTE)Value, /*__out_opt LPBYTE lpData*/ - &cbValue/*__inout_opt LPDWORD lpcbData*/ - ); - if(winEr == ERROR_SUCCESS) - { - PWCHAR endPrt; - ULONG enmMedium = wcstoul(Value, - &endPrt, - 0 /* base*/); - - winEr = errno; - if(winEr == ERROR_SUCCESS) - { - if(enmMedium == 0) /* 0 is Ethernet */ - { - TraceMsg(L"vboxNetFltWinNotifyCheckMsLoop: loopback is configured as ethernet, binding\n", winEr); - *pbShouldBind = true; - } - else - { - TraceMsg(L"vboxNetFltWinNotifyCheckMsLoop: loopback is configured as NOT ethernet, NOT binding\n", winEr); - *pbShouldBind = false; - } - } - else - { - TraceMsg(L"vboxNetFltWinNotifyCheckMsLoop: wcstoul error, winEr (%d), ignoring and binding\n", winEr); - AssertBreakpoint(); - *pbShouldBind = true; - } - } - else - { - TraceMsg(L"vboxNetFltWinNotifyCheckMsLoop: RegQueryValueExW failed, winEr (%d), ignoring, binding\n", hr); - /* TODO: we should check the default medium in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002bE10318}\<driver_id>\Ndi\Params\Medium, REG_SZ "Default" value */ - AssertBreakpoint(); - *pbShouldBind = true; - } - - RegCloseKey(DriverKey); - } - else - { - TraceMsg(L"vboxNetFltWinNotifyCheckMsLoop: vboxNetFltWinQueryDriverKey for msloop failed, hr (0x%x)\n", hr); - AssertBreakpoint(); - } - } - else - { - hr = S_FALSE; - } - CoTaskMemFree(pDevId); - } - else - { - TraceMsg(L"vboxNetFltWinNotifyCheckMsLoop: GetId failed, hr (0x%x)\n", hr); - AssertBreakpoint(); - } - - return hr; -} - -static HRESULT vboxNetFltWinNotifyCheckLowerRange(IN INetCfgComponent *pComponent, OUT bool * pbShouldBind) -{ - HKEY DriverKey; - HKEY InterfacesKey; - HRESULT hr = vboxNetFltWinQueryDriverKey(pComponent, &DriverKey); - if(hr == S_OK) - { - LONG winEr = RegOpenKeyExW(DriverKey, L"Ndi\\Interfaces", - 0, /*__reserved DWORD ulOptions*/ - KEY_READ, /*__in REGSAM samDesired*/ - &InterfacesKey); - if(winEr == ERROR_SUCCESS) - { - DWORD Type = REG_SZ; - WCHAR Value[MAX_PATH]; - DWORD cbValue = sizeof(Value); - winEr = RegQueryValueExW(InterfacesKey, - L"LowerRange", /*__in_opt LPCTSTR lpValueName*/ - 0, /*__reserved LPDWORD lpReserved*/ - &Type, /*__out_opt LPDWORD lpType*/ - (LPBYTE)Value, /*__out_opt LPBYTE lpData*/ - &cbValue/*__inout_opt LPDWORD lpcbData*/ - ); - if(winEr == ERROR_SUCCESS) - { - if(wcsstr(Value,L"ethernet") || wcsstr(Value, L"wan")) - { - *pbShouldBind = true; - } - else - { - *pbShouldBind = false; - } - } - else - { - /* do not set err status to it */ - *pbShouldBind = false; - TraceMsg(L"vboxNetFltWinNotifyCheckLowerRange: RegQueryValueExW for LowerRange error, winEr (%d), not binding\n", winEr); - AssertBreakpoint(); - } - - RegCloseKey(InterfacesKey); - } - else - { - hr = HRESULT_FROM_WIN32(winEr); - TraceMsg(L"vboxNetFltWinNotifyCheckLowerRange: RegOpenKeyExW error, hr (0x%x)\n", hr); - AssertBreakpoint(); - } - - RegCloseKey(DriverKey); - } - else - { - TraceMsg(L"vboxNetFltWinNotifyShouldBind for INetCfgComponen: vboxNetFltWinQueryDriverKey failed, hr (0x%x)\n", hr); - AssertBreakpoint(); - } - - return hr; -} - -static HRESULT vboxNetFltWinNotifyShouldBind(IN INetCfgComponent *pComponent, OUT bool *pbShouldBind) -{ - TraceMsg(L"-->vboxNetFltWinNotifyShouldBind for INetCfgComponent\n"); - DWORD fCharacteristics; - HRESULT hr; - - do - { - /* filter out only physical adapters */ - hr = pComponent->GetCharacteristics(&fCharacteristics); - if(hr != S_OK) - { - TraceMsg(L"vboxNetFltWinNotifyShouldBind for INetCfgComponen: GetCharacteristics failed, hr (0x%x)\n", hr); - AssertBreakpoint(); - break; - } - - - if(fCharacteristics & NCF_HIDDEN) - { - /* we are not binding to hidden adapters */ - *pbShouldBind = false; - break; - } - - hr = vboxNetFltWinNotifyCheckMsLoop(pComponent, pbShouldBind); - if(hr == S_OK) - { - /* this is a loopback adapter, - * the pbShouldBind already contains the result */ - break; - } - else if(hr != S_FALSE) - { - /* error occurred */ - break; - } - - hr = vboxNetFltWinNotifyCheckNetAdp(pComponent, pbShouldBind); - if(hr == S_OK) - { - /* this is a VBoxNetAdp adapter, - * the pbShouldBind already contains the result */ - break; - } - else if(hr != S_FALSE) - { - /* error occurred */ - break; - } - - /* hr == S_FALSE means this is not a loopback adpater, set it to S_OK */ - hr = S_OK; - -// if(!(fCharacteristics & NCF_PHYSICAL)) -// { -// /* we are binding to physical adapters only */ -// *pbShouldBind = false; -// break; -// } - - hr = vboxNetFltWinNotifyCheckLowerRange(pComponent, pbShouldBind); - if(hr == S_OK) - { - /* the vboxNetFltWinNotifyCheckLowerRange ccucceeded, - * the pbShouldBind already contains the result */ - break; - } - /* we are here because of the fail, nothing else to do */ - } while(0); - - TraceMsg(L"<--vboxNetFltWinNotifyShouldBind for INetCfgComponent, hr (0x%x)\n", hr); - - return hr; -} - - -static HRESULT vboxNetFltWinNotifyShouldBind(IN INetCfgBindingInterface *pIf, OUT bool *pbShouldBind) -{ - TraceMsg(L"-->vboxNetFltWinNotifyShouldBind for INetCfgBindingInterface\n"); - - INetCfgComponent * pAdapterComponent; - HRESULT hr = pIf->GetLowerComponent(&pAdapterComponent); - if(hr == S_OK) - { - hr = vboxNetFltWinNotifyShouldBind(pAdapterComponent, pbShouldBind); - - pAdapterComponent->Release(); - } - else - { - TraceMsg(L"vboxNetFltWinNotifyShouldBind: GetLowerComponent failed, hr (0x%x)\n", hr); - AssertBreakpoint(); - } - - TraceMsg(L"<--vboxNetFltWinNotifyShouldBind for INetCfgBindingInterface, hr (0x%x)\n", hr); - return hr; -} - -static HRESULT vboxNetFltWinNotifyShouldBind(IN INetCfgBindingPath *pPath, OUT bool * pbDoBind) -{ - TraceMsg(L"-->vboxNetFltWinNotifyShouldBind for INetCfgBindingPath\n"); - IEnumNetCfgBindingInterface *pEnumBindingIf; - HRESULT hr = pPath->EnumBindingInterfaces(&pEnumBindingIf); - - if(hr == S_OK) - { - hr = pEnumBindingIf->Reset(); - if(hr == S_OK) - { - ULONG ulCount; - INetCfgBindingInterface *pBindingIf; - - do - { - hr = pEnumBindingIf->Next( 1, - &pBindingIf, - &ulCount ); - if(hr == S_OK) - { - hr = vboxNetFltWinNotifyShouldBind(pBindingIf, pbDoBind); - - pBindingIf->Release(); - - if(hr == S_OK) - { - if(!(*pbDoBind)) - { - break; - } - } - else - { - /* break on failure */ - break; - } - } - else if(hr == S_FALSE) - { - /* no more elements */ - hr = S_OK; - break; - } - else - { - TraceMsg(L"vboxNetFltWinNotifyShouldBind: Next failed, hr (0x%x)\n", hr); - AssertBreakpoint(); - /* break on falure */ - break; - } - } while(true); - } - else - { - TraceMsg(L"vboxNetFltWinNotifyShouldBind: Reset failed, hr (0x%x)\n", hr); - AssertBreakpoint(); - } - - pEnumBindingIf->Release(); - } - else - { - TraceMsg(L"vboxNetFltWinNotifyShouldBind: EnumBindingInterfaces failed, hr (0x%x)\n", hr); - AssertBreakpoint(); - } - - TraceMsg(L"<--vboxNetFltWinNotifyShouldBind for INetCfgBindingPath, hr (0x%x)\n", hr); - return hr; -} - -static bool vboxNetFltWinNotifyShouldBind(IN INetCfgBindingPath *pPath) -{ -#ifdef VBOXNETFLTNOTIFY_DEBUG_BIND - return VBOXNETFLTNOTIFY_DEBUG_BIND; -#else - HRESULT hr; - bool bShouldBind; - - TraceMsg( L"-->vboxNetFltWinNotifyShouldBind\n"); - - hr = vboxNetFltWinNotifyShouldBind(pPath, &bShouldBind) ; - if(hr != S_OK) - { - TraceMsg( L"vboxNetFltWinNotifyShouldBind: vboxNetFltWinNotifyShouldBind failed, hr (0x%x)\n", hr ); - bShouldBind = VBOXNETFLTNOTIFY_ONFAIL_BINDDEFAULT; - } - - - TraceMsg( L"<--vboxNetFltWinNotifyShouldBind, bShouldBind (%d)\n", bShouldBind); - return bShouldBind; -#endif -} - -/* - * INetCfgComponentNotifyBinding - * The following functions provide the INetCfgComponentNotifyBinding interface. - */ - -/** - * This is specific to the component being installed. This will - * ask us if we want to bind to the Item being passed into - * this routine. We can disable the binding by returning - * NETCFG_S_DISABLE_QUERY - * - * @param dwChangeFlag Type of binding change - * @param pncbpItem Pointer to INetCfgBindingPath object - * @return S_OK on success, otherwise an error code. - */ -STDMETHODIMP VBoxNetFltNotify::QueryBindingPath (IN DWORD dwChangeFlag, - IN INetCfgBindingPath *pPath) -{ - HRESULT hr = S_OK; - TraceMsg( L"-->QueryBindingPath, flags (0x%x)\n", dwChangeFlag ); - - if(!vboxNetFltWinNotifyShouldBind(pPath)) - { - TraceMsg( L"QueryBindingPath: we are NOT supporting the current component\n"); - hr = NETCFG_S_DISABLE_QUERY; - } - else - { - TraceMsg( L"QueryBindingPath: we are supporting the current component\n"); - } - TraceMsg( L"<--QueryBindingPath, hr (0x%x)\n", hr); - return hr; -} - -/** - * bind to the component passed to us. - * @param dwChangeFlag Type of system change - * @param pncc Pointer to INetCfgComponent object - * @return S_OK on success, otherwise an error code - */ -STDMETHODIMP VBoxNetFltNotify::NotifyBindingPath (IN DWORD dwChangeFlag, - IN INetCfgBindingPath *pPath) -{ - HRESULT hr = S_OK; - - TraceMsg( L"-->NotifyBindingPath, flags (0x%x)\n", dwChangeFlag ); - /* NCN_ADD | NCN_ENABLE - * NCN_REMOVE | NCN_ENABLE - * NCN_ADD | NCN_DISABLE - * NCN_REMOVE | NCN_DISABLE - * */ - if ( (dwChangeFlag & NCN_ENABLE) && !(dwChangeFlag & NCN_REMOVE)) - { - if(!vboxNetFltWinNotifyShouldBind(pPath)) - { - TraceMsg( L"NotifyBindingPath: binding enabled for the component we are not supporting\n"); - AssertBreakpoint(); - hr = NETCFG_S_DISABLE_QUERY; - } - } - - TraceMsg( L"<--NotifyBindingPath, hr (0x%x)\n", hr); - - return hr; -} - -/* - * DLL Entry Point - */ -extern "C" -BOOL WINAPI DllMain (HINSTANCE hInstance, - DWORD dwReason, - LPVOID /*lpReserved*/) -{ - TraceMsg( L"-->DllMain.\n"); - - if (dwReason == DLL_PROCESS_ATTACH) { - - TraceMsg( L" Reason: Attach.\n"); - - _Module.Init(ObjectMap, hInstance); - - DisableThreadLibraryCalls(hInstance); - } - else if (dwReason == DLL_PROCESS_DETACH) { - - TraceMsg( L" Reason: Detach.\n"); - - _Module.Term(); - } - - TraceMsg( L"<--DllMain.\n"); - - return TRUE; -} - -/* - * Used to determine whether the DLL can be unloaded by OLE - */ -STDAPI DllCanUnloadNow(void) -{ - HRESULT hr; - - TraceMsg( L"-->DllCanUnloadNow.\n"); - - hr = (_Module.GetLockCount() == 0) ? S_OK : S_FALSE; - - TraceMsg( L"<--DllCanUnloadNow, hr (0x%x).\n", - hr ); - - return hr; -} - -/* - * Returns a class factory to create an object of the requested type - */ -STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) -{ - TraceMsg( L"DllGetClassObject.\n"); - - return _Module.GetClassObject(rclsid, riid, ppv); -} - - -/* - * DllRegisterServer - Adds entries to the system registry - */ -STDAPI DllRegisterServer(void) -{ - /* Registers object, typelib and all interfaces in typelib */ - - TraceMsg( L"DllRegisterServer.\n"); - - return _Module.RegisterServer(TRUE); -} - -/* - * DllUnregisterServer - Removes entries from the system registry - */ -STDAPI DllUnregisterServer(void) -{ - TraceMsg( L"DllUnregisterServer.\n"); - _Module.UnregisterServer(TRUE); - return S_OK; -} diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.def b/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.def deleted file mode 100644 index a45750ce7..000000000 --- a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY VBOXNETFLTNOTIFY -EXPORTS - DllCanUnloadNow PRIVATE - DllGetClassObject PRIVATE - DllRegisterServer PRIVATE - DllUnregisterServer PRIVATE diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.h b/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.h deleted file mode 100644 index ae772727c..000000000 --- a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (C) 2008 Oracle Corporation - * - * This file is part of VirtualBox Open Source Edition (OSE), as - * available from http://www.virtualbox.org. This file is free software; - * you can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) as published by the Free Software - * Foundation, in version 2 as it comes in the "COPYING" file of the - * VirtualBox OSE distribution. VirtualBox OSE is distributed in the - * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. - */ -/* - * Based in part on Microsoft DDK sample code for Sample Notify Object - *+--------------------------------------------------------------------------- - * - * Microsoft Windows - * Copyright (C) Microsoft Corporation, 1992-2001. - * - * Author: Alok Sinha - * - *---------------------------------------------------------------------------- - */ -#ifndef ___VboxNetFltNotify_h___ -#define ___VboxNetFltNotify_h___ - -#include <windows.h> -#include <atlbase.h> -extern CComModule _Module; // required by atlcom.h -#include <atlcom.h> -#include <VBoxNetFltNotifyn.h> -//#include <Netcfgx.h> - -#include "VBoxNetFltNotifyRc.h" - -#define VBOXNETFLTNOTIFY_ONFAIL_BINDDEFAULT false - -/* - * VboxNetFlt Notify Object used to control bindings - */ -class VBoxNetFltNotify : - - /* - * Must inherit from CComObjectRoot(Ex) for reference count - * management and default threading model. - */ - public CComObjectRoot, - - /* - * Define the default class factory and aggregation model. - */ - public CComCoClass<VBoxNetFltNotify, &CLSID_VBoxNetFltNotify>, - - /* - * Notify Object's interfaces. - */ - public INetCfgComponentControl, - public INetCfgComponentNotifyBinding -{ - - /* - * Public members. - */ - public: - - /* - * Constructor - */ - VBoxNetFltNotify(VOID); - - /* - * Destructors. - */ - ~VBoxNetFltNotify(VOID); - - /* - * Notify Object's interfaces. - */ - BEGIN_COM_MAP(VBoxNetFltNotify) - COM_INTERFACE_ENTRY(INetCfgComponentControl) -// COM_INTERFACE_ENTRY(INetCfgComponentSetup) -// COM_INTERFACE_ENTRY(INetCfgComponentPropertyUi) - COM_INTERFACE_ENTRY(INetCfgComponentNotifyBinding) -// COM_INTERFACE_ENTRY(INetCfgComponentNotifyGlobal) - END_COM_MAP() - - /* - * Uncomment the the line below if you don't want your object to - * support aggregation. The default is to support it - * - * DECLARE_NOT_AGGREGATABLE(CMuxNotify) - */ - - DECLARE_REGISTRY_RESOURCEID(IDR_REG_VBOXNETFLT_NOTIFY) - - /* - * INetCfgComponentControl - */ - STDMETHOD (Initialize) ( - IN INetCfgComponent *pIComp, - IN INetCfg *pINetCfg, - IN BOOL fInstalling); - - STDMETHOD (CancelChanges) (); - - STDMETHOD (ApplyRegistryChanges) (); - - STDMETHOD (ApplyPnpChanges) ( - IN INetCfgPnpReconfigCallback* pICallback); - - /* - * INetCfgNotifyBinding - */ - STDMETHOD (QueryBindingPath) ( - IN DWORD dwChangeFlag, - IN INetCfgBindingPath* pncbp); - - STDMETHOD (NotifyBindingPath) ( - IN DWORD dwChangeFlag, - IN INetCfgBindingPath* pncbp); - - /* - * Private members. - */ - private: - - /* - * Private member variables. - */ - INetCfgComponent *m_pncc; /* Our Protocol's Net Config component */ - INetCfg *m_pnc; -}; - -#endif diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotifyRc.h b/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotifyRc.h deleted file mode 100644 index 1703bbe6a..000000000 --- a/src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotifyRc.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef ___VboxNetFltNotifyRc_h___ -#define ___VboxNetFltNotifyRc_h___ - -#define IDR_REG_VBOXNETFLT_NOTIFY 40001 - -#endif diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/tools/Makefile.kup b/src/VBox/HostDrivers/VBoxNetFlt/win/tools/Makefile.kup new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/VBox/HostDrivers/VBoxNetFlt/win/tools/Makefile.kup diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/NetAdpInstall.cpp b/src/VBox/HostDrivers/VBoxNetFlt/win/tools/VBoxNetAdpInstall.cpp index 5c3783c3c..a836cf023 100644 --- a/src/VBox/HostDrivers/VBoxNetFlt/win/NetAdpInstall.cpp +++ b/src/VBox/HostDrivers/VBoxNetFlt/win/tools/VBoxNetAdpInstall.cpp @@ -1,4 +1,4 @@ -/* $Id: NetAdpInstall.cpp $ */ +/* $Id: VBoxNetAdpInstall.cpp 36184 2011-03-07 10:57:04Z vboxsync $ */ /** @file * NetAdpInstall - VBoxNetAdp installer command line tool */ @@ -15,17 +15,17 @@ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. */ -#include <vbox/WinNetConfig.h> +#include <VBox/VBoxNetCfg-win.h> #include <stdio.h> #define VBOX_NETADP_INF L".\\VBoxNetAdp.inf" -static VOID winNetCfgLogger (LPCWSTR szString) +static VOID winNetCfgLogger (LPCSTR szString) { - wprintf(L"%s", szString); + printf("%s", szString); } -static int InstallNetAdp() +static int VBoxNetAdpInstall() { int r = 1; VBoxNetCfgWinSetLogging(winNetCfgLogger); @@ -33,13 +33,9 @@ static int InstallNetAdp() HRESULT hr = CoInitialize(NULL); if(hr == S_OK) { -#ifndef DEBUG_misha +#if 0 //ndef DEBUG_misha printf("not implemented yet, please use device manager for Host-Only net interface installation.. sorry :( \n"); #else - /* this installs the Net Adp from the pre-installed driver package, - * it does NOT install the new driver package, so the installation might use old drivers - * or fail in case no NetAdp package is currently installed - * the code is here for debugging NetAdp installation only */ GUID guid; BSTR name, errMsg; printf("adding host-only interface..\n"); @@ -99,5 +95,5 @@ static int InstallNetAdp() int __cdecl main(int argc, char **argv) { - return InstallNetAdp(); + return VBoxNetAdpInstall(); } diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/NetAdpUninstall.cpp b/src/VBox/HostDrivers/VBoxNetFlt/win/tools/VBoxNetAdpUninstall.cpp index deb31779a..63e6772c0 100644 --- a/src/VBox/HostDrivers/VBoxNetFlt/win/NetAdpUninstall.cpp +++ b/src/VBox/HostDrivers/VBoxNetFlt/win/tools/VBoxNetAdpUninstall.cpp @@ -1,4 +1,4 @@ -/* $Id: NetAdpUninstall.cpp $ */ +/* $Id: VBoxNetAdpUninstall.cpp 36487 2011-04-01 08:21:30Z vboxsync $ */ /** @file * NetAdpUninstall - VBoxNetAdp uninstaller command line tool */ @@ -15,18 +15,19 @@ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. */ -#include <vbox/WinNetConfig.h> +#include <VBox/VBoxNetCfg-win.h> +#include <VBox/VBoxDrvCfg-win.h> #include <stdio.h> #include <devguid.h> -static VOID winNetCfgLogger (LPCWSTR szString) +static VOID winNetCfgLogger (LPCSTR szString) { - wprintf(L"%s", szString); + printf("%s", szString); } -static int UninstallNetAdp() +static int VBoxNetAdpUninstall() { int r = 1; VBoxNetCfgWinSetLogging(winNetCfgLogger); @@ -39,7 +40,7 @@ static int UninstallNetAdp() hr = VBoxNetCfgWinRemoveAllNetDevicesOfId(L"sun_VBoxNetAdp"); if(hr == S_OK) { - hr = VBoxNetCfgWinUninstallInfs (&GUID_DEVCLASS_NET, L"sun_VBoxNetAdp", 0/* could be SUOI_FORCEDELETE */); + hr = VBoxDrvCfgInfUninstallAllSetupDi(&GUID_DEVCLASS_NET, L"Net", L"sun_VBoxNetAdp", 0/* could be SUOI_FORCEDELETE */); if(hr == S_OK) { printf("uninstalled successfully\n"); @@ -69,5 +70,5 @@ static int UninstallNetAdp() int __cdecl main(int argc, char **argv) { - return UninstallNetAdp(); + return VBoxNetAdpUninstall(); } diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/NetFltInstall.cpp b/src/VBox/HostDrivers/VBoxNetFlt/win/tools/VBoxNetFltInstall.cpp index 44cebbb17..3ce13ab90 100644 --- a/src/VBox/HostDrivers/VBoxNetFlt/win/NetFltInstall.cpp +++ b/src/VBox/HostDrivers/VBoxNetFlt/win/tools/VBoxNetFltInstall.cpp @@ -1,4 +1,4 @@ -/* $Id: NetFltInstall.cpp $ */ +/* $Id: VBoxNetFltInstall.cpp 36184 2011-03-07 10:57:04Z vboxsync $ */ /** @file * NetFltInstall - VBoxNetFlt installer command line tool */ @@ -15,20 +15,20 @@ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. */ -#include <vbox/WinNetConfig.h> +#include <VBox/VBoxNetCfg-win.h> #include <devguid.h> #include <stdio.h> -#define NETFLT_ID L"sun_VBoxNetFlt" +#define NETFLT_ID L"sun_VBoxNetFlt" #define VBOX_NETCFG_APP_NAME L"NetFltInstall" #define VBOX_NETFLT_PT_INF L".\\VBoxNetFlt.inf" -#define VBOX_NETFLT_MP_INF L".\\VBoxNetFlt_m.inf" +#define VBOX_NETFLT_MP_INF L".\\VBoxNetFltM.inf" #define VBOX_NETFLT_RETRIES 10 -static VOID winNetCfgLogger (LPCWSTR szString) +static VOID winNetCfgLogger (LPCSTR szString) { - wprintf(L"%s", szString); + printf("%s", szString); } /** Wrapper around GetfullPathNameW that will try an alternative INF location. @@ -40,7 +40,7 @@ static VOID winNetCfgLogger (LPCWSTR szString) static DWORD MyGetfullPathNameW(LPCWSTR pwszName, size_t cchFull, LPWSTR pwszFull) { LPWSTR pwszFilePart; - DWORD dwSize = GetFullPathNameW(pwszName, cchFull, pwszFull, &pwszFilePart); + DWORD dwSize = GetFullPathNameW(pwszName, (DWORD)cchFull, pwszFull, &pwszFilePart); if(dwSize <= 0) return dwSize; @@ -59,9 +59,8 @@ static DWORD MyGetfullPathNameW(LPCWSTR pwszName, size_t cchFull, LPWSTR pwszFul wsz[cch] = pwszFilePart[i++]; if(!wsz[cch]) { - dwSize = GetFullPathNameW(wsz, cchFull, pwszFull, NULL); - if( dwSize > 0 - && GetFileAttributesW(pwszFull) != INVALID_FILE_ATTRIBUTES) + dwSize = GetFullPathNameW(wsz, (DWORD)cchFull, pwszFull, NULL); + if(dwSize > 0 && GetFileAttributesW(pwszFull) != INVALID_FILE_ATTRIBUTES) return dwSize; break; } @@ -71,10 +70,10 @@ static DWORD MyGetfullPathNameW(LPCWSTR pwszName, size_t cchFull, LPWSTR pwszFul } /* fallback */ - return GetFullPathNameW(pwszName, cchFull, pwszFull, NULL); + return GetFullPathNameW(pwszName, (DWORD)cchFull, pwszFull, NULL); } -static int InstallNetFlt() +static int VBoxNetFltInstall() { WCHAR PtInf[MAX_PATH]; WCHAR MpInf[MAX_PATH]; @@ -90,7 +89,7 @@ static int InstallNetFlt() int i = 0; do { - hr = VBoxNetCfgWinQueryINetCfg(TRUE, VBOX_NETCFG_APP_NAME, &pnc, &lpszLockedBy); + hr = VBoxNetCfgWinQueryINetCfg(&pnc, TRUE, VBOX_NETCFG_APP_NAME, 10000, &lpszLockedBy); if(hr == S_OK) { DWORD dwSize; @@ -118,13 +117,13 @@ static int InstallNetFlt() } else { - hr = HRESULT_FROM_WIN32(GetLastError()); - wprintf(L"error getting full inf path for VBoxNetFlt_m.inf (0x%x)\n", hr); + hr = HRESULT_FROM_WIN32(GetLastError()); + wprintf(L"error getting full inf path for VBoxNetFltM.inf (0x%x)\n", hr); } } else { - hr = HRESULT_FROM_WIN32(GetLastError()); + hr = HRESULT_FROM_WIN32(GetLastError()); wprintf(L"error getting full inf path for VBoxNetFlt.inf (0x%x)\n", hr); } @@ -170,5 +169,5 @@ static int InstallNetFlt() int __cdecl main(int argc, char **argv) { - return InstallNetFlt(); + return VBoxNetFltInstall(); } diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/NetFltUninstall.cpp b/src/VBox/HostDrivers/VBoxNetFlt/win/tools/VBoxNetFltUninstall.cpp index 03dfa66ae..710db34ab 100644 --- a/src/VBox/HostDrivers/VBoxNetFlt/win/NetFltUninstall.cpp +++ b/src/VBox/HostDrivers/VBoxNetFlt/win/tools/VBoxNetFltUninstall.cpp @@ -1,4 +1,4 @@ -/* $Id: NetFltUninstall.cpp $ */ +/* $Id: VBoxNetFltUninstall.cpp 36184 2011-03-07 10:57:04Z vboxsync $ */ /** @file * NetFltUninstall - VBoxNetFlt uninstaller command line tool */ @@ -15,21 +15,21 @@ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. */ -#include <vbox/WinNetConfig.h> +#include <VBox/VBoxNetCfg-win.h> #include <stdio.h> -#define NETFLT_ID L"sun_VBoxNetFlt" +#define NETFLT_ID L"sun_VBoxNetFlt" #define VBOX_NETCFG_APP_NAME L"NetFltUninstall" #define VBOX_NETFLT_PT_INF L".\\VBoxNetFlt.inf" -#define VBOX_NETFLT_MP_INF L".\\VBoxNetFlt_m.inf" +#define VBOX_NETFLT_MP_INF L".\\VBoxNetFltM.inf" #define VBOX_NETFLT_RETRIES 10 -static VOID winNetCfgLogger (LPCWSTR szString) +static VOID winNetCfgLogger (LPCSTR szString) { - wprintf(L"%s", szString); + printf("%s", szString); } -static int UninstallNetFlt() +static int VBoxNetFltUninstall() { INetCfg *pnc; LPWSTR lpszLockedBy = NULL; @@ -43,7 +43,7 @@ static int UninstallNetFlt() int i = 0; do { - hr = VBoxNetCfgWinQueryINetCfg(TRUE, VBOX_NETCFG_APP_NAME, &pnc, &lpszLockedBy); + hr = VBoxNetCfgWinQueryINetCfg(&pnc, TRUE, VBOX_NETCFG_APP_NAME, 10000, &lpszLockedBy); if(hr == S_OK) { hr = VBoxNetCfgWinNetFltUninstall(pnc); @@ -99,5 +99,5 @@ static int UninstallNetFlt() int __cdecl main(int argc, char **argv) { - return UninstallNetFlt(); + return VBoxNetFltUninstall(); } |