summaryrefslogtreecommitdiff
path: root/src/VBox/HostDrivers/VBoxNetFlt
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/HostDrivers/VBoxNetFlt')
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/Makefile.kmk152
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFlt.c2
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h8
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/darwin/VBoxNetFlt-darwin.cpp2
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/freebsd/Makefile2
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/freebsd/VBoxNetFlt-freebsd.c40
-rw-r--r--[-rwxr-xr-x]src/VBox/HostDrivers/VBoxNetFlt/freebsd/files_vboxnetflt2
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c21
-rw-r--r--[-rwxr-xr-x]src/VBox/HostDrivers/VBoxNetFlt/linux/files_vboxnetflt2
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFlt-solaris.c147
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFltBow-solaris.c47
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_client.h199
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_client_priv.h156
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/solaris/include/mac_provider.h498
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/solaris/vboxbow.conf21
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltCommon-win.h501
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltMp-win.c2807
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltMp-win.h46
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltPt-win.c2512
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFltPt-win.h43
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/WinNetConfig.cpp4368
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/cfg/Makefile.kup (renamed from src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/Makefile.kup)0
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/cfg/VBoxNetCfg.cpp2771
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/drv/Makefile.kup0
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetAdp.inf (renamed from src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetAdp.inf)22
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFlt-win.rc (renamed from src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.rc)5
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFlt.inf (renamed from src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt.inf)75
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltCmn-win.h544
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltM-win.cpp1552
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltM-win.h42
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltM.inf (renamed from src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt_m.inf)31
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltP-win.cpp1580
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltP-win.h29
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltRt-win.cpp (renamed from src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.c)1954
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltRt-win.h (renamed from src/VBox/HostDrivers/VBoxNetFlt/win/VBoxNetFlt-win.h)477
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/nobj/Makefile.kup0
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.cpp585
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.def22
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.h73
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.rc (renamed from src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.rc)30
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.rgs (renamed from src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.rgs)2
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobjRc.h23
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobjT.idl (renamed from src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotifyn.idl)29
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.cpp769
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.def6
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotify.h133
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/notifyobj/VBoxNetFltNotifyRc.h6
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/tools/Makefile.kup0
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/tools/VBoxNetAdpInstall.cpp (renamed from src/VBox/HostDrivers/VBoxNetFlt/win/NetAdpInstall.cpp)18
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/tools/VBoxNetAdpUninstall.cpp (renamed from src/VBox/HostDrivers/VBoxNetFlt/win/NetAdpUninstall.cpp)15
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/tools/VBoxNetFltInstall.cpp (renamed from src/VBox/HostDrivers/VBoxNetFlt/win/NetFltInstall.cpp)33
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/win/tools/VBoxNetFltUninstall.cpp (renamed from src/VBox/HostDrivers/VBoxNetFlt/win/NetFltUninstall.cpp)18
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, &param.ParameterData.StringData);
- Assert(RT_SUCCESS(rc));
- if(RT_SUCCESS(rc))
- {
- NdisWriteConfiguration(&Status,
- hConfiguration,
- &strMAC,
- &param);
- 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, &param.ParameterData.StringData);
+ Assert(RT_SUCCESS(rc));
+ if (RT_SUCCESS(rc))
+ {
+ NdisWriteConfiguration(&Status,
+ hConfiguration,
+ &strMAC,
+ &param);
+ 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();
}