summaryrefslogtreecommitdiff
path: root/libre/virtualbox-libre-modules-lts/libre.patch
diff options
context:
space:
mode:
Diffstat (limited to 'libre/virtualbox-libre-modules-lts/libre.patch')
-rw-r--r--libre/virtualbox-libre-modules-lts/libre.patch5765
1 files changed, 5765 insertions, 0 deletions
diff --git a/libre/virtualbox-libre-modules-lts/libre.patch b/libre/virtualbox-libre-modules-lts/libre.patch
new file mode 100644
index 000000000..e51d0c0a7
--- /dev/null
+++ b/libre/virtualbox-libre-modules-lts/libre.patch
@@ -0,0 +1,5765 @@
+--- VirtualBox-4.1.18.orig/Config.kmk 2012-07-24 16:38:43.981310996 -0300
++++ VirtualBox-4.1.18/Config.kmk 2012-07-24 16:38:44.001309865 -0300
+@@ -56,9 +56,6 @@
+ PROPS_SYSMODS_ACCUMULATE_L += INTERMEDIATES
+ PROPS_MISCBINS_ACCUMULATE_L += INTERMEDIATES
+
+-# Misc names used bye the install paths below.
+-VBOX_PUEL_MANGLED_NAME := Oracle_VM_VirtualBox_Extension_Pack
+-
+ # Install paths
+ ## @todo This will change after 4.1 is branched off!
+ # What is now 'bin' and 'lib' will be moved down under 'staged/', except on
+@@ -125,9 +122,6 @@
+ endif
+
+ INST_DOC = doc/
+-INST_EXTPACK = $(INST_BIN)ExtensionPacks/
+-INST_EXTPACK_CERTS = $(INST_BIN)ExtPackCertificates/
+-INST_EXTPACK_PUEL = $(INST_EXTPACK)$(VBOX_PUEL_MANGLED_NAME)/
+ INST_PACKAGES = packages/
+
+ VBOX_PATH_SDK = $(patsubst %/,%,$(PATH_STAGE)/$(INST_SDK))
+@@ -136,7 +130,6 @@
+ VBOX_PATH_ADDITIONS = $(patsubst %/,%,$(PATH_STAGE)/$(INST_ADDITIONS))
+ VBOX_PATH_ADDITIONS_ISO = $(patsubst %/,%,$(PATH_STAGE)/$(INST_ADDITIONS_ISO))
+ VBOX_PATH_ADDITIONS_LIB = $(patsubst %/,%,$(PATH_STAGE)/$(INST_ADDITIONS_LIB))
+-VBOX_PATH_EXTPACK_PUEL= $(patsubst %/,%,$(PATH_STAGE)/$(INST_EXTPACK_PUEL))
+ VBOX_PATH_PACKAGES = $(patsubst %/,%,$(PATH_STAGE)/$(INST_PACKAGES))
+
+
+@@ -208,7 +201,6 @@
+ export VBOX_ADDITIONS_SH_MODE = release
+ export VBOX_DOCUMENTATION_SH_MODE = release
+ export VBOX_EFI_SH_MODE = release
+- export VBOX_EXTPACKS_SH_MODE = release
+ endif
+
+ # Some info on the vendor
+@@ -361,8 +353,6 @@
+ VBOX_WITH_USB = 1
+ # Enable the USB 1.1 controller plus virtual USB HID devices.
+ VBOX_WITH_VUSB = 1
+-# Enable the USB 2.0 controller.
+-VBOX_WITH_EHCI = 1
+ # Enable the ISCSI feature.
+ VBOX_WITH_ISCSI = 1
+ # Enable INIP support in the ISCSI feature.
+@@ -430,9 +420,6 @@
+ ifdef VBOX_WITH_USB
+ VBOX_WITH_VUSB = 1
+ endif
+-ifdef VBOX_WITH_EHCI
+- VBOX_WITH_EHCI_IMPL = 1
+-endif
+ ifdef VBOX_WITH_PCI_PASSTHROUGH
+ VBOX_WITH_PCI_PASSTHROUGH_IMPL = 1
+ endif
+@@ -591,15 +578,6 @@
+ ## @}
+
+
+-## @name Extension pack
+-## @{
+-# Enables the extension pack feature.
+-VBOX_WITH_EXTPACK = 1
+-# Enables separating code into the Oracle VM VirtualBox Extension Pack, dubbed PUEL.
+-VBOX_WITH_EXTPACK_PUEL = 1
+-# Enables building+packing the Oracle VM VirtualBox Extension Pack, includes VBOX_WITH_EXTPACK_PUEL
+-VBOX_WITH_EXTPACK_PUEL_BUILD = 1
+-## @}
+
+ ## @name Misc
+ ## @{
+@@ -777,14 +755,6 @@
+ # Skip stuff.
+ #
+
+-ifdef VBOX_ONLY_EXTPACKS
+- # Clear some VBOX_WITH_XXX variables instead of adding ifdefs all over the place.
+- VBOX_WITH_DEBUGGER =
+- VBOX_WITH_ADDITIONS =
+- VBOX_WITH_VBOXDRV =
+- VBOX_WITH_TESTCASES =
+-endif
+-
+ # VBOX_QUICK can be used by core developers to speed to the build
+ ifdef VBOX_QUICK
+ # undefine variables by assigning blank.
+@@ -848,7 +818,6 @@
+ VBOX_WITH_TESTSUITE=
+ VBOX_WITH_QTGUI=
+ VBOX_WITH_USB=
+- VBOX_WITH_EHCI=
+ VBOX_WITH_DOCS=
+ VBOX_WITH_PDM_ASYNC_COMPLETION=
+ VBOX_WITH_KCHMVIEWER=
+@@ -870,7 +839,6 @@
+ VBOX_WITH_CROGL=
+ VBOX_WITH_DEBUGGER=
+ VBOX_WITH_DOCS=
+- VBOX_WITH_EHCI=
+ VBOX_WITH_HARDENING=
+ VBOX_WITH_HEADLESS=
+ VBOX_WITH_HGCM=
+@@ -952,9 +920,6 @@
+ #
+ ifdef VBOX_OSE
+ VBOX_WITH_VRDP=
+- VBOX_WITH_EHCI_IMPL=
+- VBOX_WITH_EXTPACK_PUEL=
+- VBOX_WITH_EXTPACK_PUEL_BUILD=
+ VBOX_WITH_PCI_PASSTHROUGH_IMPL=
+ VBOX_WITH_OS2_ADDITIONS_BIN=
+ VBOX_WITH_SECURELABEL=
+@@ -1082,10 +1047,6 @@
+ VBOX_WITH_KCHMVIEWER=
+ endif
+
+-ifdef VBOX_WITH_EXTPACK_PUEL_BUILD
+- VBOX_WITH_EXTPACK_PUEL = 1
+-endif
+-
+ #
+ # Mark OSE builds clearly, helps figuring out limitations more easily.
+ #
+@@ -1679,9 +1640,6 @@
+ # biossums (set BIOS checksums)
+ VBOX_BIOSSUMS ?= $(PATH_OBJ)/biossums/biossums$(HOSTSUFF_EXE)
+
+-# RTManifest (extension pack manifest utility)
+-VBOX_RTMANIFEST ?= $(PATH_OBJ)/bldRTManifest/bldRTManifest$(HOSTSUFF_EXE)
+-
+ # filesplitter (splits java files)
+ VBOX_FILESPLIT ?= $(PATH_OBJ)/filesplitter/filesplitter$(HOSTSUFF_EXE)
+
+@@ -2461,13 +2419,6 @@
+ SDK_VBOX_OPENSSL2_LIBS = $(NO_SUCH_VARIABLE)
+ endif
+
+-SDK_VBoxOpenSslExtPack = Internal use only.
+-SDK_VBoxOpenSslExtPack_INCS = $(SDK_VBOX_OPENSSL_VBOX_DEFAULT_INCS)
+-SDK_VBoxOpenSslExtPack_ORDERDEPS = $(crypto-headers_1_TARGET)
+-SDK_VBoxOpenSslExtPack_LIBS = \
+- $(PATH_STAGE_LIB)/VBoxExtPack-libssl$(VBOX_SUFF_LIB) \
+- $(PATH_STAGE_LIB)/VBoxExtPack-libcrypto$(VBOX_SUFF_LIB)
+-
+ SDK_VBOX_BLD_OPENSSL = .
+ SDK_VBOX_BLD_OPENSSL_EXTENDS = VBOX_OPENSSL
+ SDK_VBOX_BLD_OPENSSL_LIBS ?= \
+@@ -3817,100 +3768,6 @@
+ endif
+ TEMPLATE_VBOXMAINCLIENTDLL_LDFLAGS.darwin = $(filter-out -bind_at_load,$(TEMPLATE_VBOXMAINCLIENTEXE_LDFLAGS.darwin))
+
+-
+-
+-#
+-# Templates used for building the extension packs.
+-#
+-ifdef VBOX_WITH_EXTPACK
+- # Base templates (native or portable).
+- TEMPLATE_VBoxR3ExtPack = For the ring-3 context extension pack modules.
+- if 1 # Native for now.
+- TEMPLATE_VBoxR3ExtPack_EXTENDS = VBOXR3DLLNOXCPT
+- TEMPLATE_VBoxR3ExtPack_DEFS = $(TEMPLATE_VBOXR3DLLNOXCPT_DEFS) VBOX_IN_EXTPACK VBOX_IN_EXTPACK_R3
+- else
+- TEMPLATE_VBoxR3ExtPack_EXTENDS = VBOXNOCRTGCC
+- TEMPLATE_VBoxR3ExtPack_DEFS = $(TEMPLATE_VBOXNOCRTGCC_DEFS) VBOX_IN_EXTPACK VBOX_IN_EXTPACK_R3 IPRT_NO_CRT IN_RING3
+- TEMPLATE_VBoxR3ExtPack_INCS = $(PATH_ROOT)/include/iprt/nocrt $(TEMPLATE_VBOXR3DLLNOXCPT_INCS)
+- endif
+- ifneq ($(KBUILD_TARGET),win)
+- TEMPLATE_VBoxR3ExtPack_CXXFLAGS = $(TEMPLATE_VBOXR3DLLNOXCPT_CXXFLAGS) -fno-rtti
+- endif
+- TEMPLATE_VBoxR3ExtPack_INST = $(INST_EXTPACK)YouShallOverrideThis/
+- ifeq ($(KBUILD_TARGET),linux)
+- TEMPLATE_VBoxR3ExtPack_LDFLAGS = $(filter-out '$(VBOX_GCC_RPATH_OPT)$(VBOX_WITH_RUNPATH)' '$(VBOX_GCC_RPATH_OPT)$(VBOX_WITH_RELATIVE_RUNPATH)', $(TEMPLATE_VBOXR3DLLNOXCPT_LDFLAGS))
+- else
+- if !defined(VBOX_WITH_RUNPATH) && defined(VBOX_WITH_RELATIVE_RUNPATH)
+- TEMPLATE_VBoxR3ExtPack_LDFLAGS = '$(VBOX_GCC_RPATH_OPT)$(VBOX_WITH_RELATIVE_RUNPATH)/../../..' $(filter-out '$(VBOX_GCC_RPATH_OPT)$(VBOX_WITH_RELATIVE_RUNPATH)', $(TEMPLATE_VBOXR3DLLNOXCPT_LDFLAGS))
+- endif
+- endif
+- ifdef VBOX_ONLY_EXTPACKS_USE_IMPLIBS
+- if1of ($(KBUILD_TARGET), win os2)
+- TEMPLATE_VBoxR3ExtPack_LIBS = \
+- $(TEMPLATE_LIBS_VBOXR3) \
+- $(PATH_STAGE_LIB)/VMMR3Imp$(VBOX_SUFF_LIB) \
+- $(PATH_STAGE_LIB)/VBoxRTImp$(VBOX_SUFF_LIB)
+- else
+- TEMPLATE_VBoxR3ExtPack_LIBS = \
+- $(TEMPLATE_LIBS_VBOXR3) \
+- $(PATH_STAGE_LIB)/VMMR3Imp$(VBOX_SUFF_DLL) \
+- $(PATH_STAGE_LIB)/VBoxRTImp$(VBOX_SUFF_DLL)
+- endif
+- else
+- TEMPLATE_VBoxR3ExtPack_LIBS = \
+- $(TEMPLATE_LIBS_VBOXR3) \
+- $(LIB_RUNTIME) \
+- $(LIB_VMM)
+- endif
+-
+- TEMPLATE_VBoxR0ExtPack = For the ring-0 context extension pack modules.
+- TEMPLATE_VBoxR0ExtPack_EXTENDS = VBoxR0
+- TEMPLATE_VBoxR0ExtPack_EXTENDS_BY = appending
+- TEMPLATE_VBoxR0ExtPack_INST = $(INST_EXTPACK)YouShallOverrideThis/
+- TEMPLATE_VBoxR0ExtPack_DEFS = VBOX_IN_EXTPACK VBOX_IN_EXTPACK_R0
+- if1of ($(VBOX_LDR_FMT), pe lx)
+- TEMPLATE_VBoxR0ExtPack_LIBS = \
+- $(PATH_STAGE_LIB)/VMMR0Imp$(VBOX_SUFF_LIB) \
+- $(PATH_STAGE_LIB)/SUPR0$(VBOX_SUFF_LIB)
+- endif
+-
+- TEMPLATE_VBoxRcExtPack = For the raw-mode context extension pack modules.
+- TEMPLATE_VBoxRcExtPack_EXTENDS = VBoxRc
+- TEMPLATE_VBoxRcExtPack_EXTENDS_BY = appending
+- TEMPLATE_VBoxRcExtPack_SYSSUFF = .rc
+- TEMPLATE_VBoxRcExtPack_INST = $(INST_EXTPACK)YouShallOverrideThis/
+- TEMPLATE_VBoxRcExtPack_DEFS = VBOX_IN_EXTPACK VBOX_IN_EXTPACK_RC
+- if1of ($(VBOX_LDR_FMT32), pe lx)
+- TEMPLATE_VBoxRcExtPack_LIBS = \
+- $(PATH_STAGE_LIB)/VMMRCBuiltin$(VBOX_SUFF_LIB) \
+- $(PATH_STAGE_LIB)/VMMRCImp$(VBOX_SUFF_LIB)
+- endif
+-
+- TEMPLATE_VBoxInsExtPack = For the install targets of an extension pack.
+- TEMPLATE_VBoxInsExtPack_MODE = 0644
+- TEMPLATE_VBoxInsExtPack_INST = $(INST_EXTPACK)YouShallOverrideThis/
+-
+- # For each individual extension pack
+- ifdef VBOX_WITH_EXTPACK_PUEL
+- TEMPLATE_VBoxR3ExtPackPuel = For the ring-3 context modules in the PUEL extension pack.
+- TEMPLATE_VBoxR3ExtPackPuel_EXTENDS = VBoxR3ExtPack
+- TEMPLATE_VBoxR3ExtPackPuel_INST = $(INST_EXTPACK_PUEL)$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)/
+-
+- TEMPLATE_VBoxR0ExtPackPuel = For the ring-0 context modules in the PUEL extension pack.
+- TEMPLATE_VBoxR0ExtPackPuel_EXTENDS = VBoxR0ExtPack
+- TEMPLATE_VBoxR0ExtPackPuel_INST = $(INST_EXTPACK_PUEL)$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)/
+-
+- TEMPLATE_VBoxRcExtPackPuel = For the raw-mode context modules in the PUEL extension pack.
+- TEMPLATE_VBoxRcExtPackPuel_EXTENDS = VBoxRcExtPack
+- TEMPLATE_VBoxRcExtPackPuel_INST = $(INST_EXTPACK_PUEL)$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)/
+-
+- TEMPLATE_VBoxInsExtPackPuel = For the install targets of an extension pack.
+- TEMPLATE_VBoxInsExtPackPuel_EXTENDS = VBoxR0ExtPack
+- TEMPLATE_VBoxInsExtPackPuel_INST = $(INST_EXTPACK_PUEL)
+-endif
+-endif # VBOX_WITH_EXTPACK
+-
+-
+ #
+ # Qt 4
+ # Qt 4
+--- VirtualBox-4.1.18.orig/Makefile.kmk 2012-07-24 17:16:47.078929150 -0300
++++ VirtualBox-4.1.18/Makefile.kmk 2012-07-24 17:16:47.125592981 -0300
+@@ -446,7 +446,6 @@
+ include/VBox \
+ include/VBox/vmm \
+ include/VBox/com \
+- include/VBox/ExtPack \
+ include/VBox/HostServices \
+ include/VBox/GuestHost \
+ include/VBox/HGSMI \
+@@ -862,191 +861,6 @@
+ additions-build-linux.x86.combined \
+ additions-packing
+
+-
+-#
+-# Build the extension packs, all of them.
+-#
+-# This is tailored (hardcoded) for the extension pack build box.
+-#
+-# The fetching must be done in serial fashion, while the building should be
+-# more flexible wrt to -jN.
+-#
+-extpacks-fetch:
+- + $(KMK) -C tools fetch VBOX_ONLY_EXTPACKS=1
+- + $(KMK) -C tools fetch KBUILD_TARGET_ARCH=amd64 KBUILD_TARGET=darwin BUILD_TARGET_ARCH=amd64 BUILD_TARGET=darwin VBOX_ONLY_EXTPACKS=1
+- + $(KMK) -C tools fetch KBUILD_TARGET_ARCH=x86 KBUILD_TARGET=darwin BUILD_TARGET_ARCH=x86 BUILD_TARGET=darwin VBOX_ONLY_EXTPACKS=1
+-# + $(KMK) -C tools fetch KBUILD_TARGET_ARCH=amd64 KBUILD_TARGET=freebsd BUILD_TARGET_ARCH=amd64 BUILD_TARGET=freebsd VBOX_ONLY_EXTPACKS=1
+-# + $(KMK) -C tools fetch KBUILD_TARGET_ARCH=x86 KBUILD_TARGET=freebsd BUILD_TARGET_ARCH=x86 BUILD_TARGET=freebsd VBOX_ONLY_EXTPACKS=1
+- + $(KMK) -C tools fetch KBUILD_TARGET_ARCH=amd64 KBUILD_TARGET=linux BUILD_TARGET_ARCH=amd64 BUILD_TARGET=linux VBOX_ONLY_EXTPACKS=1
+- + $(KMK) -C tools fetch KBUILD_TARGET_ARCH=x86 KBUILD_TARGET=linux BUILD_TARGET_ARCH=x86 BUILD_TARGET=linux VBOX_ONLY_EXTPACKS=1
+-# + $(KMK) -C tools fetch KBUILD_TARGET_ARCH=x86 KBUILD_TARGET=os2 BUILD_TARGET_ARCH=x86 BUILD_TARGET=os2 VBOX_ONLY_EXTPACKS=1
+- + $(KMK) -C tools fetch KBUILD_TARGET_ARCH=amd64 KBUILD_TARGET=solaris BUILD_TARGET_ARCH=amd64 BUILD_TARGET=solaris VBOX_ONLY_EXTPACKS=1
+- + $(KMK) -C tools fetch KBUILD_TARGET_ARCH=x86 KBUILD_TARGET=solaris BUILD_TARGET_ARCH=x86 BUILD_TARGET=solaris VBOX_ONLY_EXTPACKS=1
+- + $(KMK) -C tools fetch KBUILD_TARGET_ARCH=amd64 KBUILD_TARGET=win BUILD_TARGET_ARCH=amd64 BUILD_TARGET=win VBOX_ONLY_EXTPACKS=1
+- + $(KMK) -C tools fetch KBUILD_TARGET_ARCH=x86 KBUILD_TARGET=win BUILD_TARGET_ARCH=x86 BUILD_TARGET=win VBOX_ONLY_EXTPACKS=1
+-
+-
+-extpacks-build: \
+- extpacks-build-win.amd64 \
+- extpacks-build-win.x86 \
+- extpacks-build-solaris.amd64 \
+- extpacks-build-solaris.x86 \
+- extpacks-build-os2.x86 \
+- extpacks-build-linux.amd64 \
+- extpacks-build-linux.x86 \
+- extpacks-build-darwin.amd64 \
+- extpacks-build-darwin.x86 \
+- extpacks-build-freebsd.amd64 \
+- extpacks-build-freebsd.x86
+-
+-VBOX_EXTPACKS_BUILD.amd64 = VBOX_ONLY_EXTPACKS=1 \
+- KBUILD_TYPE=$(KBUILD_TYPE) BUILD_TYPE=$(KBUILD_TYPE) \
+- KBUILD_TARGET_ARCH=amd64 BUILD_TARGET_ARCH=amd64 \
+- VBOX_SVN_REV=$(VBOX_SVN_REV)
+-
+-VBOX_EXTPACKS_BUILD.x86 = VBOX_ONLY_EXTPACKS=1 \
+- KBUILD_TYPE=$(KBUILD_TYPE) BUILD_TYPE=$(KBUILD_TYPE) \
+- KBUILD_TARGET_ARCH=x86 BUILD_TARGET_ARCH=x86 \
+- VBOX_SVN_REV=$(VBOX_SVN_REV)
+-
+-# Automatically determine the extpack build subdir name. Used for figuring out
+-# directory names inside the extension pack building VMs.
+-VBOX_EXTPACKS_BUILD_SUBDIRNAME := $(lastword $(subst /, ,$(PATH_ROOT)))
+-
+-# When building in parallel on a Windows host, make sure we finish the host
+-# bit before kicking off any UNIX guest or we'll run into file sharing issues.
+-ifeq ($(KBUILD_TARGET),win)
+-VBOX_EXTPACKS_BUILD_WIN_HOST_FIRST = extpacks-build-win.x86 extpacks-build-win.amd64
+-else
+-VBOX_EXTPACKS_BUILD_WIN_HOST_FIRST =
+-endif
+-
+-extpacks-build-win.amd64:
+-ifeq ($(KBUILD_TARGET),win)
+- + $(VBOX_KMK_TIME) $(KMK) $(VBOX_EXTPACKS_BUILD.amd64) all $(VBOX_EXTPACKS_HOST_BUILD_TWEAK)
+-else
+- $(call MSG_L1,Building Windows/amd64 extension packs)
+- $(VBOX_KMK_TIME) ssh vbox@192.168.27.6 " echo $@ && cd e:/$(VBOX_EXTPACKS_BUILD_SUBDIRNAME) && tools/env.sh kmk $(VBOX_EXTPACKS_BUILD.amd64) all"
+-endif
+-
+-extpacks-build-win.x86:
+-ifeq ($(KBUILD_TARGET),win)
+- + $(VBOX_KMK_TIME) $(KMK) $(VBOX_EXTPACKS_BUILD.x86) all $(VBOX_EXTPACKS_HOST_BUILD_TWEAK)
+-else
+- $(call MSG_L1,Building Windows/x86 extension packs)
+- $(VBOX_KMK_TIME) ssh vbox@192.168.27.16 " echo $@ && cd e:/$(VBOX_EXTPACKS_BUILD_SUBDIRNAME) && tools/env.sh kmk $(VBOX_EXTPACKS_BUILD.x86) all"
+-endif
+-
+-ifeq ($(KBUILD_TARGET),solaris)
+-extpacks-build-solaris.amd64:
+- + $(VBOX_KMK_TIME) $(KMK) $(VBOX_EXTPACKS_BUILD.amd64) all $(VBOX_EXTPACKS_HOST_BUILD_TWEAK)
+-
+-extpacks-build-solaris.x86: extpacks-build-solaris.amd64
+- + $(VBOX_KMK_TIME) $(KMK) $(VBOX_EXTPACKS_BUILD.x86) VBOX_WITH_COMBINED_SOLARIS_GUEST_PACKAGE=1 all $(VBOX_EXTPACKS_HOST_BUILD_TWEAK)
+-
+-else
+-# Serialize 32-bit and 64-bit ASSUMING the same VM builds both.
+-extpacks-build-solaris.rsync-into-vm: $(VBOX_EXTPACKS_BUILD_WIN_HOST_FIRST)
+- $(VBOX_KMK_TIME) $(call VBOX_RSYNC_IN_FN,solaris,*) . 192.168.27.4:/mnt/tinderbox/$(VBOX_EXTPACKS_BUILD_SUBDIRNAME)
+-
+-extpacks-build-solaris.build-it: extpacks-build-solaris.rsync-into-vm
+- $(call MSG_L1,Building Solaris/amd64 extension packs)
+- $(VBOX_KMK_TIME) ssh vbox@192.168.27.4 " echo $@/amd64 && cd /mnt/tinderbox/$(VBOX_EXTPACKS_BUILD_SUBDIRNAME) && tools/env.sh --no-wine kmk $(VBOX_EXTPACKS_BUILD.amd64) all"
+- $(call MSG_L1,Building Solaris/x86 extension packs)
+- $(VBOX_KMK_TIME) ssh vbox@192.168.27.4 " echo $@/x86 && cd /mnt/tinderbox/$(VBOX_EXTPACKS_BUILD_SUBDIRNAME) && tools/env.sh --no-wine kmk $(VBOX_EXTPACKS_BUILD.x86) all"
+-
+-extpacks-build-solaris.rsync-out-of-vm: extpacks-build-solaris.build-it
+- $(VBOX_KMK_TIME) rsync -a --delete 192.168.27.4:/mnt/tinderbox/$(VBOX_EXTPACKS_BUILD_SUBDIRNAME)/out/solaris.x86 out/
+- $(VBOX_KMK_TIME) rsync -a --delete 192.168.27.4:/mnt/tinderbox/$(VBOX_EXTPACKS_BUILD_SUBDIRNAME)/out/solaris.amd64 out/
+-
+-.NOTPARALLEL: extpacks-build-solaris.rsync-out-of-vm extpacks-build-solaris.rsync-into-vm
+-.PHONY: extpacks-build-solaris.rsync-out-of-vm extpacks-build-solaris.rsync-into-vm extpacks-build-solaris.build-it
+-
+-extpacks-build-solaris.amd64: extpacks-build-solaris.rsync-out-of-vm
+-extpacks-build-solaris.x86: extpacks-build-solaris.rsync-out-of-vm
+-endif
+-
+-extpacks-build-os2.x86:
+-#ifeq ($(KBUILD_TARGET),os2)
+-# + $(VBOX_KMK_TIME) $(KMK) $(VBOX_EXTPACKS_BUILD.x86) all $(VBOX_EXTPACKS_HOST_BUILD_TWEAK)
+-#else
+-# $(VBOX_KMK_TIME) ssh vbox@192.168.27.3 " cd /mnt/tinderbox/$(VBOX_EXTPACKS_BUILD_SUBDIRNAME) && tools/env.sh --no-wine kmk $(VBOX_EXTPACKS_BUILD.x86) "
+-#endif
+-
+-extpacks-build-linux.amd64: $(VBOX_EXTPACKS_BUILD_WIN_HOST_FIRST)
+-ifeq ($(KBUILD_TARGET).$(KBUILD_TARGET_ARCH),linux.amd64)
+- + $(VBOX_KMK_TIME) $(KMK) $(VBOX_EXTPACKS_BUILD.amd64) all $(VBOX_EXTPACKS_HOST_BUILD_TWEAK)
+-else
+- $(call MSG_L1,Building Linux/amd64 extension packs)
+- $(VBOX_KMK_TIME) ssh vbox@192.168.27.12 " echo $@ && cd /mnt/tinderbox/$(VBOX_EXTPACKS_BUILD_SUBDIRNAME) && tools/env.sh --no-wine kmk $(VBOX_EXTPACKS_BUILD.amd64) all"
+-endif
+-
+-extpacks-build-linux.x86: $(VBOX_EXTPACKS_BUILD_WIN_HOST_FIRST)
+-ifeq ($(KBUILD_TARGET).$(KBUILD_TARGET_ARCH),linux.x86)
+- + $(VBOX_KMK_TIME) $(KMK) $(VBOX_EXTPACKS_BUILD.x86) all $(VBOX_EXTPACKS_HOST_BUILD_TWEAK)
+-else
+- $(call MSG_L1,Building Linux/x86 extension packs)
+- $(VBOX_KMK_TIME) ssh vbox@192.168.27.11 " echo $@ && cd /mnt/tinderbox/$(VBOX_EXTPACKS_BUILD_SUBDIRNAME) && tools/env.sh --no-wine kmk $(VBOX_EXTPACKS_BUILD.x86) all"
+-endif
+-
+-extpacks-build-freebsd.amd64: $(VBOX_EXTPACKS_BUILD_WIN_HOST_FIRST)
+-#ifeq ($(KBUILD_TARGET).$(KBUILD_TARGET_ARCH),freebsd.amd64)
+-# + $(VBOX_KMK_TIME) $(KMK) $(VBOX_EXTPACKS_BUILD.amd64) all $(VBOX_EXTPACKS_HOST_BUILD_TWEAK)
+-#else
+-# $(call MSG_L1,Building FreeBSD/amd64 extension packs)
+-# $(VBOX_KMK_TIME) ssh vbox@192.168.27.17 " echo $@ && cd /mnt/tinderbox/$(VBOX_EXTPACKS_BUILD_SUBDIRNAME) && tools/env.sh --no-wine kmk $(VBOX_EXTPACKS_BUILD.amd64) all"
+-#endif
+-
+-extpacks-build-freebsd.x86: $(VBOX_EXTPACKS_BUILD_WIN_HOST_FIRST)
+-#ifeq ($(KBUILD_TARGET).$(KBUILD_TARGET_ARCH),freebsd.x86)
+-# + $(VBOX_KMK_TIME) $(KMK) $(VBOX_EXTPACKS_BUILD.x86) all $(VBOX_EXTPACKS_HOST_BUILD_TWEAK)
+-#else
+-# $(call MSG_L1,Building FreeBSD/x86 extension packs)
+-# $(VBOX_KMK_TIME) ssh vbox@192.168.27.7 " echo $@ && cd /mnt/tinderbox/$(VBOX_EXTPACKS_BUILD_SUBDIRNAME) && tools/env.sh --no-wine kmk $(VBOX_EXTPACKS_BUILD.x86) all"
+-#endif
+-
+-extpacks-build-darwin.amd64: $(VBOX_EXTPACKS_BUILD_WIN_HOST_FIRST)
+-ifeq ($(KBUILD_TARGET).$(KBUILD_TARGET_ARCH),darwin.amd64)
+- + $(VBOX_KMK_TIME) $(KMK) $(VBOX_EXTPACKS_BUILD.amd64) all $(VBOX_EXTPACKS_HOST_BUILD_TWEAK)
+-else
+- $(call MSG_L1,Building Darwin/amd64 extension packs)
+- $(VBOX_KMK_TIME) $(call VBOX_RSYNC_IN_FN,darwin,amd64) . 192.168.27.15:/Users/vbox/tinderbox/$(VBOX_EXTPACKS_BUILD_SUBDIRNAME)
+- $(VBOX_KMK_TIME) ssh vbox@192.168.27.15 " echo $@ && cd /Users/vbox/tinderbox/$(VBOX_EXTPACKS_BUILD_SUBDIRNAME) && tools/env.sh --no-wine kmk $(VBOX_EXTPACKS_BUILD.amd64) all"
+- $(VBOX_KMK_TIME) rsync -am -v --delete 192.168.27.15:/Users/vbox/tinderbox/$(VBOX_EXTPACKS_BUILD_SUBDIRNAME)/out/darwin.amd64 out/
+-endif
+-
+-extpacks-build-darwin.x86: $(VBOX_EXTPACKS_BUILD_WIN_HOST_FIRST)
+-ifeq ($(KBUILD_TARGET).$(KBUILD_TARGET_ARCH),darwin.x86)
+- + $(VBOX_KMK_TIME) $(KMK) $(VBOX_EXTPACKS_BUILD.x86) all $(VBOX_EXTPACKS_HOST_BUILD_TWEAK)
+-else
+- $(call MSG_L1,Building Darwin/x86 extension packs)
+- $(VBOX_KMK_TIME) $(call VBOX_RSYNC_IN_FN,darwin,x86) . 192.168.27.5:/Users/vbox/tinderbox/$(VBOX_EXTPACKS_BUILD_SUBDIRNAME)
+- $(VBOX_KMK_TIME) ssh vbox@192.168.27.5 " echo $@ && cd /Users/vbox/tinderbox/$(VBOX_EXTPACKS_BUILD_SUBDIRNAME) && tools/env.sh --no-wine kmk $(VBOX_EXTPACKS_BUILD.x86) all"
+- $(VBOX_KMK_TIME) rsync -am -v --delete 192.168.27.5:/Users/vbox/tinderbox/$(VBOX_EXTPACKS_BUILD_SUBDIRNAME)/out/darwin.x86 out/
+-endif
+-
+-
+-extpacks-packing:
+- + $(KMK) VBOX_ONLY_EXTPACKS=1 \
+- VBOX_WITH_EXTPACK_OS_ARCHS="darwin.amd64 darwin.x86 linux.amd64 linux.x86 solaris.amd64 solaris.x86 win.amd64 win.x86" \
+- packing
+-# +++ freebsd.amd64 freebsd.x86 os2.x86 ^^^
+-
+-.PHONY: \
+- extpacks-build-win.x86 \
+- extpacks-build-win.amd64 \
+- extpacks-build-solaris.amd64 \
+- extpacks-build-solaris.x86 \
+- extpacks-build-os2.x86 \
+- extpacks-build-linux.amd64 \
+- extpacks-build-linux.x86 \
+- extpacks-build-freebsd.amd64 \
+- extpacks-build-freebsd.x86 \
+- extpacks-build-darwin.amd64 \
+- extpacks-build-darwin.x86 \
+- extpacks-packing
+-
+-
+ #
+ # Build the test suite, all of it.
+ #
+--- VirtualBox-4.1.18.orig/src/VBox/Devices/build/VBoxDD.cpp 2012-06-20 10:15:51.000000000 -0300
++++ VirtualBox-4.1.18/src/VBox/Devices/build/VBoxDD.cpp 2012-07-24 16:18:03.964493454 -0300
+@@ -132,11 +132,6 @@
+ if (RT_FAILURE(rc))
+ return rc;
+ #endif
+-#ifdef VBOX_WITH_EHCI_IMPL
+- rc = pCallbacks->pfnRegister(pCallbacks, &g_DeviceEHCI);
+- if (RT_FAILURE(rc))
+- return rc;
+-#endif
+ #ifdef VBOX_ACPI
+ rc = pCallbacks->pfnRegister(pCallbacks, &g_DeviceACPI);
+ if (RT_FAILURE(rc))
+--- VirtualBox-4.1.18.orig/src/VBox/Devices/build/VBoxDD.h 2012-06-20 10:15:51.000000000 -0300
++++ VirtualBox-4.1.18/src/VBox/Devices/build/VBoxDD.h 2012-07-24 16:20:35.939205389 -0300
+@@ -62,7 +62,6 @@
+ extern const PDMDEVREG g_DeviceICH6_HDA;
+ extern const PDMDEVREG g_DeviceAudioSniffer;
+ extern const PDMDEVREG g_DeviceOHCI;
+-extern const PDMDEVREG g_DeviceEHCI;
+ extern const PDMDEVREG g_DeviceACPI;
+ extern const PDMDEVREG g_DeviceDMA;
+ extern const PDMDEVREG g_DeviceFloppyController;
+--- VirtualBox-4.1.18.orig/src/VBox/Main/include/ExtPackManagerImpl.h 2012-06-20 10:17:33.000000000 -0300
++++ /dev/null 2012-07-24 14:48:18.638572110 -0300
+@@ -1,245 +0,0 @@
+-/* $Id: ExtPackManagerImpl.h $ */
+-/** @file
+- * VirtualBox Main - interface for Extension Packs, VBoxSVC & VBoxC.
+- */
+-
+-/*
+- * Copyright (C) 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.
+- */
+-
+-#ifndef ____H_EXTPACKMANAGERIMPL
+-#define ____H_EXTPACKMANAGERIMPL
+-
+-#include "VirtualBoxBase.h"
+-#include <VBox/ExtPack/ExtPack.h>
+-#include <iprt/fs.h>
+-
+-/**
+- * An extension pack file.
+- */
+-class ATL_NO_VTABLE ExtPackFile :
+- public VirtualBoxBase,
+- VBOX_SCRIPTABLE_IMPL(IExtPackFile)
+-{
+-public:
+- /** @name COM and internal init/term/mapping cruft.
+- * @{ */
+- VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT(ExtPackFile, IExtPackFile)
+- DECLARE_NOT_AGGREGATABLE(ExtPackFile)
+- DECLARE_PROTECT_FINAL_CONSTRUCT()
+- BEGIN_COM_MAP(ExtPackFile)
+- VBOX_DEFAULT_INTERFACE_ENTRIES(IExtPackFile)
+- COM_INTERFACE_ENTRY(IExtPackBase)
+- END_COM_MAP()
+- DECLARE_EMPTY_CTOR_DTOR(ExtPackFile)
+-
+- HRESULT FinalConstruct();
+- void FinalRelease();
+- HRESULT initWithFile(const char *a_pszFile, const char *a_pszDigest, class ExtPackManager *a_pExtPackMgr, VirtualBox *a_pVirtualBox);
+- void uninit();
+- RTMEMEF_NEW_AND_DELETE_OPERATORS();
+- /** @} */
+-
+- /** @name IExtPackBase interfaces
+- * @{ */
+- STDMETHOD(COMGETTER(Name))(BSTR *a_pbstrName);
+- STDMETHOD(COMGETTER(Description))(BSTR *a_pbstrDescription);
+- STDMETHOD(COMGETTER(Version))(BSTR *a_pbstrVersion);
+- STDMETHOD(COMGETTER(Revision))(ULONG *a_puRevision);
+- STDMETHOD(COMGETTER(VRDEModule))(BSTR *a_pbstrVrdeModule);
+- STDMETHOD(COMGETTER(PlugIns))(ComSafeArrayOut(IExtPackPlugIn *, a_paPlugIns));
+- STDMETHOD(COMGETTER(Usable))(BOOL *a_pfUsable);
+- STDMETHOD(COMGETTER(WhyUnusable))(BSTR *a_pbstrWhy);
+- STDMETHOD(COMGETTER(ShowLicense))(BOOL *a_pfShowIt);
+- STDMETHOD(COMGETTER(License))(BSTR *a_pbstrHtmlLicense);
+- STDMETHOD(QueryLicense)(IN_BSTR a_bstrPreferredLocale, IN_BSTR a_bstrPreferredLanguage,
+- IN_BSTR a_bstrFormat, BSTR *a_pbstrLicense);
+- /** @} */
+-
+- /** @name IExtPackFile interfaces
+- * @{ */
+- STDMETHOD(COMGETTER(FilePath))(BSTR *a_pbstrPath);
+- STDMETHOD(Install)(BOOL a_fReplace, IN_BSTR a_bstrDisplayInfo, IProgress **a_ppProgress);
+- /** @} */
+-
+-private:
+- /** @name Misc init helpers
+- * @{ */
+- HRESULT initFailed(const char *a_pszWhyFmt, ...);
+- /** @} */
+-
+-private:
+- struct Data;
+- /** Pointer to the private instance. */
+- Data *m;
+-
+- friend class ExtPackManager;
+-};
+-
+-
+-/**
+- * An installed extension pack.
+- */
+-class ATL_NO_VTABLE ExtPack :
+- public VirtualBoxBase,
+- VBOX_SCRIPTABLE_IMPL(IExtPack)
+-{
+-public:
+- /** @name COM and internal init/term/mapping cruft.
+- * @{ */
+- VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT(ExtPack, IExtPack)
+- DECLARE_NOT_AGGREGATABLE(ExtPack)
+- DECLARE_PROTECT_FINAL_CONSTRUCT()
+- BEGIN_COM_MAP(ExtPack)
+- VBOX_DEFAULT_INTERFACE_ENTRIES(IExtPack)
+- COM_INTERFACE_ENTRY(IExtPackBase)
+- END_COM_MAP()
+- DECLARE_EMPTY_CTOR_DTOR(ExtPack)
+-
+- HRESULT FinalConstruct();
+- void FinalRelease();
+- HRESULT initWithDir(VBOXEXTPACKCTX a_enmContext, const char *a_pszName, const char *a_pszDir);
+- void uninit();
+- RTMEMEF_NEW_AND_DELETE_OPERATORS();
+- /** @} */
+-
+- /** @name IExtPackBase interfaces
+- * @{ */
+- STDMETHOD(COMGETTER(Name))(BSTR *a_pbstrName);
+- STDMETHOD(COMGETTER(Description))(BSTR *a_pbstrDescription);
+- STDMETHOD(COMGETTER(Version))(BSTR *a_pbstrVersion);
+- STDMETHOD(COMGETTER(Revision))(ULONG *a_puRevision);
+- STDMETHOD(COMGETTER(VRDEModule))(BSTR *a_pbstrVrdeModule);
+- STDMETHOD(COMGETTER(PlugIns))(ComSafeArrayOut(IExtPackPlugIn *, a_paPlugIns));
+- STDMETHOD(COMGETTER(Usable))(BOOL *a_pfUsable);
+- STDMETHOD(COMGETTER(WhyUnusable))(BSTR *a_pbstrWhy);
+- STDMETHOD(COMGETTER(ShowLicense))(BOOL *a_pfShowIt);
+- STDMETHOD(COMGETTER(License))(BSTR *a_pbstrHtmlLicense);
+- STDMETHOD(QueryLicense)(IN_BSTR a_bstrPreferredLocale, IN_BSTR a_bstrPreferredLanguage,
+- IN_BSTR a_bstrFormat, BSTR *a_pbstrLicense);
+- /** @} */
+-
+- /** @name IExtPack interfaces
+- * @{ */
+- STDMETHOD(QueryObject)(IN_BSTR a_bstrObjectId, IUnknown **a_ppUnknown);
+- /** @} */
+-
+- /** @name Internal interfaces used by ExtPackManager.
+- * @{ */
+- bool callInstalledHook(IVirtualBox *a_pVirtualBox, AutoWriteLock *a_pLock, PRTERRINFO pErrInfo);
+- HRESULT callUninstallHookAndClose(IVirtualBox *a_pVirtualBox, bool a_fForcedRemoval);
+- bool callVirtualBoxReadyHook(IVirtualBox *a_pVirtualBox, AutoWriteLock *a_pLock);
+- bool callConsoleReadyHook(IConsole *a_pConsole, AutoWriteLock *a_pLock);
+- bool callVmCreatedHook(IVirtualBox *a_pVirtualBox, IMachine *a_pMachine, AutoWriteLock *a_pLock);
+- bool callVmConfigureVmmHook(IConsole *a_pConsole, PVM a_pVM, AutoWriteLock *a_pLock, int *a_pvrc);
+- bool callVmPowerOnHook(IConsole *a_pConsole, PVM a_pVM, AutoWriteLock *a_pLock, int *a_pvrc);
+- bool callVmPowerOffHook(IConsole *a_pConsole, PVM a_pVM, AutoWriteLock *a_pLock);
+- HRESULT checkVrde(void);
+- HRESULT getVrdpLibraryName(Utf8Str *a_pstrVrdeLibrary);
+- bool wantsToBeDefaultVrde(void) const;
+- HRESULT refresh(bool *pfCanDelete);
+- /** @} */
+-
+-protected:
+- /** @name Internal helper methods.
+- * @{ */
+- void probeAndLoad(void);
+- bool findModule(const char *a_pszName, const char *a_pszExt, VBOXEXTPACKMODKIND a_enmKind,
+- Utf8Str *a_ppStrFound, bool *a_pfNative, PRTFSOBJINFO a_pObjInfo) const;
+- static bool objinfoIsEqual(PCRTFSOBJINFO pObjInfo1, PCRTFSOBJINFO pObjInfo2);
+- /** @} */
+-
+- /** @name Extension Pack Helpers
+- * @{ */
+- static DECLCALLBACK(int) hlpFindModule(PCVBOXEXTPACKHLP pHlp, const char *pszName, const char *pszExt,
+- VBOXEXTPACKMODKIND enmKind, char *pszFound, size_t cbFound, bool *pfNative);
+- static DECLCALLBACK(int) hlpGetFilePath(PCVBOXEXTPACKHLP pHlp, const char *pszFilename, char *pszPath, size_t cbPath);
+- static DECLCALLBACK(VBOXEXTPACKCTX) hlpGetContext(PCVBOXEXTPACKHLP pHlp);
+- static DECLCALLBACK(int) hlpReservedN(PCVBOXEXTPACKHLP pHlp);
+- /** @} */
+-
+-private:
+- struct Data;
+- /** Pointer to the private instance. */
+- Data *m;
+-
+- friend class ExtPackManager;
+-};
+-
+-
+-/**
+- * Extension pack manager.
+- */
+-class ATL_NO_VTABLE ExtPackManager :
+- public VirtualBoxBase,
+- VBOX_SCRIPTABLE_IMPL(IExtPackManager)
+-{
+- /** @name COM and internal init/term/mapping cruft.
+- * @{ */
+- VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT(ExtPackManager, IExtPackManager)
+- DECLARE_NOT_AGGREGATABLE(ExtPackManager)
+- DECLARE_PROTECT_FINAL_CONSTRUCT()
+- BEGIN_COM_MAP(ExtPackManager)
+- VBOX_DEFAULT_INTERFACE_ENTRIES(IExtPackManager)
+- END_COM_MAP()
+- DECLARE_EMPTY_CTOR_DTOR(ExtPackManager)
+-
+- HRESULT FinalConstruct();
+- void FinalRelease();
+- HRESULT initExtPackManager(VirtualBox *a_pVirtualBox, VBOXEXTPACKCTX a_enmContext);
+- void uninit();
+- RTMEMEF_NEW_AND_DELETE_OPERATORS();
+- /** @} */
+-
+- /** @name IExtPack interfaces
+- * @{ */
+- STDMETHOD(COMGETTER(InstalledExtPacks))(ComSafeArrayOut(IExtPack *, a_paExtPacks));
+- STDMETHOD(Find)(IN_BSTR a_bstrName, IExtPack **a_pExtPack);
+- STDMETHOD(OpenExtPackFile)(IN_BSTR a_bstrTarball, IExtPackFile **a_ppExtPackFile);
+- STDMETHOD(Uninstall)(IN_BSTR a_bstrName, BOOL a_fForcedRemoval, IN_BSTR a_bstrDisplayInfo, IProgress **a_ppProgress);
+- STDMETHOD(Cleanup)(void);
+- STDMETHOD(QueryAllPlugInsForFrontend)(IN_BSTR a_bstrFrontend, ComSafeArrayOut(BSTR, a_pabstrPlugInModules));
+- STDMETHOD(IsExtPackUsable(IN_BSTR a_bstrExtPack, BOOL *aUsable));
+- /** @} */
+-
+- /** @name Internal interfaces used by other Main classes.
+- * @{ */
+- static DECLCALLBACK(int) doInstallThreadProc(RTTHREAD hThread, void *pvJob);
+- HRESULT doInstall(ExtPackFile *a_pExtPackFile, bool a_fReplace, Utf8Str const *a_pstrDisplayInfo);
+- static DECLCALLBACK(int) doUninstallThreadProc(RTTHREAD hThread, void *pvJob);
+- HRESULT doUninstall(const Utf8Str *a_pstrName, bool a_fForcedRemoval, const Utf8Str *a_pstrDisplayInfo);
+- void callAllVirtualBoxReadyHooks(void);
+- void callAllConsoleReadyHooks(IConsole *a_pConsole);
+- void callAllVmCreatedHooks(IMachine *a_pMachine);
+- int callAllVmConfigureVmmHooks(IConsole *a_pConsole, PVM a_pVM);
+- int callAllVmPowerOnHooks(IConsole *a_pConsole, PVM a_pVM);
+- void callAllVmPowerOffHooks(IConsole *a_pConsole, PVM a_pVM);
+- HRESULT checkVrdeExtPack(Utf8Str const *a_pstrExtPack);
+- int getVrdeLibraryPathForExtPack(Utf8Str const *a_pstrExtPack, Utf8Str *a_pstrVrdeLibrary);
+- HRESULT getDefaultVrdeExtPack(Utf8Str *a_pstrExtPack);
+- bool isExtPackUsable(const char *a_pszExtPack);
+- void dumpAllToReleaseLog(void);
+- /** @} */
+-
+-private:
+- HRESULT runSetUidToRootHelper(Utf8Str const *a_pstrDisplayInfo, const char *a_pszCommand, ...);
+- ExtPack *findExtPack(const char *a_pszName);
+- void removeExtPack(const char *a_pszName);
+- HRESULT refreshExtPack(const char *a_pszName, bool a_fUnsuableIsError, ExtPack **a_ppExtPack);
+-
+-private:
+- struct Data;
+- /** Pointer to the private instance. */
+- Data *m;
+-};
+-
+-#endif
+-/* vi: set tabstop=4 shiftwidth=4 expandtab: */
+--- VirtualBox-4.1.18.orig/src/VBox/Main/include/ExtPackUtil.h 2012-06-20 10:17:33.000000000 -0300
++++ /dev/null 2012-07-24 14:48:18.638572110 -0300
+@@ -1,137 +0,0 @@
+-/* $Id: ExtPackUtil.h $ */
+-/** @file
+- * VirtualBox Main - Extension Pack Utilities and definitions, VBoxC, VBoxSVC, ++.
+- */
+-
+-/*
+- * Copyright (C) 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.
+- */
+-
+-#ifndef ____H_EXTPACKUTIL
+-#define ____H_EXTPACKUTIL
+-
+-#include <iprt/cpp/ministring.h>
+-#include <iprt/fs.h>
+-#include <iprt/vfs.h>
+-
+-
+-/** @name VBOX_EXTPACK_DESCRIPTION_NAME
+- * The name of the description file in an extension pack. */
+-#define VBOX_EXTPACK_DESCRIPTION_NAME "ExtPack.xml"
+-/** @name VBOX_EXTPACK_DESCRIPTION_NAME
+- * The name of the manifest file in an extension pack. */
+-#define VBOX_EXTPACK_MANIFEST_NAME "ExtPack.manifest"
+-/** @name VBOX_EXTPACK_SIGNATURE_NAME
+- * The name of the signature file in an extension pack. */
+-#define VBOX_EXTPACK_SIGNATURE_NAME "ExtPack.signature"
+-/** @name VBOX_EXTPACK_LICENSE_NAME_PREFIX
+- * The name prefix of a license file in an extension pack. There can be
+- * several license files in a pack, the variations being on locale, language
+- * and format (HTML, RTF, plain text). All extension packages shall include
+- * a */
+-#define VBOX_EXTPACK_LICENSE_NAME_PREFIX "ExtPack-license"
+-/** @name VBOX_EXTPACK_SUFFIX
+- * The suffix of a extension pack tarball. */
+-#define VBOX_EXTPACK_SUFFIX ".vbox-extpack"
+-
+-/** The minimum length (strlen) of a extension pack name. */
+-#define VBOX_EXTPACK_NAME_MIN_LEN 3
+-/** The max length (strlen) of a extension pack name. */
+-#define VBOX_EXTPACK_NAME_MAX_LEN 64
+-
+-/** The architecture-dependent application data subdirectory where the
+- * extension packs are installed. Relative to RTPathAppPrivateArch. */
+-#define VBOX_EXTPACK_INSTALL_DIR "ExtensionPacks"
+-/** The architecture-independent application data subdirectory where the
+- * certificates are installed. Relative to RTPathAppPrivateNoArch. */
+-#define VBOX_EXTPACK_CERT_DIR "ExtPackCertificates"
+-
+-/** The maximum entry name length.
+- * Play short and safe. */
+-#define VBOX_EXTPACK_MAX_MEMBER_NAME_LENGTH 128
+-
+-
+-/**
+- * Plug-in descriptor.
+- */
+-typedef struct VBOXEXTPACKPLUGINDESC
+-{
+- /** The name. */
+- RTCString strName;
+- /** The module name. */
+- RTCString strModule;
+- /** The description. */
+- RTCString strDescription;
+- /** The frontend or component which it plugs into. */
+- RTCString strFrontend;
+-} VBOXEXTPACKPLUGINDESC;
+-/** Pointer to a plug-in descriptor. */
+-typedef VBOXEXTPACKPLUGINDESC *PVBOXEXTPACKPLUGINDESC;
+-
+-/**
+- * Extension pack descriptor
+- *
+- * This is the internal representation of the ExtPack.xml.
+- */
+-typedef struct VBOXEXTPACKDESC
+-{
+- /** The name. */
+- RTCString strName;
+- /** The description. */
+- RTCString strDescription;
+- /** The version string. */
+- RTCString strVersion;
+- /** The edition string. */
+- RTCString strEdition;
+- /** The internal revision number. */
+- uint32_t uRevision;
+- /** The name of the main module. */
+- RTCString strMainModule;
+- /** The name of the VRDE module, empty if none. */
+- RTCString strVrdeModule;
+- /** The number of plug-in descriptors. */
+- uint32_t cPlugIns;
+- /** Pointer to an array of plug-in descriptors. */
+- PVBOXEXTPACKPLUGINDESC paPlugIns;
+- /** Whether to show the license prior to installation. */
+- bool fShowLicense;
+-} VBOXEXTPACKDESC;
+-
+-/** Pointer to a extension pack descriptor. */
+-typedef VBOXEXTPACKDESC *PVBOXEXTPACKDESC;
+-/** Pointer to a const extension pack descriptor. */
+-typedef VBOXEXTPACKDESC const *PCVBOXEXTPACKDESC;
+-
+-
+-void VBoxExtPackInitDesc(PVBOXEXTPACKDESC a_pExtPackDesc);
+-RTCString *VBoxExtPackLoadDesc(const char *a_pszDir, PVBOXEXTPACKDESC a_pExtPackDesc, PRTFSOBJINFO a_pObjInfo);
+-RTCString *VBoxExtPackLoadDescFromVfsFile(RTVFSFILE hVfsFile, PVBOXEXTPACKDESC a_pExtPackDesc, PRTFSOBJINFO a_pObjInfo);
+-RTCString *VBoxExtPackExtractNameFromTarballPath(const char *pszTarball);
+-void VBoxExtPackFreeDesc(PVBOXEXTPACKDESC a_pExtPackDesc);
+-bool VBoxExtPackIsValidName(const char *pszName);
+-bool VBoxExtPackIsValidMangledName(const char *pszMangledName, size_t cchMax = RTSTR_MAX);
+-RTCString *VBoxExtPackMangleName(const char *pszName);
+-RTCString *VBoxExtPackUnmangleName(const char *pszMangledName, size_t cbMax);
+-int VBoxExtPackCalcDir(char *pszExtPackDir, size_t cbExtPackDir, const char *pszParentDir, const char *pszName);
+-bool VBoxExtPackIsValidVersionString(const char *pszVersion);
+-bool VBoxExtPackIsValidEditionString(const char *pszEdition);
+-bool VBoxExtPackIsValidModuleString(const char *pszModule);
+-
+-int VBoxExtPackValidateMember(const char *pszName, RTVFSOBJTYPE enmType, RTVFSOBJ hVfsObj, char *pszError, size_t cbError);
+-int VBoxExtPackOpenTarFss(RTFILE hTarballFile, char *pszError, size_t cbError, PRTVFSFSSTREAM phTarFss, PRTMANIFEST phFileManifest);
+-int VBoxExtPackValidateTarball(RTFILE hTarballFile, const char *pszExtPackName,
+- const char *pszTarball, const char *pszTarballDigest,
+- char *pszError, size_t cbError,
+- PRTMANIFEST phValidManifest, PRTVFSFILE phXmlFile, RTCString *pStrDigest);
+-
+-
+-#endif
+-
+--- VirtualBox-4.1.18.orig/src/VBox/Main/src-all/ExtPackManagerImpl.cpp 2012-06-20 10:17:34.000000000 -0300
++++ /dev/null 2012-07-24 14:48:18.638572110 -0300
+@@ -1,3126 +0,0 @@
+-/* $Id: ExtPackManagerImpl.cpp $ */
+-/** @file
+- * VirtualBox Main - interface for Extension Packs, VBoxSVC & VBoxC.
+- */
+-
+-/*
+- * Copyright (C) 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.
+- */
+-
+-
+-/*******************************************************************************
+-* Header Files *
+-*******************************************************************************/
+-#include "ExtPackManagerImpl.h"
+-#include "ExtPackUtil.h"
+-
+-#include <iprt/buildconfig.h>
+-#include <iprt/ctype.h>
+-#include <iprt/dir.h>
+-#include <iprt/env.h>
+-#include <iprt/file.h>
+-#include <iprt/ldr.h>
+-#include <iprt/manifest.h>
+-#include <iprt/param.h>
+-#include <iprt/path.h>
+-#include <iprt/pipe.h>
+-#include <iprt/process.h>
+-#include <iprt/string.h>
+-
+-#include <VBox/com/array.h>
+-#include <VBox/com/ErrorInfo.h>
+-#include <VBox/err.h>
+-#include <VBox/log.h>
+-#include <VBox/sup.h>
+-#include <VBox/version.h>
+-#include "AutoCaller.h"
+-#include "Global.h"
+-#include "ProgressImpl.h"
+-#include "SystemPropertiesImpl.h"
+-#include "VirtualBoxImpl.h"
+-
+-
+-/*******************************************************************************
+-* Defined Constants And Macros *
+-*******************************************************************************/
+-/** @name VBOX_EXTPACK_HELPER_NAME
+- * The name of the utility application we employ to install and uninstall the
+- * extension packs. This is a set-uid-to-root binary on unixy platforms, which
+- * is why it has to be a separate application.
+- */
+-#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
+-# define VBOX_EXTPACK_HELPER_NAME "VBoxExtPackHelperApp.exe"
+-#else
+-# define VBOX_EXTPACK_HELPER_NAME "VBoxExtPackHelperApp"
+-#endif
+-
+-
+-/*******************************************************************************
+-* Structures and Typedefs *
+-*******************************************************************************/
+-struct ExtPackBaseData
+-{
+-public:
+- /** The extension pack descriptor (loaded from the XML, mostly). */
+- VBOXEXTPACKDESC Desc;
+- /** The file system object info of the XML file.
+- * This is for detecting changes and save time in refresh(). */
+- RTFSOBJINFO ObjInfoDesc;
+- /** Whether it's usable or not. */
+- bool fUsable;
+- /** Why it is unusable. */
+- Utf8Str strWhyUnusable;
+-};
+-
+-/**
+- * Private extension pack data.
+- */
+-struct ExtPackFile::Data : public ExtPackBaseData
+-{
+-public:
+- /** The path to the tarball. */
+- Utf8Str strExtPackFile;
+- /** The SHA-256 hash of the file (as string). */
+- Utf8Str strDigest;
+- /** The file handle of the extension pack file. */
+- RTFILE hExtPackFile;
+- /** Our manifest for the tarball. */
+- RTMANIFEST hOurManifest;
+- /** Pointer to the extension pack manager. */
+- ComObjPtr<ExtPackManager> ptrExtPackMgr;
+- /** Pointer to the VirtualBox object so we can create a progress object. */
+- VirtualBox *pVirtualBox;
+-
+- RTMEMEF_NEW_AND_DELETE_OPERATORS();
+-};
+-
+-/**
+- * Private extension pack data.
+- */
+-struct ExtPack::Data : public ExtPackBaseData
+-{
+-public:
+- /** Where the extension pack is located. */
+- Utf8Str strExtPackPath;
+- /** The file system object info of the extension pack directory.
+- * This is for detecting changes and save time in refresh(). */
+- RTFSOBJINFO ObjInfoExtPack;
+- /** The full path to the main module. */
+- Utf8Str strMainModPath;
+- /** The file system object info of the main module.
+- * This is used to determin whether to bother try reload it. */
+- RTFSOBJINFO ObjInfoMainMod;
+- /** The module handle of the main extension pack module. */
+- RTLDRMOD hMainMod;
+-
+- /** The helper callbacks for the extension pack. */
+- VBOXEXTPACKHLP Hlp;
+- /** Pointer back to the extension pack object (for Hlp methods). */
+- ExtPack *pThis;
+- /** The extension pack registration structure. */
+- PCVBOXEXTPACKREG pReg;
+- /** The current context. */
+- VBOXEXTPACKCTX enmContext;
+- /** Set if we've made the pfnVirtualBoxReady or pfnConsoleReady call. */
+- bool fMadeReadyCall;
+-
+- RTMEMEF_NEW_AND_DELETE_OPERATORS();
+-};
+-
+-/** List of extension packs. */
+-typedef std::list< ComObjPtr<ExtPack> > ExtPackList;
+-
+-/**
+- * Private extension pack manager data.
+- */
+-struct ExtPackManager::Data
+-{
+- /** The directory where the extension packs are installed. */
+- Utf8Str strBaseDir;
+- /** The directory where the certificates this installation recognizes are
+- * stored. */
+- Utf8Str strCertificatDirPath;
+- /** The list of installed extension packs. */
+- ExtPackList llInstalledExtPacks;
+- /** Pointer to the VirtualBox object, our parent. */
+- VirtualBox *pVirtualBox;
+- /** The current context. */
+- VBOXEXTPACKCTX enmContext;
+-#if !defined(RT_OS_WINDOWS) && !defined(RT_OS_DARWIN)
+- /** File handle for the VBoxVMM libary which we slurp because ExtPacks depend on it. */
+- RTLDRMOD hVBoxVMM;
+-#endif
+-
+- RTMEMEF_NEW_AND_DELETE_OPERATORS();
+-};
+-
+-/**
+- * Extension pack installation job.
+- */
+-typedef struct EXTPACKINSTALLJOB
+-{
+- /** Smart pointer to the extension pack file. */
+- ComPtr<ExtPackFile> ptrExtPackFile;
+- /** The replace argument. */
+- bool fReplace;
+- /** The display info argument. */
+- Utf8Str strDisplayInfo;
+- /** Smart pointer to the extension manager. */
+- ComPtr<ExtPackManager> ptrExtPackMgr;
+- /** Smart pointer to the progress object for this job. */
+- ComObjPtr<Progress> ptrProgress;
+-} EXTPACKINSTALLJOB;
+-/** Pointer to an extension pack installation job. */
+-typedef EXTPACKINSTALLJOB *PEXTPACKINSTALLJOB;
+-
+-/**
+- * Extension pack uninstallation job.
+- */
+-typedef struct EXTPACKUNINSTALLJOB
+-{
+- /** Smart pointer to the extension manager. */
+- ComPtr<ExtPackManager> ptrExtPackMgr;
+- /** The name of the extension pack. */
+- Utf8Str strName;
+- /** The replace argument. */
+- bool fForcedRemoval;
+- /** The display info argument. */
+- Utf8Str strDisplayInfo;
+- /** Smart pointer to the progress object for this job. */
+- ComObjPtr<Progress> ptrProgress;
+-} EXTPACKUNINSTALLJOB;
+-/** Pointer to an extension pack uninstallation job. */
+-typedef EXTPACKUNINSTALLJOB *PEXTPACKUNINSTALLJOB;
+-
+-
+-DEFINE_EMPTY_CTOR_DTOR(ExtPackFile)
+-
+-/**
+- * Called by ComObjPtr::createObject when creating the object.
+- *
+- * Just initialize the basic object state, do the rest in initWithDir().
+- *
+- * @returns S_OK.
+- */
+-HRESULT ExtPackFile::FinalConstruct()
+-{
+- m = NULL;
+- return BaseFinalConstruct();
+-}
+-
+-/**
+- * Initializes the extension pack by reading its file.
+- *
+- * @returns COM status code.
+- * @param a_pszFile The path to the extension pack file.
+- * @param a_pszDigest The SHA-256 digest of the file. Or an empty string.
+- * @param a_pExtPackMgr Pointer to the extension pack manager.
+- * @param a_pVirtualBox Pointer to the VirtualBox object.
+- */
+-HRESULT ExtPackFile::initWithFile(const char *a_pszFile, const char *a_pszDigest, ExtPackManager *a_pExtPackMgr, VirtualBox *a_pVirtualBox)
+-{
+- AutoInitSpan autoInitSpan(this);
+- AssertReturn(autoInitSpan.isOk(), E_FAIL);
+-
+- /*
+- * Allocate + initialize our private data.
+- */
+- m = new ExtPackFile::Data;
+- VBoxExtPackInitDesc(&m->Desc);
+- RT_ZERO(m->ObjInfoDesc);
+- m->fUsable = false;
+- m->strWhyUnusable = tr("ExtPack::init failed");
+- m->strExtPackFile = a_pszFile;
+- m->strDigest = a_pszDigest;
+- m->hExtPackFile = NIL_RTFILE;
+- m->hOurManifest = NIL_RTMANIFEST;
+- m->ptrExtPackMgr = a_pExtPackMgr;
+- m->pVirtualBox = a_pVirtualBox;
+-
+- RTCString *pstrTarName = VBoxExtPackExtractNameFromTarballPath(a_pszFile);
+- if (pstrTarName)
+- {
+- m->Desc.strName = *pstrTarName;
+- delete pstrTarName;
+- pstrTarName = NULL;
+- }
+-
+- autoInitSpan.setSucceeded();
+-
+- /*
+- * Try open the extension pack and check that it is a regular file.
+- */
+- int vrc = RTFileOpen(&m->hExtPackFile, a_pszFile,
+- RTFILE_O_READ | RTFILE_O_DENY_WRITE | RTFILE_O_OPEN);
+- if (RT_FAILURE(vrc))
+- {
+- if (vrc == VERR_FILE_NOT_FOUND || vrc == VERR_PATH_NOT_FOUND)
+- return initFailed(tr("'%s' file not found"), a_pszFile);
+- return initFailed(tr("RTFileOpen('%s',,) failed with %Rrc"), a_pszFile, vrc);
+- }
+-
+- RTFSOBJINFO ObjInfo;
+- vrc = RTFileQueryInfo(m->hExtPackFile, &ObjInfo, RTFSOBJATTRADD_UNIX);
+- if (RT_FAILURE(vrc))
+- return initFailed(tr("RTFileQueryInfo failed with %Rrc on '%s'"), vrc, a_pszFile);
+- if (!RTFS_IS_FILE(ObjInfo.Attr.fMode))
+- return initFailed(tr("Not a regular file: %s"), a_pszFile);
+-
+- /*
+- * Validate the tarball and extract the XML file.
+- */
+- char szError[8192];
+- RTVFSFILE hXmlFile;
+- vrc = VBoxExtPackValidateTarball(m->hExtPackFile, NULL /*pszExtPackName*/, a_pszFile, a_pszDigest,
+- szError, sizeof(szError), &m->hOurManifest, &hXmlFile, &m->strDigest);
+- if (RT_FAILURE(vrc))
+- return initFailed(tr("%s"), szError);
+-
+- /*
+- * Parse the XML.
+- */
+- RTCString strSavedName(m->Desc.strName);
+- RTCString *pStrLoadErr = VBoxExtPackLoadDescFromVfsFile(hXmlFile, &m->Desc, &m->ObjInfoDesc);
+- RTVfsFileRelease(hXmlFile);
+- if (pStrLoadErr != NULL)
+- {
+- m->strWhyUnusable.printf(tr("Failed to the xml file: %s"), pStrLoadErr->c_str());
+- m->Desc.strName = strSavedName;
+- delete pStrLoadErr;
+- return S_OK;
+- }
+-
+- /*
+- * Match the tarball name with the name from the XML.
+- */
+- /** @todo drop this restriction after the old install interface is
+- * dropped. */
+- if (!strSavedName.equalsIgnoreCase(m->Desc.strName))
+- return initFailed(tr("Extension pack name mismatch between the downloaded file and the XML inside it (xml='%s' file='%s')"),
+- m->Desc.strName.c_str(), strSavedName.c_str());
+-
+- m->fUsable = true;
+- m->strWhyUnusable.setNull();
+- return S_OK;
+-}
+-
+-/**
+- * Protected helper that formats the strWhyUnusable value.
+- *
+- * @returns S_OK
+- * @param a_pszWhyFmt Why it failed, format string.
+- * @param ... The format arguments.
+- */
+-HRESULT ExtPackFile::initFailed(const char *a_pszWhyFmt, ...)
+-{
+- va_list va;
+- va_start(va, a_pszWhyFmt);
+- m->strWhyUnusable.printfV(a_pszWhyFmt, va);
+- va_end(va);
+- return S_OK;
+-}
+-
+-/**
+- * COM cruft.
+- */
+-void ExtPackFile::FinalRelease()
+-{
+- uninit();
+- BaseFinalRelease();
+-}
+-
+-/**
+- * Do the actual cleanup.
+- */
+-void ExtPackFile::uninit()
+-{
+- /* Enclose the state transition Ready->InUninit->NotReady */
+- AutoUninitSpan autoUninitSpan(this);
+- if (!autoUninitSpan.uninitDone() && m != NULL)
+- {
+- VBoxExtPackFreeDesc(&m->Desc);
+- RTFileClose(m->hExtPackFile);
+- m->hExtPackFile = NIL_RTFILE;
+- RTManifestRelease(m->hOurManifest);
+- m->hOurManifest = NIL_RTMANIFEST;
+-
+- delete m;
+- m = NULL;
+- }
+-}
+-
+-STDMETHODIMP ExtPackFile::COMGETTER(Name)(BSTR *a_pbstrName)
+-{
+- CheckComArgOutPointerValid(a_pbstrName);
+-
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (SUCCEEDED(hrc))
+- {
+- Bstr str(m->Desc.strName);
+- str.cloneTo(a_pbstrName);
+- }
+- return hrc;
+-}
+-
+-STDMETHODIMP ExtPackFile::COMGETTER(Description)(BSTR *a_pbstrDescription)
+-{
+- CheckComArgOutPointerValid(a_pbstrDescription);
+-
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (SUCCEEDED(hrc))
+- {
+- Bstr str(m->Desc.strDescription);
+- str.cloneTo(a_pbstrDescription);
+- }
+- return hrc;
+-}
+-
+-STDMETHODIMP ExtPackFile::COMGETTER(Version)(BSTR *a_pbstrVersion)
+-{
+- CheckComArgOutPointerValid(a_pbstrVersion);
+-
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (SUCCEEDED(hrc))
+- {
+- /* HACK ALERT: This is for easing backporting to 4.1. The edition stuff
+- will be changed into a separate */
+- if (m->Desc.strEdition.isEmpty())
+- {
+- Bstr str(m->Desc.strVersion);
+- str.cloneTo(a_pbstrVersion);
+- }
+- else
+- {
+- RTCString strHack(m->Desc.strVersion);
+- strHack.append('-');
+- strHack.append(m->Desc.strEdition);
+-
+- Bstr str(strHack);
+- str.cloneTo(a_pbstrVersion);
+- }
+- }
+- return hrc;
+-}
+-
+-STDMETHODIMP ExtPackFile::COMGETTER(Revision)(ULONG *a_puRevision)
+-{
+- CheckComArgOutPointerValid(a_puRevision);
+-
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (SUCCEEDED(hrc))
+- *a_puRevision = m->Desc.uRevision;
+- return hrc;
+-}
+-
+-STDMETHODIMP ExtPackFile::COMGETTER(VRDEModule)(BSTR *a_pbstrVrdeModule)
+-{
+- CheckComArgOutPointerValid(a_pbstrVrdeModule);
+-
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (SUCCEEDED(hrc))
+- {
+- Bstr str(m->Desc.strVrdeModule);
+- str.cloneTo(a_pbstrVrdeModule);
+- }
+- return hrc;
+-}
+-
+-STDMETHODIMP ExtPackFile::COMGETTER(PlugIns)(ComSafeArrayOut(IExtPackPlugIn *, a_paPlugIns))
+-{
+- /** @todo implement plug-ins. */
+-#ifdef VBOX_WITH_XPCOM
+- NOREF(a_paPlugIns);
+- NOREF(a_paPlugInsSize);
+-#endif
+- ReturnComNotImplemented();
+-}
+-
+-STDMETHODIMP ExtPackFile::COMGETTER(Usable)(BOOL *a_pfUsable)
+-{
+- CheckComArgOutPointerValid(a_pfUsable);
+-
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (SUCCEEDED(hrc))
+- *a_pfUsable = m->fUsable;
+- return hrc;
+-}
+-
+-STDMETHODIMP ExtPackFile::COMGETTER(WhyUnusable)(BSTR *a_pbstrWhy)
+-{
+- CheckComArgOutPointerValid(a_pbstrWhy);
+-
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (SUCCEEDED(hrc))
+- m->strWhyUnusable.cloneTo(a_pbstrWhy);
+- return hrc;
+-}
+-
+-STDMETHODIMP ExtPackFile::COMGETTER(ShowLicense)(BOOL *a_pfShowIt)
+-{
+- CheckComArgOutPointerValid(a_pfShowIt);
+-
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (SUCCEEDED(hrc))
+- *a_pfShowIt = m->Desc.fShowLicense;
+- return hrc;
+-}
+-
+-STDMETHODIMP ExtPackFile::COMGETTER(License)(BSTR *a_pbstrHtmlLicense)
+-{
+- Bstr bstrHtml("html");
+- return QueryLicense(Bstr::Empty.raw(), Bstr::Empty.raw(), bstrHtml.raw(), a_pbstrHtmlLicense);
+-}
+-
+-/* Same as ExtPack::QueryLicense, should really explore the subject of base classes here... */
+-STDMETHODIMP ExtPackFile::QueryLicense(IN_BSTR a_bstrPreferredLocale, IN_BSTR a_bstrPreferredLanguage, IN_BSTR a_bstrFormat,
+- BSTR *a_pbstrLicense)
+-{
+- /*
+- * Validate input.
+- */
+- CheckComArgOutPointerValid(a_pbstrLicense);
+- CheckComArgNotNull(a_bstrPreferredLocale);
+- CheckComArgNotNull(a_bstrPreferredLanguage);
+- CheckComArgNotNull(a_bstrFormat);
+-
+- Utf8Str strPreferredLocale(a_bstrPreferredLocale);
+- if (strPreferredLocale.length() != 2 && strPreferredLocale.length() != 0)
+- return setError(E_FAIL, tr("The preferred locale is a two character string or empty."));
+-
+- Utf8Str strPreferredLanguage(a_bstrPreferredLanguage);
+- if (strPreferredLanguage.length() != 2 && strPreferredLanguage.length() != 0)
+- return setError(E_FAIL, tr("The preferred lanuage is a two character string or empty."));
+-
+- Utf8Str strFormat(a_bstrFormat);
+- if ( !strFormat.equals("html")
+- && !strFormat.equals("rtf")
+- && !strFormat.equals("txt"))
+- return setError(E_FAIL, tr("The license format can only have the values 'html', 'rtf' and 'txt'."));
+-
+- /*
+- * Combine the options to form a file name before locking down anything.
+- */
+- char szName[sizeof(VBOX_EXTPACK_LICENSE_NAME_PREFIX "-de_DE.html") + 2];
+- if (strPreferredLocale.isNotEmpty() && strPreferredLanguage.isNotEmpty())
+- RTStrPrintf(szName, sizeof(szName), VBOX_EXTPACK_LICENSE_NAME_PREFIX "-%s_%s.%s",
+- strPreferredLocale.c_str(), strPreferredLanguage.c_str(), strFormat.c_str());
+- else if (strPreferredLocale.isNotEmpty())
+- RTStrPrintf(szName, sizeof(szName), VBOX_EXTPACK_LICENSE_NAME_PREFIX "-%s.%s", strPreferredLocale.c_str(), strFormat.c_str());
+- else if (strPreferredLanguage.isNotEmpty())
+- RTStrPrintf(szName, sizeof(szName), VBOX_EXTPACK_LICENSE_NAME_PREFIX "-_%s.%s", strPreferredLocale.c_str(), strFormat.c_str());
+- else
+- RTStrPrintf(szName, sizeof(szName), VBOX_EXTPACK_LICENSE_NAME_PREFIX ".%s", strFormat.c_str());
+-
+- /*
+- * Lock the extension pack. We need a write lock here as there must not be
+- * concurrent accesses to the tar file handle.
+- */
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (SUCCEEDED(hrc))
+- {
+- AutoWriteLock autoLock(this COMMA_LOCKVAL_SRC_POS);
+-
+- /*
+- * Do not permit this query on a pack that isn't considered usable (could
+- * be marked so because of bad license files).
+- */
+- if (!m->fUsable)
+- hrc = setError(E_FAIL, tr("%s"), m->strWhyUnusable.c_str());
+- else
+- {
+- /*
+- * Look it up in the manifest before scanning the tarball for it
+- */
+- if (RTManifestEntryExists(m->hOurManifest, szName))
+- {
+- RTVFSFSSTREAM hTarFss;
+- char szError[8192];
+- int vrc = VBoxExtPackOpenTarFss(m->hExtPackFile, szError, sizeof(szError), &hTarFss, NULL);
+- if (RT_SUCCESS(vrc))
+- {
+- for (;;)
+- {
+- /* Get the first/next. */
+- char *pszName;
+- RTVFSOBJ hVfsObj;
+- RTVFSOBJTYPE enmType;
+- vrc = RTVfsFsStrmNext(hTarFss, &pszName, &enmType, &hVfsObj);
+- if (RT_FAILURE(vrc))
+- {
+- if (vrc != VERR_EOF)
+- hrc = setError(VBOX_E_IPRT_ERROR, tr("RTVfsFsStrmNext failed: %Rrc"), vrc);
+- else
+- hrc = setError(E_UNEXPECTED, tr("'%s' was found in the manifest but not in the tarball"), szName);
+- break;
+- }
+-
+- /* Is this it? */
+- const char *pszAdjName = pszName[0] == '.' && pszName[1] == '/' ? &pszName[2] : pszName;
+- if ( !strcmp(pszAdjName, szName)
+- && ( enmType == RTVFSOBJTYPE_IO_STREAM
+- || enmType == RTVFSOBJTYPE_FILE))
+- {
+- RTVFSIOSTREAM hVfsIos = RTVfsObjToIoStream(hVfsObj);
+- RTVfsObjRelease(hVfsObj);
+- RTStrFree(pszName);
+-
+- /* Load the file into memory. */
+- RTFSOBJINFO ObjInfo;
+- vrc = RTVfsIoStrmQueryInfo(hVfsIos, &ObjInfo, RTFSOBJATTRADD_NOTHING);
+- if (RT_SUCCESS(vrc))
+- {
+- size_t cbFile = (size_t)ObjInfo.cbObject;
+- void *pvFile = RTMemAllocZ(cbFile + 1);
+- if (pvFile)
+- {
+- vrc = RTVfsIoStrmRead(hVfsIos, pvFile, cbFile, true /*fBlocking*/, NULL);
+- if (RT_SUCCESS(vrc))
+- {
+- /* try translate it into a string we can return. */
+- Bstr bstrLicense((const char *)pvFile, cbFile);
+- if (bstrLicense.isNotEmpty())
+- {
+- bstrLicense.detachTo(a_pbstrLicense);
+- hrc = S_OK;
+- }
+- else
+- hrc = setError(VBOX_E_IPRT_ERROR,
+- tr("The license file '%s' is empty or contains invalid UTF-8 encoding"),
+- szName);
+- }
+- else
+- hrc = setError(VBOX_E_IPRT_ERROR, tr("Failed to read '%s': %Rrc"), szName, vrc);
+- RTMemFree(pvFile);
+- }
+- else
+- hrc = setError(E_OUTOFMEMORY, tr("Failed to allocate %zu bytes for '%s'"), cbFile, szName);
+- }
+- else
+- hrc = setError(VBOX_E_IPRT_ERROR, tr("RTVfsIoStrmQueryInfo on '%s': %Rrc"), szName, vrc);
+- RTVfsIoStrmRelease(hVfsIos);
+- break;
+- }
+-
+- /* Release current. */
+- RTVfsObjRelease(hVfsObj);
+- RTStrFree(pszName);
+- }
+- RTVfsFsStrmRelease(hTarFss);
+- }
+- else
+- hrc = setError(VBOX_E_OBJECT_NOT_FOUND, tr("%s"), szError);
+- }
+- else
+- hrc = setError(VBOX_E_OBJECT_NOT_FOUND, tr("The license file '%s' was not found in '%s'"),
+- szName, m->strExtPackFile.c_str());
+- }
+- }
+- return hrc;
+-}
+-
+-STDMETHODIMP ExtPackFile::COMGETTER(FilePath)(BSTR *a_pbstrPath)
+-{
+- CheckComArgOutPointerValid(a_pbstrPath);
+-
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (SUCCEEDED(hrc))
+- m->strExtPackFile.cloneTo(a_pbstrPath);
+- return hrc;
+-}
+-
+-STDMETHODIMP ExtPackFile::Install(BOOL a_fReplace, IN_BSTR a_bstrDisplayInfo, IProgress **a_ppProgress)
+-{
+- if (a_ppProgress)
+- *a_ppProgress = NULL;
+-
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (SUCCEEDED(hrc))
+- {
+- if (m->fUsable)
+- {
+- PEXTPACKINSTALLJOB pJob = NULL;
+- try
+- {
+- pJob = new EXTPACKINSTALLJOB;
+- pJob->ptrExtPackFile = this;
+- pJob->fReplace = a_fReplace != FALSE;
+- pJob->strDisplayInfo = a_bstrDisplayInfo;
+- pJob->ptrExtPackMgr = m->ptrExtPackMgr;
+- hrc = pJob->ptrProgress.createObject();
+- if (SUCCEEDED(hrc))
+- {
+- Bstr bstrDescription = tr("Installing extension pack");
+- hrc = pJob->ptrProgress->init(
+-#ifndef VBOX_COM_INPROC
+- m->pVirtualBox,
+-#endif
+- static_cast<IExtPackFile *>(this),
+- bstrDescription.raw(),
+- FALSE /*aCancelable*/,
+- NULL /*aId*/);
+- }
+- if (SUCCEEDED(hrc))
+- {
+- ComPtr<Progress> ptrProgress = pJob->ptrProgress;
+- int vrc = RTThreadCreate(NULL /*phThread*/, ExtPackManager::doInstallThreadProc, pJob, 0,
+- RTTHREADTYPE_DEFAULT, 0 /*fFlags*/, "ExtPackInst");
+- if (RT_SUCCESS(vrc))
+- {
+- pJob = NULL; /* the thread deletes it */
+- ptrProgress.queryInterfaceTo(a_ppProgress);
+- }
+- else
+- hrc = setError(VBOX_E_IPRT_ERROR, tr("RTThreadCreate failed with %Rrc"), vrc);
+- }
+- }
+- catch (std::bad_alloc)
+- {
+- hrc = E_OUTOFMEMORY;
+- }
+- if (pJob)
+- delete pJob;
+- }
+- else
+- hrc = setError(E_FAIL, "%s", m->strWhyUnusable.c_str());
+- }
+- return hrc;
+-}
+-
+-
+-
+-
+-
+-DEFINE_EMPTY_CTOR_DTOR(ExtPack)
+-
+-/**
+- * Called by ComObjPtr::createObject when creating the object.
+- *
+- * Just initialize the basic object state, do the rest in initWithDir().
+- *
+- * @returns S_OK.
+- */
+-HRESULT ExtPack::FinalConstruct()
+-{
+- m = NULL;
+- return S_OK;
+-}
+-
+-/**
+- * Initializes the extension pack by reading its file.
+- *
+- * @returns COM status code.
+- * @param a_enmContext The context we're in.
+- * @param a_pszName The name of the extension pack. This is also the
+- * name of the subdirector under @a a_pszParentDir
+- * where the extension pack is installed.
+- * @param a_pszDir The extension pack directory name.
+- */
+-HRESULT ExtPack::initWithDir(VBOXEXTPACKCTX a_enmContext, const char *a_pszName, const char *a_pszDir)
+-{
+- AutoInitSpan autoInitSpan(this);
+- AssertReturn(autoInitSpan.isOk(), E_FAIL);
+-
+- static const VBOXEXTPACKHLP s_HlpTmpl =
+- {
+- /* u32Version = */ VBOXEXTPACKHLP_VERSION,
+- /* uVBoxFullVersion = */ VBOX_FULL_VERSION,
+- /* uVBoxVersionRevision = */ 0,
+- /* u32Padding = */ 0,
+- /* pszVBoxVersion = */ "",
+- /* pfnFindModule = */ ExtPack::hlpFindModule,
+- /* pfnGetFilePath = */ ExtPack::hlpGetFilePath,
+- /* pfnGetContext = */ ExtPack::hlpGetContext,
+- /* pfnReserved1 = */ ExtPack::hlpReservedN,
+- /* pfnReserved2 = */ ExtPack::hlpReservedN,
+- /* pfnReserved3 = */ ExtPack::hlpReservedN,
+- /* pfnReserved4 = */ ExtPack::hlpReservedN,
+- /* pfnReserved5 = */ ExtPack::hlpReservedN,
+- /* pfnReserved6 = */ ExtPack::hlpReservedN,
+- /* pfnReserved7 = */ ExtPack::hlpReservedN,
+- /* pfnReserved8 = */ ExtPack::hlpReservedN,
+- /* pfnReserved9 = */ ExtPack::hlpReservedN,
+- /* u32EndMarker = */ VBOXEXTPACKHLP_VERSION
+- };
+-
+- /*
+- * Allocate + initialize our private data.
+- */
+- m = new Data;
+- VBoxExtPackInitDesc(&m->Desc);
+- m->Desc.strName = a_pszName;
+- RT_ZERO(m->ObjInfoDesc);
+- m->fUsable = false;
+- m->strWhyUnusable = tr("ExtPack::init failed");
+- m->strExtPackPath = a_pszDir;
+- RT_ZERO(m->ObjInfoExtPack);
+- m->strMainModPath.setNull();
+- RT_ZERO(m->ObjInfoMainMod);
+- m->hMainMod = NIL_RTLDRMOD;
+- m->Hlp = s_HlpTmpl;
+- m->Hlp.pszVBoxVersion = RTBldCfgVersion();
+- m->Hlp.uVBoxInternalRevision = RTBldCfgRevision();
+- m->pThis = this;
+- m->pReg = NULL;
+- m->enmContext = a_enmContext;
+- m->fMadeReadyCall = false;
+-
+- /*
+- * Probe the extension pack (this code is shared with refresh()).
+- */
+- probeAndLoad();
+-
+- autoInitSpan.setSucceeded();
+- return S_OK;
+-}
+-
+-/**
+- * COM cruft.
+- */
+-void ExtPack::FinalRelease()
+-{
+- uninit();
+-}
+-
+-/**
+- * Do the actual cleanup.
+- */
+-void ExtPack::uninit()
+-{
+- /* Enclose the state transition Ready->InUninit->NotReady */
+- AutoUninitSpan autoUninitSpan(this);
+- if (!autoUninitSpan.uninitDone() && m != NULL)
+- {
+- if (m->hMainMod != NIL_RTLDRMOD)
+- {
+- AssertPtr(m->pReg);
+- if (m->pReg->pfnUnload != NULL)
+- m->pReg->pfnUnload(m->pReg);
+-
+- RTLdrClose(m->hMainMod);
+- m->hMainMod = NIL_RTLDRMOD;
+- m->pReg = NULL;
+- }
+-
+- VBoxExtPackFreeDesc(&m->Desc);
+-
+- delete m;
+- m = NULL;
+- }
+-}
+-
+-
+-/**
+- * Calls the installed hook.
+- *
+- * @returns true if we left the lock, false if we didn't.
+- * @param a_pVirtualBox The VirtualBox interface.
+- * @param a_pLock The write lock held by the caller.
+- * @param pErrInfo Where to return error information.
+- */
+-bool ExtPack::callInstalledHook(IVirtualBox *a_pVirtualBox, AutoWriteLock *a_pLock, PRTERRINFO pErrInfo)
+-{
+- if ( m != NULL
+- && m->hMainMod != NIL_RTLDRMOD)
+- {
+- if (m->pReg->pfnInstalled)
+- {
+- ComPtr<ExtPack> ptrSelfRef = this;
+- a_pLock->release();
+- pErrInfo->rc = m->pReg->pfnInstalled(m->pReg, a_pVirtualBox, pErrInfo);
+- a_pLock->acquire();
+- return true;
+- }
+- }
+- pErrInfo->rc = VINF_SUCCESS;
+- return false;
+-}
+-
+-/**
+- * Calls the uninstall hook and closes the module.
+- *
+- * @returns S_OK or COM error status with error information.
+- * @param a_pVirtualBox The VirtualBox interface.
+- * @param a_fForcedRemoval When set, we'll ignore complaints from the
+- * uninstall hook.
+- * @remarks The caller holds the manager's write lock, not released.
+- */
+-HRESULT ExtPack::callUninstallHookAndClose(IVirtualBox *a_pVirtualBox, bool a_fForcedRemoval)
+-{
+- HRESULT hrc = S_OK;
+-
+- if ( m != NULL
+- && m->hMainMod != NIL_RTLDRMOD)
+- {
+- if (m->pReg->pfnUninstall && !a_fForcedRemoval)
+- {
+- int vrc = m->pReg->pfnUninstall(m->pReg, a_pVirtualBox);
+- if (RT_FAILURE(vrc))
+- {
+- LogRel(("ExtPack pfnUninstall returned %Rrc for %s\n", vrc, m->Desc.strName.c_str()));
+- if (!a_fForcedRemoval)
+- hrc = setError(E_FAIL, tr("pfnUninstall returned %Rrc"), vrc);
+- }
+- }
+- if (SUCCEEDED(hrc))
+- {
+- RTLdrClose(m->hMainMod);
+- m->hMainMod = NIL_RTLDRMOD;
+- m->pReg = NULL;
+- }
+- }
+-
+- return hrc;
+-}
+-
+-/**
+- * Calls the pfnVirtualBoxReady hook.
+- *
+- * @returns true if we left the lock, false if we didn't.
+- * @param a_pVirtualBox The VirtualBox interface.
+- * @param a_pLock The write lock held by the caller.
+- */
+-bool ExtPack::callVirtualBoxReadyHook(IVirtualBox *a_pVirtualBox, AutoWriteLock *a_pLock)
+-{
+- if ( m != NULL
+- && m->fUsable
+- && !m->fMadeReadyCall)
+- {
+- m->fMadeReadyCall = true;
+- if (m->pReg->pfnVirtualBoxReady)
+- {
+- ComPtr<ExtPack> ptrSelfRef = this;
+- a_pLock->release();
+- m->pReg->pfnVirtualBoxReady(m->pReg, a_pVirtualBox);
+- a_pLock->acquire();
+- return true;
+- }
+- }
+- return false;
+-}
+-
+-/**
+- * Calls the pfnConsoleReady hook.
+- *
+- * @returns true if we left the lock, false if we didn't.
+- * @param a_pConsole The Console interface.
+- * @param a_pLock The write lock held by the caller.
+- */
+-bool ExtPack::callConsoleReadyHook(IConsole *a_pConsole, AutoWriteLock *a_pLock)
+-{
+- if ( m != NULL
+- && m->fUsable
+- && !m->fMadeReadyCall)
+- {
+- m->fMadeReadyCall = true;
+- if (m->pReg->pfnConsoleReady)
+- {
+- ComPtr<ExtPack> ptrSelfRef = this;
+- a_pLock->release();
+- m->pReg->pfnConsoleReady(m->pReg, a_pConsole);
+- a_pLock->acquire();
+- return true;
+- }
+- }
+- return false;
+-}
+-
+-/**
+- * Calls the pfnVMCreate hook.
+- *
+- * @returns true if we left the lock, false if we didn't.
+- * @param a_pVirtualBox The VirtualBox interface.
+- * @param a_pMachine The machine interface of the new VM.
+- * @param a_pLock The write lock held by the caller.
+- */
+-bool ExtPack::callVmCreatedHook(IVirtualBox *a_pVirtualBox, IMachine *a_pMachine, AutoWriteLock *a_pLock)
+-{
+- if ( m != NULL
+- && m->fUsable)
+- {
+- if (m->pReg->pfnVMCreated)
+- {
+- ComPtr<ExtPack> ptrSelfRef = this;
+- a_pLock->release();
+- m->pReg->pfnVMCreated(m->pReg, a_pVirtualBox, a_pMachine);
+- a_pLock->acquire();
+- return true;
+- }
+- }
+- return false;
+-}
+-
+-/**
+- * Calls the pfnVMConfigureVMM hook.
+- *
+- * @returns true if we left the lock, false if we didn't.
+- * @param a_pConsole The console interface.
+- * @param a_pVM The VM handle.
+- * @param a_pLock The write lock held by the caller.
+- * @param a_pvrc Where to return the status code of the
+- * callback. This is always set. LogRel is
+- * called on if a failure status is returned.
+- */
+-bool ExtPack::callVmConfigureVmmHook(IConsole *a_pConsole, PVM a_pVM, AutoWriteLock *a_pLock, int *a_pvrc)
+-{
+- *a_pvrc = VINF_SUCCESS;
+- if ( m != NULL
+- && m->fUsable)
+- {
+- if (m->pReg->pfnVMConfigureVMM)
+- {
+- ComPtr<ExtPack> ptrSelfRef = this;
+- a_pLock->release();
+- int vrc = m->pReg->pfnVMConfigureVMM(m->pReg, a_pConsole, a_pVM);
+- *a_pvrc = vrc;
+- a_pLock->acquire();
+- if (RT_FAILURE(vrc))
+- LogRel(("ExtPack pfnVMConfigureVMM returned %Rrc for %s\n", vrc, m->Desc.strName.c_str()));
+- return true;
+- }
+- }
+- return false;
+-}
+-
+-/**
+- * Calls the pfnVMPowerOn hook.
+- *
+- * @returns true if we left the lock, false if we didn't.
+- * @param a_pConsole The console interface.
+- * @param a_pVM The VM handle.
+- * @param a_pLock The write lock held by the caller.
+- * @param a_pvrc Where to return the status code of the
+- * callback. This is always set. LogRel is
+- * called on if a failure status is returned.
+- */
+-bool ExtPack::callVmPowerOnHook(IConsole *a_pConsole, PVM a_pVM, AutoWriteLock *a_pLock, int *a_pvrc)
+-{
+- *a_pvrc = VINF_SUCCESS;
+- if ( m != NULL
+- && m->fUsable)
+- {
+- if (m->pReg->pfnVMPowerOn)
+- {
+- ComPtr<ExtPack> ptrSelfRef = this;
+- a_pLock->release();
+- int vrc = m->pReg->pfnVMPowerOn(m->pReg, a_pConsole, a_pVM);
+- *a_pvrc = vrc;
+- a_pLock->acquire();
+- if (RT_FAILURE(vrc))
+- LogRel(("ExtPack pfnVMPowerOn returned %Rrc for %s\n", vrc, m->Desc.strName.c_str()));
+- return true;
+- }
+- }
+- return false;
+-}
+-
+-/**
+- * Calls the pfnVMPowerOff hook.
+- *
+- * @returns true if we left the lock, false if we didn't.
+- * @param a_pConsole The console interface.
+- * @param a_pVM The VM handle.
+- * @param a_pLock The write lock held by the caller.
+- */
+-bool ExtPack::callVmPowerOffHook(IConsole *a_pConsole, PVM a_pVM, AutoWriteLock *a_pLock)
+-{
+- if ( m != NULL
+- && m->fUsable)
+- {
+- if (m->pReg->pfnVMPowerOff)
+- {
+- ComPtr<ExtPack> ptrSelfRef = this;
+- a_pLock->release();
+- m->pReg->pfnVMPowerOff(m->pReg, a_pConsole, a_pVM);
+- a_pLock->acquire();
+- return true;
+- }
+- }
+- return false;
+-}
+-
+-/**
+- * Check if the extension pack is usable and has an VRDE module.
+- *
+- * @returns S_OK or COM error status with error information.
+- *
+- * @remarks Caller holds the extension manager lock for reading, no locking
+- * necessary.
+- */
+-HRESULT ExtPack::checkVrde(void)
+-{
+- HRESULT hrc;
+- if ( m != NULL
+- && m->fUsable)
+- {
+- if (m->Desc.strVrdeModule.isNotEmpty())
+- hrc = S_OK;
+- else
+- hrc = setError(E_FAIL, tr("The extension pack '%s' does not include a VRDE module"), m->Desc.strName.c_str());
+- }
+- else
+- hrc = setError(E_FAIL, tr("%s"), m->strWhyUnusable.c_str());
+- return hrc;
+-}
+-
+-/**
+- * Same as checkVrde(), except that it also resolves the path to the module.
+- *
+- * @returns S_OK or COM error status with error information.
+- * @param a_pstrVrdeLibrary Where to return the path on success.
+- *
+- * @remarks Caller holds the extension manager lock for reading, no locking
+- * necessary.
+- */
+-HRESULT ExtPack::getVrdpLibraryName(Utf8Str *a_pstrVrdeLibrary)
+-{
+- HRESULT hrc = checkVrde();
+- if (SUCCEEDED(hrc))
+- {
+- if (findModule(m->Desc.strVrdeModule.c_str(), NULL, VBOXEXTPACKMODKIND_R3,
+- a_pstrVrdeLibrary, NULL /*a_pfNative*/, NULL /*a_pObjInfo*/))
+- hrc = S_OK;
+- else
+- hrc = setError(E_FAIL, tr("Failed to locate the VRDE module '%s' in extension pack '%s'"),
+- m->Desc.strVrdeModule.c_str(), m->Desc.strName.c_str());
+- }
+- return hrc;
+-}
+-
+-/**
+- * Check if this extension pack wishes to be the default VRDE provider.
+- *
+- * @returns @c true if it wants to and it is in a usable state, otherwise
+- * @c false.
+- *
+- * @remarks Caller holds the extension manager lock for reading, no locking
+- * necessary.
+- */
+-bool ExtPack::wantsToBeDefaultVrde(void) const
+-{
+- return m->fUsable
+- && m->Desc.strVrdeModule.isNotEmpty();
+-}
+-
+-/**
+- * Refreshes the extension pack state.
+- *
+- * This is called by the manager so that the on disk changes are picked up.
+- *
+- * @returns S_OK or COM error status with error information.
+- *
+- * @param a_pfCanDelete Optional can-delete-this-object output indicator.
+- *
+- * @remarks Caller holds the extension manager lock for writing.
+- * @remarks Only called in VBoxSVC.
+- */
+-HRESULT ExtPack::refresh(bool *a_pfCanDelete)
+-{
+- if (a_pfCanDelete)
+- *a_pfCanDelete = false;
+-
+- AutoWriteLock autoLock(this COMMA_LOCKVAL_SRC_POS); /* for the COMGETTERs */
+-
+- /*
+- * Has the module been deleted?
+- */
+- RTFSOBJINFO ObjInfoExtPack;
+- int vrc = RTPathQueryInfoEx(m->strExtPackPath.c_str(), &ObjInfoExtPack, RTFSOBJATTRADD_UNIX, RTPATH_F_ON_LINK);
+- if ( RT_FAILURE(vrc)
+- || !RTFS_IS_DIRECTORY(ObjInfoExtPack.Attr.fMode))
+- {
+- if (a_pfCanDelete)
+- *a_pfCanDelete = true;
+- return S_OK;
+- }
+-
+- /*
+- * We've got a directory, so try query file system object info for the
+- * files we are interested in as well.
+- */
+- RTFSOBJINFO ObjInfoDesc;
+- char szDescFilePath[RTPATH_MAX];
+- vrc = RTPathJoin(szDescFilePath, sizeof(szDescFilePath), m->strExtPackPath.c_str(), VBOX_EXTPACK_DESCRIPTION_NAME);
+- if (RT_SUCCESS(vrc))
+- vrc = RTPathQueryInfoEx(szDescFilePath, &ObjInfoDesc, RTFSOBJATTRADD_UNIX, RTPATH_F_ON_LINK);
+- if (RT_FAILURE(vrc))
+- RT_ZERO(ObjInfoDesc);
+-
+- RTFSOBJINFO ObjInfoMainMod;
+- if (m->strMainModPath.isNotEmpty())
+- vrc = RTPathQueryInfoEx(m->strMainModPath.c_str(), &ObjInfoMainMod, RTFSOBJATTRADD_UNIX, RTPATH_F_ON_LINK);
+- if (m->strMainModPath.isEmpty() || RT_FAILURE(vrc))
+- RT_ZERO(ObjInfoMainMod);
+-
+- /*
+- * If we have a usable module already, just verify that things haven't
+- * changed since we loaded it.
+- */
+- if (m->fUsable)
+- {
+- if (m->hMainMod == NIL_RTLDRMOD)
+- probeAndLoad();
+- else if ( !objinfoIsEqual(&ObjInfoDesc, &m->ObjInfoDesc)
+- || !objinfoIsEqual(&ObjInfoMainMod, &m->ObjInfoMainMod)
+- || !objinfoIsEqual(&ObjInfoExtPack, &m->ObjInfoExtPack) )
+- {
+- /** @todo not important, so it can wait. */
+- }
+- }
+- /*
+- * Ok, it is currently not usable. If anything has changed since last time
+- * reprobe the extension pack.
+- */
+- else if ( !objinfoIsEqual(&ObjInfoDesc, &m->ObjInfoDesc)
+- || !objinfoIsEqual(&ObjInfoMainMod, &m->ObjInfoMainMod)
+- || !objinfoIsEqual(&ObjInfoExtPack, &m->ObjInfoExtPack) )
+- probeAndLoad();
+-
+- return S_OK;
+-}
+-
+-/**
+- * Probes the extension pack, loading the main dll and calling its registration
+- * entry point.
+- *
+- * This updates the state accordingly, the strWhyUnusable and fUnusable members
+- * being the most important ones.
+- */
+-void ExtPack::probeAndLoad(void)
+-{
+- m->fUsable = false;
+- m->fMadeReadyCall = false;
+-
+- /*
+- * Query the file system info for the extension pack directory. This and
+- * all other file system info we save is for the benefit of refresh().
+- */
+- int vrc = RTPathQueryInfoEx(m->strExtPackPath.c_str(), &m->ObjInfoExtPack, RTFSOBJATTRADD_UNIX, RTPATH_F_ON_LINK);
+- if (RT_FAILURE(vrc))
+- {
+- m->strWhyUnusable.printf(tr("RTPathQueryInfoEx on '%s' failed: %Rrc"), m->strExtPackPath.c_str(), vrc);
+- return;
+- }
+- if (!RTFS_IS_DIRECTORY(m->ObjInfoExtPack.Attr.fMode))
+- {
+- if (RTFS_IS_SYMLINK(m->ObjInfoExtPack.Attr.fMode))
+- m->strWhyUnusable.printf(tr("'%s' is a symbolic link, this is not allowed"), m->strExtPackPath.c_str(), vrc);
+- else if (RTFS_IS_FILE(m->ObjInfoExtPack.Attr.fMode))
+- m->strWhyUnusable.printf(tr("'%s' is a symbolic file, not a directory"), m->strExtPackPath.c_str(), vrc);
+- else
+- m->strWhyUnusable.printf(tr("'%s' is not a directory (fMode=%#x)"), m->strExtPackPath.c_str(), m->ObjInfoExtPack.Attr.fMode);
+- return;
+- }
+-
+- RTERRINFOSTATIC ErrInfo;
+- RTErrInfoInitStatic(&ErrInfo);
+- vrc = SUPR3HardenedVerifyDir(m->strExtPackPath.c_str(), true /*fRecursive*/, true /*fCheckFiles*/, &ErrInfo.Core);
+- if (RT_FAILURE(vrc))
+- {
+- m->strWhyUnusable.printf(tr("%s (rc=%Rrc)"), ErrInfo.Core.pszMsg, vrc);
+- return;
+- }
+-
+- /*
+- * Read the description file.
+- */
+- RTCString strSavedName(m->Desc.strName);
+- RTCString *pStrLoadErr = VBoxExtPackLoadDesc(m->strExtPackPath.c_str(), &m->Desc, &m->ObjInfoDesc);
+- if (pStrLoadErr != NULL)
+- {
+- m->strWhyUnusable.printf(tr("Failed to load '%s/%s': %s"),
+- m->strExtPackPath.c_str(), VBOX_EXTPACK_DESCRIPTION_NAME, pStrLoadErr->c_str());
+- m->Desc.strName = strSavedName;
+- delete pStrLoadErr;
+- return;
+- }
+-
+- /*
+- * Make sure the XML name and directory matches.
+- */
+- if (!m->Desc.strName.equalsIgnoreCase(strSavedName))
+- {
+- m->strWhyUnusable.printf(tr("The description name ('%s') and directory name ('%s') does not match"),
+- m->Desc.strName.c_str(), strSavedName.c_str());
+- m->Desc.strName = strSavedName;
+- return;
+- }
+-
+- /*
+- * Load the main DLL and call the predefined entry point.
+- */
+- bool fIsNative;
+- if (!findModule(m->Desc.strMainModule.c_str(), NULL /* default extension */, VBOXEXTPACKMODKIND_R3,
+- &m->strMainModPath, &fIsNative, &m->ObjInfoMainMod))
+- {
+- m->strWhyUnusable.printf(tr("Failed to locate the main module ('%s')"), m->Desc.strMainModule.c_str());
+- return;
+- }
+-
+- vrc = SUPR3HardenedVerifyPlugIn(m->strMainModPath.c_str(), &ErrInfo.Core);
+- if (RT_FAILURE(vrc))
+- {
+- m->strWhyUnusable.printf(tr("%s"), ErrInfo.Core.pszMsg);
+- return;
+- }
+-
+- if (fIsNative)
+- {
+- vrc = SUPR3HardenedLdrLoadPlugIn(m->strMainModPath.c_str(), &m->hMainMod, &ErrInfo.Core);
+- if (RT_FAILURE(vrc))
+- {
+- m->hMainMod = NIL_RTLDRMOD;
+- m->strWhyUnusable.printf(tr("Failed to load the main module ('%s'): %Rrc - %s"),
+- m->strMainModPath.c_str(), vrc, ErrInfo.Core.pszMsg);
+- return;
+- }
+- }
+- else
+- {
+- m->strWhyUnusable.printf(tr("Only native main modules are currently supported"));
+- return;
+- }
+-
+- /*
+- * Resolve the predefined entry point.
+- */
+- PFNVBOXEXTPACKREGISTER pfnRegistration;
+- vrc = RTLdrGetSymbol(m->hMainMod, VBOX_EXTPACK_MAIN_MOD_ENTRY_POINT, (void **)&pfnRegistration);
+- if (RT_SUCCESS(vrc))
+- {
+- RTErrInfoClear(&ErrInfo.Core);
+- vrc = pfnRegistration(&m->Hlp, &m->pReg, &ErrInfo.Core);
+- if ( RT_SUCCESS(vrc)
+- && !RTErrInfoIsSet(&ErrInfo.Core)
+- && VALID_PTR(m->pReg))
+- {
+- if ( VBOXEXTPACK_IS_MAJOR_VER_EQUAL(m->pReg->u32Version, VBOXEXTPACKREG_VERSION)
+- && m->pReg->u32EndMarker == m->pReg->u32Version)
+- {
+- if ( (!m->pReg->pfnInstalled || RT_VALID_PTR(m->pReg->pfnInstalled))
+- && (!m->pReg->pfnUninstall || RT_VALID_PTR(m->pReg->pfnUninstall))
+- && (!m->pReg->pfnVirtualBoxReady || RT_VALID_PTR(m->pReg->pfnVirtualBoxReady))
+- && (!m->pReg->pfnConsoleReady || RT_VALID_PTR(m->pReg->pfnConsoleReady))
+- && (!m->pReg->pfnUnload || RT_VALID_PTR(m->pReg->pfnUnload))
+- && (!m->pReg->pfnVMCreated || RT_VALID_PTR(m->pReg->pfnVMCreated))
+- && (!m->pReg->pfnVMConfigureVMM || RT_VALID_PTR(m->pReg->pfnVMConfigureVMM))
+- && (!m->pReg->pfnVMPowerOn || RT_VALID_PTR(m->pReg->pfnVMPowerOn))
+- && (!m->pReg->pfnVMPowerOff || RT_VALID_PTR(m->pReg->pfnVMPowerOff))
+- && (!m->pReg->pfnQueryObject || RT_VALID_PTR(m->pReg->pfnQueryObject))
+- )
+- {
+- /*
+- * We're good!
+- */
+- m->fUsable = true;
+- m->strWhyUnusable.setNull();
+- return;
+- }
+-
+- m->strWhyUnusable = tr("The registration structure contains on or more invalid function pointers");
+- }
+- else
+- m->strWhyUnusable.printf(tr("Unsupported registration structure version %u.%u"),
+- RT_HIWORD(m->pReg->u32Version), RT_LOWORD(m->pReg->u32Version));
+- }
+- else
+- m->strWhyUnusable.printf(tr("%s returned %Rrc, pReg=%p ErrInfo='%s'"),
+- VBOX_EXTPACK_MAIN_MOD_ENTRY_POINT, vrc, m->pReg, ErrInfo.Core.pszMsg);
+- m->pReg = NULL;
+- }
+- else
+- m->strWhyUnusable.printf(tr("Failed to resolve exported symbol '%s' in the main module: %Rrc"),
+- VBOX_EXTPACK_MAIN_MOD_ENTRY_POINT, vrc);
+-
+- RTLdrClose(m->hMainMod);
+- m->hMainMod = NIL_RTLDRMOD;
+-}
+-
+-/**
+- * Finds a module.
+- *
+- * @returns true if found, false if not.
+- * @param a_pszName The module base name (no extension).
+- * @param a_pszExt The extension. If NULL we use default
+- * extensions.
+- * @param a_enmKind The kind of module to locate.
+- * @param a_pStrFound Where to return the path to the module we've
+- * found.
+- * @param a_pfNative Where to return whether this is a native module
+- * or an agnostic one. Optional.
+- * @param a_pObjInfo Where to return the file system object info for
+- * the module. Optional.
+- */
+-bool ExtPack::findModule(const char *a_pszName, const char *a_pszExt, VBOXEXTPACKMODKIND a_enmKind,
+- Utf8Str *a_pStrFound, bool *a_pfNative, PRTFSOBJINFO a_pObjInfo) const
+-{
+- /*
+- * Try the native path first.
+- */
+- char szPath[RTPATH_MAX];
+- int vrc = RTPathJoin(szPath, sizeof(szPath), m->strExtPackPath.c_str(), RTBldCfgTargetDotArch());
+- AssertLogRelRCReturn(vrc, false);
+- vrc = RTPathAppend(szPath, sizeof(szPath), a_pszName);
+- AssertLogRelRCReturn(vrc, false);
+- if (!a_pszExt)
+- {
+- const char *pszDefExt;
+- switch (a_enmKind)
+- {
+- case VBOXEXTPACKMODKIND_RC: pszDefExt = ".rc"; break;
+- case VBOXEXTPACKMODKIND_R0: pszDefExt = ".r0"; break;
+- case VBOXEXTPACKMODKIND_R3: pszDefExt = RTLdrGetSuff(); break;
+- default:
+- AssertFailedReturn(false);
+- }
+- vrc = RTStrCat(szPath, sizeof(szPath), pszDefExt);
+- AssertLogRelRCReturn(vrc, false);
+- }
+-
+- RTFSOBJINFO ObjInfo;
+- if (!a_pObjInfo)
+- a_pObjInfo = &ObjInfo;
+- vrc = RTPathQueryInfo(szPath, a_pObjInfo, RTFSOBJATTRADD_UNIX);
+- if (RT_SUCCESS(vrc) && RTFS_IS_FILE(a_pObjInfo->Attr.fMode))
+- {
+- if (a_pfNative)
+- *a_pfNative = true;
+- *a_pStrFound = szPath;
+- return true;
+- }
+-
+- /*
+- * Try the platform agnostic modules.
+- */
+- /* gcc.x86/module.rel */
+- char szSubDir[32];
+- RTStrPrintf(szSubDir, sizeof(szSubDir), "%s.%s", RTBldCfgCompiler(), RTBldCfgTargetArch());
+- vrc = RTPathJoin(szPath, sizeof(szPath), m->strExtPackPath.c_str(), szSubDir);
+- AssertLogRelRCReturn(vrc, false);
+- vrc = RTPathAppend(szPath, sizeof(szPath), a_pszName);
+- AssertLogRelRCReturn(vrc, false);
+- if (!a_pszExt)
+- {
+- vrc = RTStrCat(szPath, sizeof(szPath), ".rel");
+- AssertLogRelRCReturn(vrc, false);
+- }
+- vrc = RTPathQueryInfo(szPath, a_pObjInfo, RTFSOBJATTRADD_UNIX);
+- if (RT_SUCCESS(vrc) && RTFS_IS_FILE(a_pObjInfo->Attr.fMode))
+- {
+- if (a_pfNative)
+- *a_pfNative = false;
+- *a_pStrFound = szPath;
+- return true;
+- }
+-
+- /* x86/module.rel */
+- vrc = RTPathJoin(szPath, sizeof(szPath), m->strExtPackPath.c_str(), RTBldCfgTargetArch());
+- AssertLogRelRCReturn(vrc, false);
+- vrc = RTPathAppend(szPath, sizeof(szPath), a_pszName);
+- AssertLogRelRCReturn(vrc, false);
+- if (!a_pszExt)
+- {
+- vrc = RTStrCat(szPath, sizeof(szPath), ".rel");
+- AssertLogRelRCReturn(vrc, false);
+- }
+- vrc = RTPathQueryInfo(szPath, a_pObjInfo, RTFSOBJATTRADD_UNIX);
+- if (RT_SUCCESS(vrc) && RTFS_IS_FILE(a_pObjInfo->Attr.fMode))
+- {
+- if (a_pfNative)
+- *a_pfNative = false;
+- *a_pStrFound = szPath;
+- return true;
+- }
+-
+- return false;
+-}
+-
+-/**
+- * Compares two file system object info structures.
+- *
+- * @returns true if equal, false if not.
+- * @param pObjInfo1 The first.
+- * @param pObjInfo2 The second.
+- * @todo IPRT should do this, really.
+- */
+-/* static */ bool ExtPack::objinfoIsEqual(PCRTFSOBJINFO pObjInfo1, PCRTFSOBJINFO pObjInfo2)
+-{
+- if (!RTTimeSpecIsEqual(&pObjInfo1->ModificationTime, &pObjInfo2->ModificationTime))
+- return false;
+- if (!RTTimeSpecIsEqual(&pObjInfo1->ChangeTime, &pObjInfo2->ChangeTime))
+- return false;
+- if (!RTTimeSpecIsEqual(&pObjInfo1->BirthTime, &pObjInfo2->BirthTime))
+- return false;
+- if (pObjInfo1->cbObject != pObjInfo2->cbObject)
+- return false;
+- if (pObjInfo1->Attr.fMode != pObjInfo2->Attr.fMode)
+- return false;
+- if (pObjInfo1->Attr.enmAdditional == pObjInfo2->Attr.enmAdditional)
+- {
+- switch (pObjInfo1->Attr.enmAdditional)
+- {
+- case RTFSOBJATTRADD_UNIX:
+- if (pObjInfo1->Attr.u.Unix.uid != pObjInfo2->Attr.u.Unix.uid)
+- return false;
+- if (pObjInfo1->Attr.u.Unix.gid != pObjInfo2->Attr.u.Unix.gid)
+- return false;
+- if (pObjInfo1->Attr.u.Unix.INodeIdDevice != pObjInfo2->Attr.u.Unix.INodeIdDevice)
+- return false;
+- if (pObjInfo1->Attr.u.Unix.INodeId != pObjInfo2->Attr.u.Unix.INodeId)
+- return false;
+- if (pObjInfo1->Attr.u.Unix.GenerationId != pObjInfo2->Attr.u.Unix.GenerationId)
+- return false;
+- break;
+- default:
+- break;
+- }
+- }
+- return true;
+-}
+-
+-
+-/**
+- * @interface_method_impl{VBOXEXTPACKHLP,pfnFindModule}
+- */
+-/*static*/ DECLCALLBACK(int)
+-ExtPack::hlpFindModule(PCVBOXEXTPACKHLP pHlp, const char *pszName, const char *pszExt, VBOXEXTPACKMODKIND enmKind,
+- char *pszFound, size_t cbFound, bool *pfNative)
+-{
+- /*
+- * Validate the input and get our bearings.
+- */
+- AssertPtrReturn(pszName, VERR_INVALID_POINTER);
+- AssertPtrNullReturn(pszExt, VERR_INVALID_POINTER);
+- AssertPtrReturn(pszFound, VERR_INVALID_POINTER);
+- AssertPtrNullReturn(pfNative, VERR_INVALID_POINTER);
+- AssertReturn(enmKind > VBOXEXTPACKMODKIND_INVALID && enmKind < VBOXEXTPACKMODKIND_END, VERR_INVALID_PARAMETER);
+-
+- AssertPtrReturn(pHlp, VERR_INVALID_POINTER);
+- AssertReturn(pHlp->u32Version == VBOXEXTPACKHLP_VERSION, VERR_INVALID_POINTER);
+- ExtPack::Data *m = RT_FROM_CPP_MEMBER(pHlp, Data, Hlp);
+- AssertPtrReturn(m, VERR_INVALID_POINTER);
+- ExtPack *pThis = m->pThis;
+- AssertPtrReturn(pThis, VERR_INVALID_POINTER);
+-
+- /*
+- * This is just a wrapper around findModule.
+- */
+- Utf8Str strFound;
+- if (pThis->findModule(pszName, pszExt, enmKind, &strFound, pfNative, NULL))
+- return RTStrCopy(pszFound, cbFound, strFound.c_str());
+- return VERR_FILE_NOT_FOUND;
+-}
+-
+-/*static*/ DECLCALLBACK(int)
+-ExtPack::hlpGetFilePath(PCVBOXEXTPACKHLP pHlp, const char *pszFilename, char *pszPath, size_t cbPath)
+-{
+- /*
+- * Validate the input and get our bearings.
+- */
+- AssertPtrReturn(pszFilename, VERR_INVALID_POINTER);
+- AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
+- AssertReturn(cbPath > 0, VERR_BUFFER_OVERFLOW);
+-
+- AssertPtrReturn(pHlp, VERR_INVALID_POINTER);
+- AssertReturn(pHlp->u32Version == VBOXEXTPACKHLP_VERSION, VERR_INVALID_POINTER);
+- ExtPack::Data *m = RT_FROM_CPP_MEMBER(pHlp, Data, Hlp);
+- AssertPtrReturn(m, VERR_INVALID_POINTER);
+- ExtPack *pThis = m->pThis;
+- AssertPtrReturn(pThis, VERR_INVALID_POINTER);
+-
+- /*
+- * This is a simple RTPathJoin, no checking if things exists or anything.
+- */
+- int vrc = RTPathJoin(pszPath, cbPath, pThis->m->strExtPackPath.c_str(), pszFilename);
+- if (RT_FAILURE(vrc))
+- RT_BZERO(pszPath, cbPath);
+- return vrc;
+-}
+-
+-/*static*/ DECLCALLBACK(VBOXEXTPACKCTX)
+-ExtPack::hlpGetContext(PCVBOXEXTPACKHLP pHlp)
+-{
+- /*
+- * Validate the input and get our bearings.
+- */
+- AssertPtrReturn(pHlp, VBOXEXTPACKCTX_INVALID);
+- AssertReturn(pHlp->u32Version == VBOXEXTPACKHLP_VERSION, VBOXEXTPACKCTX_INVALID);
+- ExtPack::Data *m = RT_FROM_CPP_MEMBER(pHlp, Data, Hlp);
+- AssertPtrReturn(m, VBOXEXTPACKCTX_INVALID);
+- ExtPack *pThis = m->pThis;
+- AssertPtrReturn(pThis, VBOXEXTPACKCTX_INVALID);
+-
+- return pThis->m->enmContext;
+-}
+-
+-/*static*/ DECLCALLBACK(int)
+-ExtPack::hlpReservedN(PCVBOXEXTPACKHLP pHlp)
+-{
+- /*
+- * Validate the input and get our bearings.
+- */
+- AssertPtrReturn(pHlp, VERR_INVALID_POINTER);
+- AssertReturn(pHlp->u32Version == VBOXEXTPACKHLP_VERSION, VERR_INVALID_POINTER);
+- ExtPack::Data *m = RT_FROM_CPP_MEMBER(pHlp, Data, Hlp);
+- AssertPtrReturn(m, VERR_INVALID_POINTER);
+- ExtPack *pThis = m->pThis;
+- AssertPtrReturn(pThis, VERR_INVALID_POINTER);
+-
+- return VERR_NOT_IMPLEMENTED;
+-}
+-
+-
+-
+-
+-
+-STDMETHODIMP ExtPack::COMGETTER(Name)(BSTR *a_pbstrName)
+-{
+- CheckComArgOutPointerValid(a_pbstrName);
+-
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (SUCCEEDED(hrc))
+- {
+- Bstr str(m->Desc.strName);
+- str.cloneTo(a_pbstrName);
+- }
+- return hrc;
+-}
+-
+-STDMETHODIMP ExtPack::COMGETTER(Description)(BSTR *a_pbstrDescription)
+-{
+- CheckComArgOutPointerValid(a_pbstrDescription);
+-
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (SUCCEEDED(hrc))
+- {
+- Bstr str(m->Desc.strDescription);
+- str.cloneTo(a_pbstrDescription);
+- }
+- return hrc;
+-}
+-
+-STDMETHODIMP ExtPack::COMGETTER(Version)(BSTR *a_pbstrVersion)
+-{
+- CheckComArgOutPointerValid(a_pbstrVersion);
+-
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (SUCCEEDED(hrc))
+- {
+- /* HACK ALERT: This is for easing backporting to 4.1. The edition stuff
+- will be changed into a separate */
+- if (m->Desc.strEdition.isEmpty())
+- {
+- Bstr str(m->Desc.strVersion);
+- str.cloneTo(a_pbstrVersion);
+- }
+- else
+- {
+- RTCString strHack(m->Desc.strVersion);
+- strHack.append('-');
+- strHack.append(m->Desc.strEdition);
+-
+- Bstr str(strHack);
+- str.cloneTo(a_pbstrVersion);
+- }
+- }
+- return hrc;
+-}
+-
+-STDMETHODIMP ExtPack::COMGETTER(Revision)(ULONG *a_puRevision)
+-{
+- CheckComArgOutPointerValid(a_puRevision);
+-
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (SUCCEEDED(hrc))
+- *a_puRevision = m->Desc.uRevision;
+- return hrc;
+-}
+-
+-STDMETHODIMP ExtPack::COMGETTER(VRDEModule)(BSTR *a_pbstrVrdeModule)
+-{
+- CheckComArgOutPointerValid(a_pbstrVrdeModule);
+-
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (SUCCEEDED(hrc))
+- {
+- Bstr str(m->Desc.strVrdeModule);
+- str.cloneTo(a_pbstrVrdeModule);
+- }
+- return hrc;
+-}
+-
+-STDMETHODIMP ExtPack::COMGETTER(PlugIns)(ComSafeArrayOut(IExtPackPlugIn *, a_paPlugIns))
+-{
+- /** @todo implement plug-ins. */
+-#ifdef VBOX_WITH_XPCOM
+- NOREF(a_paPlugIns);
+- NOREF(a_paPlugInsSize);
+-#endif
+- ReturnComNotImplemented();
+-}
+-
+-STDMETHODIMP ExtPack::COMGETTER(Usable)(BOOL *a_pfUsable)
+-{
+- CheckComArgOutPointerValid(a_pfUsable);
+-
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (SUCCEEDED(hrc))
+- *a_pfUsable = m->fUsable;
+- return hrc;
+-}
+-
+-STDMETHODIMP ExtPack::COMGETTER(WhyUnusable)(BSTR *a_pbstrWhy)
+-{
+- CheckComArgOutPointerValid(a_pbstrWhy);
+-
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (SUCCEEDED(hrc))
+- m->strWhyUnusable.cloneTo(a_pbstrWhy);
+- return hrc;
+-}
+-
+-STDMETHODIMP ExtPack::COMGETTER(ShowLicense)(BOOL *a_pfShowIt)
+-{
+- CheckComArgOutPointerValid(a_pfShowIt);
+-
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (SUCCEEDED(hrc))
+- *a_pfShowIt = m->Desc.fShowLicense;
+- return hrc;
+-}
+-
+-STDMETHODIMP ExtPack::COMGETTER(License)(BSTR *a_pbstrHtmlLicense)
+-{
+- Bstr bstrHtml("html");
+- return QueryLicense(Bstr::Empty.raw(), Bstr::Empty.raw(), bstrHtml.raw(), a_pbstrHtmlLicense);
+-}
+-
+-STDMETHODIMP ExtPack::QueryLicense(IN_BSTR a_bstrPreferredLocale, IN_BSTR a_bstrPreferredLanguage, IN_BSTR a_bstrFormat,
+- BSTR *a_pbstrLicense)
+-{
+- /*
+- * Validate input.
+- */
+- CheckComArgOutPointerValid(a_pbstrLicense);
+- CheckComArgNotNull(a_bstrPreferredLocale);
+- CheckComArgNotNull(a_bstrPreferredLanguage);
+- CheckComArgNotNull(a_bstrFormat);
+-
+- Utf8Str strPreferredLocale(a_bstrPreferredLocale);
+- if (strPreferredLocale.length() != 2 && strPreferredLocale.length() != 0)
+- return setError(E_FAIL, tr("The preferred locale is a two character string or empty."));
+-
+- Utf8Str strPreferredLanguage(a_bstrPreferredLanguage);
+- if (strPreferredLanguage.length() != 2 && strPreferredLanguage.length() != 0)
+- return setError(E_FAIL, tr("The preferred lanuage is a two character string or empty."));
+-
+- Utf8Str strFormat(a_bstrFormat);
+- if ( !strFormat.equals("html")
+- && !strFormat.equals("rtf")
+- && !strFormat.equals("txt"))
+- return setError(E_FAIL, tr("The license format can only have the values 'html', 'rtf' and 'txt'."));
+-
+- /*
+- * Combine the options to form a file name before locking down anything.
+- */
+- char szName[sizeof(VBOX_EXTPACK_LICENSE_NAME_PREFIX "-de_DE.html") + 2];
+- if (strPreferredLocale.isNotEmpty() && strPreferredLanguage.isNotEmpty())
+- RTStrPrintf(szName, sizeof(szName), VBOX_EXTPACK_LICENSE_NAME_PREFIX "-%s_%s.%s",
+- strPreferredLocale.c_str(), strPreferredLanguage.c_str(), strFormat.c_str());
+- else if (strPreferredLocale.isNotEmpty())
+- RTStrPrintf(szName, sizeof(szName), VBOX_EXTPACK_LICENSE_NAME_PREFIX "-%s.%s", strPreferredLocale.c_str(), strFormat.c_str());
+- else if (strPreferredLanguage.isNotEmpty())
+- RTStrPrintf(szName, sizeof(szName), VBOX_EXTPACK_LICENSE_NAME_PREFIX "-_%s.%s", strPreferredLocale.c_str(), strFormat.c_str());
+- else
+- RTStrPrintf(szName, sizeof(szName), VBOX_EXTPACK_LICENSE_NAME_PREFIX ".%s", strFormat.c_str());
+-
+- /*
+- * Effectuate the query.
+- */
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (SUCCEEDED(hrc))
+- {
+- AutoReadLock autoLock(this COMMA_LOCKVAL_SRC_POS); /* paranoia */
+-
+- if (!m->fUsable)
+- hrc = setError(E_FAIL, tr("%s"), m->strWhyUnusable.c_str());
+- else
+- {
+- char szPath[RTPATH_MAX];
+- int vrc = RTPathJoin(szPath, sizeof(szPath), m->strExtPackPath.c_str(), szName);
+- if (RT_SUCCESS(vrc))
+- {
+- void *pvFile;
+- size_t cbFile;
+- vrc = RTFileReadAllEx(szPath, 0, RTFOFF_MAX, RTFILE_RDALL_O_DENY_READ, &pvFile, &cbFile);
+- if (RT_SUCCESS(vrc))
+- {
+- Bstr bstrLicense((const char *)pvFile, cbFile);
+- if (bstrLicense.isNotEmpty())
+- {
+- bstrLicense.detachTo(a_pbstrLicense);
+- hrc = S_OK;
+- }
+- else
+- hrc = setError(VBOX_E_IPRT_ERROR, tr("The license file '%s' is empty or contains invalid UTF-8 encoding"),
+- szPath);
+- RTFileReadAllFree(pvFile, cbFile);
+- }
+- else if (vrc == VERR_FILE_NOT_FOUND || vrc == VERR_PATH_NOT_FOUND)
+- hrc = setError(VBOX_E_OBJECT_NOT_FOUND, tr("The license file '%s' was not found in extension pack '%s'"),
+- szName, m->Desc.strName.c_str());
+- else
+- hrc = setError(VBOX_E_FILE_ERROR, tr("Failed to open the license file '%s': %Rrc"), szPath, vrc);
+- }
+- else
+- hrc = setError(VBOX_E_IPRT_ERROR, tr("RTPathJoin failed: %Rrc"), vrc);
+- }
+- }
+- return hrc;
+-}
+-
+-
+-STDMETHODIMP ExtPack::QueryObject(IN_BSTR a_bstrObjectId, IUnknown **a_ppUnknown)
+-{
+- com::Guid ObjectId;
+- CheckComArgGuid(a_bstrObjectId, ObjectId);
+- CheckComArgOutPointerValid(a_ppUnknown);
+-
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (SUCCEEDED(hrc))
+- {
+- if ( m->pReg
+- && m->pReg->pfnQueryObject)
+- {
+- void *pvUnknown = m->pReg->pfnQueryObject(m->pReg, ObjectId.raw());
+- if (pvUnknown)
+- *a_ppUnknown = (IUnknown *)pvUnknown;
+- else
+- hrc = E_NOINTERFACE;
+- }
+- else
+- hrc = E_NOINTERFACE;
+- }
+- return hrc;
+-}
+-
+-
+-
+-
+-DEFINE_EMPTY_CTOR_DTOR(ExtPackManager)
+-
+-/**
+- * Called by ComObjPtr::createObject when creating the object.
+- *
+- * Just initialize the basic object state, do the rest in init().
+- *
+- * @returns S_OK.
+- */
+-HRESULT ExtPackManager::FinalConstruct()
+-{
+- m = NULL;
+- return S_OK;
+-}
+-
+-/**
+- * Initializes the extension pack manager.
+- *
+- * @returns COM status code.
+- * @param a_pVirtualBox Pointer to the VirtualBox object.
+- * @param a_enmContext The context we're in.
+- */
+-HRESULT ExtPackManager::initExtPackManager(VirtualBox *a_pVirtualBox, VBOXEXTPACKCTX a_enmContext)
+-{
+- AutoInitSpan autoInitSpan(this);
+- AssertReturn(autoInitSpan.isOk(), E_FAIL);
+-
+- /*
+- * Figure some stuff out before creating the instance data.
+- */
+- char szBaseDir[RTPATH_MAX];
+- int rc = RTPathAppPrivateArchTop(szBaseDir, sizeof(szBaseDir));
+- AssertLogRelRCReturn(rc, E_FAIL);
+- rc = RTPathAppend(szBaseDir, sizeof(szBaseDir), VBOX_EXTPACK_INSTALL_DIR);
+- AssertLogRelRCReturn(rc, E_FAIL);
+-
+- char szCertificatDir[RTPATH_MAX];
+- rc = RTPathAppPrivateNoArch(szCertificatDir, sizeof(szCertificatDir));
+- AssertLogRelRCReturn(rc, E_FAIL);
+- rc = RTPathAppend(szCertificatDir, sizeof(szCertificatDir), VBOX_EXTPACK_CERT_DIR);
+- AssertLogRelRCReturn(rc, E_FAIL);
+-
+- /*
+- * Allocate and initialize the instance data.
+- */
+- m = new Data;
+- m->strBaseDir = szBaseDir;
+- m->strCertificatDirPath = szCertificatDir;
+- m->pVirtualBox = a_pVirtualBox;
+- m->enmContext = a_enmContext;
+-
+- /*
+- * Slurp in VBoxVMM which is used by VBoxPuelMain.
+- */
+-#if !defined(RT_OS_WINDOWS) && !defined(RT_OS_DARWIN)
+- if (a_enmContext == VBOXEXTPACKCTX_PER_USER_DAEMON)
+- {
+- int vrc = SUPR3HardenedLdrLoadAppPriv("VBoxVMM", &m->hVBoxVMM, RTLDRLOAD_FLAGS_GLOBAL, NULL);
+- if (RT_FAILURE(vrc))
+- m->hVBoxVMM = NIL_RTLDRMOD;
+- /* cleanup in ::uninit()? */
+- }
+-#endif
+-
+- /*
+- * Go looking for extensions. The RTDirOpen may fail if nothing has been
+- * installed yet, or if root is paranoid and has revoked our access to them.
+- *
+- * We ASSUME that there are no files, directories or stuff in the directory
+- * that exceed the max name length in RTDIRENTRYEX.
+- */
+- HRESULT hrc = S_OK;
+- PRTDIR pDir;
+- int vrc = RTDirOpen(&pDir, szBaseDir);
+- if (RT_SUCCESS(vrc))
+- {
+- for (;;)
+- {
+- RTDIRENTRYEX Entry;
+- vrc = RTDirReadEx(pDir, &Entry, NULL /*pcbDirEntry*/, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK);
+- if (RT_FAILURE(vrc))
+- {
+- AssertLogRelMsg(vrc == VERR_NO_MORE_FILES, ("%Rrc\n", vrc));
+- break;
+- }
+- if ( RTFS_IS_DIRECTORY(Entry.Info.Attr.fMode)
+- && strcmp(Entry.szName, ".") != 0
+- && strcmp(Entry.szName, "..") != 0
+- && VBoxExtPackIsValidMangledName(Entry.szName) )
+- {
+- /*
+- * All directories are extensions, the shall be nothing but
+- * extensions in this subdirectory.
+- */
+- char szExtPackDir[RTPATH_MAX];
+- vrc = RTPathJoin(szExtPackDir, sizeof(szExtPackDir), m->strBaseDir.c_str(), Entry.szName);
+- AssertLogRelRC(vrc);
+- if (RT_SUCCESS(vrc))
+- {
+- RTCString *pstrName = VBoxExtPackUnmangleName(Entry.szName, RTSTR_MAX);
+- AssertLogRel(pstrName);
+- if (pstrName)
+- {
+- ComObjPtr<ExtPack> NewExtPack;
+- HRESULT hrc2 = NewExtPack.createObject();
+- if (SUCCEEDED(hrc2))
+- hrc2 = NewExtPack->initWithDir(a_enmContext, pstrName->c_str(), szExtPackDir);
+- delete pstrName;
+- if (SUCCEEDED(hrc2))
+- m->llInstalledExtPacks.push_back(NewExtPack);
+- else if (SUCCEEDED(rc))
+- hrc = hrc2;
+- }
+- else
+- hrc = E_UNEXPECTED;
+- }
+- else
+- hrc = E_UNEXPECTED;
+- }
+- }
+- RTDirClose(pDir);
+- }
+- /* else: ignore, the directory probably does not exist or something. */
+-
+- if (SUCCEEDED(hrc))
+- autoInitSpan.setSucceeded();
+- return hrc;
+-}
+-
+-/**
+- * COM cruft.
+- */
+-void ExtPackManager::FinalRelease()
+-{
+- uninit();
+-}
+-
+-/**
+- * Do the actual cleanup.
+- */
+-void ExtPackManager::uninit()
+-{
+- /* Enclose the state transition Ready->InUninit->NotReady */
+- AutoUninitSpan autoUninitSpan(this);
+- if (!autoUninitSpan.uninitDone() && m != NULL)
+- {
+- delete m;
+- m = NULL;
+- }
+-}
+-
+-
+-STDMETHODIMP ExtPackManager::COMGETTER(InstalledExtPacks)(ComSafeArrayOut(IExtPack *, a_paExtPacks))
+-{
+- CheckComArgOutSafeArrayPointerValid(a_paExtPacks);
+- Assert(m->enmContext == VBOXEXTPACKCTX_PER_USER_DAEMON);
+-
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (SUCCEEDED(hrc))
+- {
+- AutoReadLock autoLock(this COMMA_LOCKVAL_SRC_POS);
+-
+- SafeIfaceArray<IExtPack> SaExtPacks(m->llInstalledExtPacks);
+- SaExtPacks.detachTo(ComSafeArrayOutArg(a_paExtPacks));
+- }
+-
+- return hrc;
+-}
+-
+-STDMETHODIMP ExtPackManager::Find(IN_BSTR a_bstrName, IExtPack **a_pExtPack)
+-{
+- CheckComArgNotNull(a_bstrName);
+- CheckComArgOutPointerValid(a_pExtPack);
+- Utf8Str strName(a_bstrName);
+- Assert(m->enmContext == VBOXEXTPACKCTX_PER_USER_DAEMON);
+-
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (SUCCEEDED(hrc))
+- {
+- AutoReadLock autoLock(this COMMA_LOCKVAL_SRC_POS);
+-
+- ComPtr<ExtPack> ptrExtPack = findExtPack(strName.c_str());
+- if (!ptrExtPack.isNull())
+- ptrExtPack.queryInterfaceTo(a_pExtPack);
+- else
+- hrc = VBOX_E_OBJECT_NOT_FOUND;
+- }
+-
+- return hrc;
+-}
+-
+-STDMETHODIMP ExtPackManager::OpenExtPackFile(IN_BSTR a_bstrTarballAndDigest, IExtPackFile **a_ppExtPackFile)
+-{
+- CheckComArgNotNull(a_bstrTarballAndDigest);
+- CheckComArgOutPointerValid(a_ppExtPackFile);
+- AssertReturn(m->enmContext == VBOXEXTPACKCTX_PER_USER_DAEMON, E_UNEXPECTED);
+-
+- /* The API can optionally take a ::SHA-256=<hex-digest> attribute at the
+- end of the file name. This is just a temporary measure for
+- backporting, in 4.2 we'll add another parameter to the method. */
+- Utf8Str strTarball;
+- Utf8Str strDigest;
+- Utf8Str strTarballAndDigest(a_bstrTarballAndDigest);
+- size_t offSha256 = strTarballAndDigest.find("::SHA-256=");
+- if (offSha256 == Utf8Str::npos)
+- strTarball = strTarballAndDigest;
+- else
+- {
+- strTarball = strTarballAndDigest.substr(0, offSha256);
+- strDigest = strTarballAndDigest.substr(offSha256 + sizeof("::SHA-256=") - 1);
+- }
+-
+- ComObjPtr<ExtPackFile> NewExtPackFile;
+- HRESULT hrc = NewExtPackFile.createObject();
+- if (SUCCEEDED(hrc))
+- hrc = NewExtPackFile->initWithFile(strTarball.c_str(), strDigest.c_str(), this, m->pVirtualBox);
+- if (SUCCEEDED(hrc))
+- NewExtPackFile.queryInterfaceTo(a_ppExtPackFile);
+-
+- return hrc;
+-}
+-
+-STDMETHODIMP ExtPackManager::Uninstall(IN_BSTR a_bstrName, BOOL a_fForcedRemoval, IN_BSTR a_bstrDisplayInfo,
+- IProgress **a_ppProgress)
+-{
+- CheckComArgNotNull(a_bstrName);
+- if (a_ppProgress)
+- *a_ppProgress = NULL;
+- Assert(m->enmContext == VBOXEXTPACKCTX_PER_USER_DAEMON);
+-
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (SUCCEEDED(hrc))
+- {
+- PEXTPACKUNINSTALLJOB pJob = NULL;
+- try
+- {
+- pJob = new EXTPACKUNINSTALLJOB;
+- pJob->ptrExtPackMgr = this;
+- pJob->strName = a_bstrName;
+- pJob->fForcedRemoval = a_fForcedRemoval != FALSE;
+- pJob->strDisplayInfo = a_bstrDisplayInfo;
+- hrc = pJob->ptrProgress.createObject();
+- if (SUCCEEDED(hrc))
+- {
+- Bstr bstrDescription = tr("Uninstalling extension pack");
+- hrc = pJob->ptrProgress->init(
+-#ifndef VBOX_COM_INPROC
+- m->pVirtualBox,
+-#endif
+- static_cast<IExtPackManager *>(this),
+- bstrDescription.raw(),
+- FALSE /*aCancelable*/,
+- NULL /*aId*/);
+- }
+- if (SUCCEEDED(hrc))
+- {
+- ComPtr<Progress> ptrProgress = pJob->ptrProgress;
+- int vrc = RTThreadCreate(NULL /*phThread*/, ExtPackManager::doUninstallThreadProc, pJob, 0,
+- RTTHREADTYPE_DEFAULT, 0 /*fFlags*/, "ExtPackUninst");
+- if (RT_SUCCESS(vrc))
+- {
+- pJob = NULL; /* the thread deletes it */
+- ptrProgress.queryInterfaceTo(a_ppProgress);
+- }
+- else
+- hrc = setError(VBOX_E_IPRT_ERROR, tr("RTThreadCreate failed with %Rrc"), vrc);
+- }
+- }
+- catch (std::bad_alloc)
+- {
+- hrc = E_OUTOFMEMORY;
+- }
+- if (pJob)
+- delete pJob;
+- }
+-
+- return hrc;
+-}
+-
+-STDMETHODIMP ExtPackManager::Cleanup(void)
+-{
+- Assert(m->enmContext == VBOXEXTPACKCTX_PER_USER_DAEMON);
+-
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (SUCCEEDED(hrc))
+- {
+- /*
+- * Run the set-uid-to-root binary that performs the cleanup.
+- *
+- * Take the write lock to prevent conflicts with other calls to this
+- * VBoxSVC instance.
+- */
+- AutoWriteLock autoLock(this COMMA_LOCKVAL_SRC_POS);
+- hrc = runSetUidToRootHelper(NULL,
+- "cleanup",
+- "--base-dir", m->strBaseDir.c_str(),
+- (const char *)NULL);
+- }
+-
+- return hrc;
+-}
+-
+-STDMETHODIMP ExtPackManager::QueryAllPlugInsForFrontend(IN_BSTR a_bstrFrontend, ComSafeArrayOut(BSTR, a_pabstrPlugInModules))
+-{
+- CheckComArgNotNull(a_bstrFrontend);
+- Utf8Str strName(a_bstrFrontend);
+- CheckComArgOutSafeArrayPointerValid(a_pabstrPlugInModules);
+- Assert(m->enmContext == VBOXEXTPACKCTX_PER_USER_DAEMON);
+-
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (SUCCEEDED(hrc))
+- {
+- com::SafeArray<BSTR> saPaths((size_t)0);
+- /** @todo implement plug-ins */
+- saPaths.detachTo(ComSafeArrayOutArg(a_pabstrPlugInModules));
+- }
+- return hrc;
+-}
+-
+-STDMETHODIMP ExtPackManager::IsExtPackUsable(IN_BSTR a_bstrExtPack, BOOL *aUsable)
+-{
+- CheckComArgNotNull(a_bstrExtPack);
+- Utf8Str strExtPack(a_bstrExtPack);
+- *aUsable = isExtPackUsable(strExtPack.c_str());
+- return S_OK;
+-}
+-
+-/**
+- * Finds the success indicator string in the stderr output ofr hte helper app.
+- *
+- * @returns Pointer to the indicator.
+- * @param psz The stderr output string. Can be NULL.
+- * @param cch The size of the string.
+- */
+-static char *findSuccessIndicator(char *psz, size_t cch)
+-{
+- static const char s_szSuccessInd[] = "rcExit=RTEXITCODE_SUCCESS";
+- Assert(!cch || strlen(psz) == cch);
+- if (cch < sizeof(s_szSuccessInd) - 1)
+- return NULL;
+- char *pszInd = &psz[cch - sizeof(s_szSuccessInd) + 1];
+- if (strcmp(s_szSuccessInd, pszInd))
+- return NULL;
+- return pszInd;
+-}
+-
+-/**
+- * Runs the helper application that does the privileged operations.
+- *
+- * @returns S_OK or a failure status with error information set.
+- * @param a_pstrDisplayInfo Platform specific display info hacks.
+- * @param a_pszCommand The command to execute.
+- * @param ... The argument strings that goes along with the
+- * command. Maximum is about 16. Terminated by a
+- * NULL.
+- */
+-HRESULT ExtPackManager::runSetUidToRootHelper(Utf8Str const *a_pstrDisplayInfo, const char *a_pszCommand, ...)
+-{
+- /*
+- * Calculate the path to the helper application.
+- */
+- char szExecName[RTPATH_MAX];
+- int vrc = RTPathAppPrivateArch(szExecName, sizeof(szExecName));
+- AssertLogRelRCReturn(vrc, E_UNEXPECTED);
+-
+- vrc = RTPathAppend(szExecName, sizeof(szExecName), VBOX_EXTPACK_HELPER_NAME);
+- AssertLogRelRCReturn(vrc, E_UNEXPECTED);
+-
+- /*
+- * Convert the variable argument list to a RTProcCreate argument vector.
+- */
+- const char *apszArgs[20];
+- unsigned cArgs = 0;
+-
+- LogRel(("ExtPack: Executing '%s'", szExecName));
+- apszArgs[cArgs++] = &szExecName[0];
+-
+- if ( a_pstrDisplayInfo
+- && a_pstrDisplayInfo->isNotEmpty())
+- {
+- LogRel((" '--display-info-hack' '%s'", a_pstrDisplayInfo->c_str()));
+- apszArgs[cArgs++] = "--display-info-hack";
+- apszArgs[cArgs++] = a_pstrDisplayInfo->c_str();
+- }
+-
+- LogRel(("'%s'", a_pszCommand));
+- apszArgs[cArgs++] = a_pszCommand;
+-
+- va_list va;
+- va_start(va, a_pszCommand);
+- const char *pszLastArg;
+- for (;;)
+- {
+- AssertReturn(cArgs < RT_ELEMENTS(apszArgs) - 1, E_UNEXPECTED);
+- pszLastArg = va_arg(va, const char *);
+- if (!pszLastArg)
+- break;
+- LogRel((" '%s'", pszLastArg));
+- apszArgs[cArgs++] = pszLastArg;
+- };
+- va_end(va);
+-
+- LogRel(("\n"));
+- apszArgs[cArgs] = NULL;
+-
+- /*
+- * Create a PIPE which we attach to stderr so that we can read the error
+- * message on failure and report it back to the caller.
+- */
+- RTPIPE hPipeR;
+- RTHANDLE hStdErrPipe;
+- hStdErrPipe.enmType = RTHANDLETYPE_PIPE;
+- vrc = RTPipeCreate(&hPipeR, &hStdErrPipe.u.hPipe, RTPIPE_C_INHERIT_WRITE);
+- AssertLogRelRCReturn(vrc, E_UNEXPECTED);
+-
+- /*
+- * Spawn the process.
+- */
+- HRESULT hrc;
+- RTPROCESS hProcess;
+- vrc = RTProcCreateEx(szExecName,
+- apszArgs,
+- RTENV_DEFAULT,
+- 0 /*fFlags*/,
+- NULL /*phStdIn*/,
+- NULL /*phStdOut*/,
+- &hStdErrPipe,
+- NULL /*pszAsUser*/,
+- NULL /*pszPassword*/,
+- &hProcess);
+- if (RT_SUCCESS(vrc))
+- {
+- vrc = RTPipeClose(hStdErrPipe.u.hPipe);
+- hStdErrPipe.u.hPipe = NIL_RTPIPE;
+-
+- /*
+- * Read the pipe output until the process completes.
+- */
+- RTPROCSTATUS ProcStatus = { -42, RTPROCEXITREASON_ABEND };
+- size_t cbStdErrBuf = 0;
+- size_t offStdErrBuf = 0;
+- char *pszStdErrBuf = NULL;
+- do
+- {
+- /*
+- * Service the pipe. Block waiting for output or the pipe breaking
+- * when the process terminates.
+- */
+- if (hPipeR != NIL_RTPIPE)
+- {
+- char achBuf[1024];
+- size_t cbRead;
+- vrc = RTPipeReadBlocking(hPipeR, achBuf, sizeof(achBuf), &cbRead);
+- if (RT_SUCCESS(vrc))
+- {
+- /* grow the buffer? */
+- size_t cbBufReq = offStdErrBuf + cbRead + 1;
+- if ( cbBufReq > cbStdErrBuf
+- && cbBufReq < _256K)
+- {
+- size_t cbNew = RT_ALIGN_Z(cbBufReq, 16); // 1024
+- void *pvNew = RTMemRealloc(pszStdErrBuf, cbNew);
+- if (pvNew)
+- {
+- pszStdErrBuf = (char *)pvNew;
+- cbStdErrBuf = cbNew;
+- }
+- }
+-
+- /* append if we've got room. */
+- if (cbBufReq <= cbStdErrBuf)
+- {
+- memcpy(&pszStdErrBuf[offStdErrBuf], achBuf, cbRead);
+- offStdErrBuf = offStdErrBuf + cbRead;
+- pszStdErrBuf[offStdErrBuf] = '\0';
+- }
+- }
+- else
+- {
+- AssertLogRelMsg(vrc == VERR_BROKEN_PIPE, ("%Rrc\n", vrc));
+- RTPipeClose(hPipeR);
+- hPipeR = NIL_RTPIPE;
+- }
+- }
+-
+- /*
+- * Service the process. Block if we have no pipe.
+- */
+- if (hProcess != NIL_RTPROCESS)
+- {
+- vrc = RTProcWait(hProcess,
+- hPipeR == NIL_RTPIPE ? RTPROCWAIT_FLAGS_BLOCK : RTPROCWAIT_FLAGS_NOBLOCK,
+- &ProcStatus);
+- if (RT_SUCCESS(vrc))
+- hProcess = NIL_RTPROCESS;
+- else
+- AssertLogRelMsgStmt(vrc == VERR_PROCESS_RUNNING, ("%Rrc\n", vrc), hProcess = NIL_RTPROCESS);
+- }
+- } while ( hPipeR != NIL_RTPIPE
+- || hProcess != NIL_RTPROCESS);
+-
+- LogRel(("ExtPack: enmReason=%d iStatus=%d stderr='%s'\n",
+- ProcStatus.enmReason, ProcStatus.iStatus, offStdErrBuf ? pszStdErrBuf : ""));
+-
+- /*
+- * Look for rcExit=RTEXITCODE_SUCCESS at the end of the error output,
+- * cut it as it is only there to attest the success.
+- */
+- if (offStdErrBuf > 0)
+- {
+- RTStrStripR(pszStdErrBuf);
+- offStdErrBuf = strlen(pszStdErrBuf);
+- }
+-
+- char *pszSuccessInd = findSuccessIndicator(pszStdErrBuf, offStdErrBuf);
+- if (pszSuccessInd)
+- {
+- *pszSuccessInd = '\0';
+- offStdErrBuf = pszSuccessInd - pszStdErrBuf;
+- }
+- else if ( ProcStatus.enmReason == RTPROCEXITREASON_NORMAL
+- && ProcStatus.iStatus == 0)
+- ProcStatus.iStatus = offStdErrBuf ? 667 : 666;
+-
+- /*
+- * Compose the status code and, on failure, error message.
+- */
+- if ( ProcStatus.enmReason == RTPROCEXITREASON_NORMAL
+- && ProcStatus.iStatus == 0)
+- hrc = S_OK;
+- else if (ProcStatus.enmReason == RTPROCEXITREASON_NORMAL)
+- {
+- AssertMsg(ProcStatus.iStatus != 0, ("%s\n", pszStdErrBuf));
+- hrc = setError(E_FAIL, tr("The installer failed with exit code %d: %s"),
+- ProcStatus.iStatus, offStdErrBuf ? pszStdErrBuf : "");
+- }
+- else if (ProcStatus.enmReason == RTPROCEXITREASON_SIGNAL)
+- hrc = setError(E_UNEXPECTED, tr("The installer was killed by signal #d (stderr: %s)"),
+- ProcStatus.iStatus, offStdErrBuf ? pszStdErrBuf : "");
+- else if (ProcStatus.enmReason == RTPROCEXITREASON_ABEND)
+- hrc = setError(E_UNEXPECTED, tr("The installer aborted abnormally (stderr: %s)"),
+- offStdErrBuf ? pszStdErrBuf : "");
+- else
+- hrc = setError(E_UNEXPECTED, tr("internal error: enmReason=%d iStatus=%d stderr='%s'"),
+- ProcStatus.enmReason, ProcStatus.iStatus, offStdErrBuf ? pszStdErrBuf : "");
+-
+- RTMemFree(pszStdErrBuf);
+- }
+- else
+- hrc = setError(VBOX_E_IPRT_ERROR, tr("Failed to launch the helper application '%s' (%Rrc)"), szExecName, vrc);
+-
+- RTPipeClose(hPipeR);
+- RTPipeClose(hStdErrPipe.u.hPipe);
+-
+- return hrc;
+-}
+-
+-/**
+- * Finds an installed extension pack.
+- *
+- * @returns Pointer to the extension pack if found, NULL if not. (No reference
+- * counting problem here since the caller must be holding the lock.)
+- * @param a_pszName The name of the extension pack.
+- */
+-ExtPack *ExtPackManager::findExtPack(const char *a_pszName)
+-{
+- size_t cchName = strlen(a_pszName);
+-
+- for (ExtPackList::iterator it = m->llInstalledExtPacks.begin();
+- it != m->llInstalledExtPacks.end();
+- it++)
+- {
+- ExtPack::Data *pExtPackData = (*it)->m;
+- if ( pExtPackData
+- && pExtPackData->Desc.strName.length() == cchName
+- && pExtPackData->Desc.strName.equalsIgnoreCase(a_pszName))
+- return (*it);
+- }
+- return NULL;
+-}
+-
+-/**
+- * Removes an installed extension pack from the internal list.
+- *
+- * The package is expected to exist!
+- *
+- * @param a_pszName The name of the extension pack.
+- */
+-void ExtPackManager::removeExtPack(const char *a_pszName)
+-{
+- size_t cchName = strlen(a_pszName);
+-
+- for (ExtPackList::iterator it = m->llInstalledExtPacks.begin();
+- it != m->llInstalledExtPacks.end();
+- it++)
+- {
+- ExtPack::Data *pExtPackData = (*it)->m;
+- if ( pExtPackData
+- && pExtPackData->Desc.strName.length() == cchName
+- && pExtPackData->Desc.strName.equalsIgnoreCase(a_pszName))
+- {
+- m->llInstalledExtPacks.erase(it);
+- return;
+- }
+- }
+- AssertMsgFailed(("%s\n", a_pszName));
+-}
+-
+-/**
+- * Refreshes the specified extension pack.
+- *
+- * This may remove the extension pack from the list, so any non-smart pointers
+- * to the extension pack object may become invalid.
+- *
+- * @returns S_OK and *a_ppExtPack on success, COM status code and error
+- * message on failure. Note that *a_ppExtPack can be NULL.
+- *
+- * @param a_pszName The extension to update..
+- * @param a_fUnusableIsError If @c true, report an unusable extension pack
+- * as an error.
+- * @param a_ppExtPack Where to store the pointer to the extension
+- * pack of it is still around after the refresh.
+- * This is optional.
+- *
+- * @remarks Caller holds the extension manager lock.
+- * @remarks Only called in VBoxSVC.
+- */
+-HRESULT ExtPackManager::refreshExtPack(const char *a_pszName, bool a_fUnusableIsError, ExtPack **a_ppExtPack)
+-{
+- Assert(m->pVirtualBox != NULL); /* Only called from VBoxSVC. */
+-
+- HRESULT hrc;
+- ExtPack *pExtPack = findExtPack(a_pszName);
+- if (pExtPack)
+- {
+- /*
+- * Refresh existing object.
+- */
+- bool fCanDelete;
+- hrc = pExtPack->refresh(&fCanDelete);
+- if (SUCCEEDED(hrc))
+- {
+- if (fCanDelete)
+- {
+- removeExtPack(a_pszName);
+- pExtPack = NULL;
+- }
+- }
+- }
+- else
+- {
+- /*
+- * Do this check here, otherwise VBoxExtPackCalcDir() will fail with a strange
+- * error.
+- */
+- bool fValid = VBoxExtPackIsValidName(a_pszName);
+- if (!fValid)
+- return setError(E_FAIL, "Invalid extension pack name specified");
+-
+- /*
+- * Does the dir exist? Make some special effort to deal with case
+- * sensitivie file systems (a_pszName is case insensitive and mangled).
+- */
+- char szDir[RTPATH_MAX];
+- int vrc = VBoxExtPackCalcDir(szDir, sizeof(szDir), m->strBaseDir.c_str(), a_pszName);
+- AssertLogRelRCReturn(vrc, E_FAIL);
+-
+- RTDIRENTRYEX Entry;
+- RTFSOBJINFO ObjInfo;
+- vrc = RTPathQueryInfoEx(szDir, &ObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK);
+- bool fExists = RT_SUCCESS(vrc) && RTFS_IS_DIRECTORY(ObjInfo.Attr.fMode);
+- if (!fExists)
+- {
+- PRTDIR pDir;
+- vrc = RTDirOpen(&pDir, m->strBaseDir.c_str());
+- if (RT_SUCCESS(vrc))
+- {
+- const char *pszMangledName = RTPathFilename(szDir);
+- for (;;)
+- {
+- vrc = RTDirReadEx(pDir, &Entry, NULL /*pcbDirEntry*/, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK);
+- if (RT_FAILURE(vrc))
+- {
+- AssertLogRelMsg(vrc == VERR_NO_MORE_FILES, ("%Rrc\n", vrc));
+- break;
+- }
+- if ( RTFS_IS_DIRECTORY(Entry.Info.Attr.fMode)
+- && !RTStrICmp(Entry.szName, pszMangledName))
+- {
+- /*
+- * The installed extension pack has a uses different case.
+- * Update the name and directory variables.
+- */
+- vrc = RTPathJoin(szDir, sizeof(szDir), m->strBaseDir.c_str(), Entry.szName); /* not really necessary */
+- AssertLogRelRCReturnStmt(vrc, RTDirClose(pDir), E_UNEXPECTED);
+- a_pszName = Entry.szName;
+- fExists = true;
+- break;
+- }
+- }
+- RTDirClose(pDir);
+- }
+- }
+- if (fExists)
+- {
+- /*
+- * We've got something, create a new extension pack object for it.
+- */
+- ComObjPtr<ExtPack> ptrNewExtPack;
+- hrc = ptrNewExtPack.createObject();
+- if (SUCCEEDED(hrc))
+- hrc = ptrNewExtPack->initWithDir(m->enmContext, a_pszName, szDir);
+- if (SUCCEEDED(hrc))
+- {
+- m->llInstalledExtPacks.push_back(ptrNewExtPack);
+- if (ptrNewExtPack->m->fUsable)
+- LogRel(("ExtPackManager: Found extension pack '%s'.\n", a_pszName));
+- else
+- LogRel(("ExtPackManager: Found bad extension pack '%s': %s\n",
+- a_pszName, ptrNewExtPack->m->strWhyUnusable.c_str() ));
+- pExtPack = ptrNewExtPack;
+- }
+- }
+- else
+- hrc = S_OK;
+- }
+-
+- /*
+- * Report error if not usable, if that is desired.
+- */
+- if ( SUCCEEDED(hrc)
+- && pExtPack
+- && a_fUnusableIsError
+- && !pExtPack->m->fUsable)
+- hrc = setError(E_FAIL, "%s", pExtPack->m->strWhyUnusable.c_str());
+-
+- if (a_ppExtPack)
+- *a_ppExtPack = pExtPack;
+- return hrc;
+-}
+-
+-/**
+- * Thread wrapper around doInstall.
+- *
+- * @returns VINF_SUCCESS (ignored)
+- * @param hThread The thread handle (ignored).
+- * @param pvJob The job structure.
+- */
+-/*static*/ DECLCALLBACK(int) ExtPackManager::doInstallThreadProc(RTTHREAD hThread, void *pvJob)
+-{
+- PEXTPACKINSTALLJOB pJob = (PEXTPACKINSTALLJOB)pvJob;
+- HRESULT hrc = pJob->ptrExtPackMgr->doInstall(pJob->ptrExtPackFile, pJob->fReplace, &pJob->strDisplayInfo);
+- pJob->ptrProgress->notifyComplete(hrc);
+- delete pJob;
+-
+- NOREF(hThread);
+- return VINF_SUCCESS;
+-}
+-
+-/**
+- * Worker for IExtPackFile::Install.
+- *
+- * Called on a worker thread via doInstallThreadProc.
+- *
+- * @returns COM status code.
+- * @param a_pExtPackFile The extension pack file, caller checks that
+- * it's usable.
+- * @param a_fReplace Whether to replace any existing extpack or just
+- * fail.
+- * @param a_pstrDisplayInfo Host specific display information hacks.
+- * @param a_ppProgress Where to return a progress object some day. Can
+- * be NULL.
+- */
+-HRESULT ExtPackManager::doInstall(ExtPackFile *a_pExtPackFile, bool a_fReplace, Utf8Str const *a_pstrDisplayInfo)
+-{
+- AssertReturn(m->enmContext == VBOXEXTPACKCTX_PER_USER_DAEMON, E_UNEXPECTED);
+- RTCString const * const pStrName = &a_pExtPackFile->m->Desc.strName;
+- RTCString const * const pStrTarball = &a_pExtPackFile->m->strExtPackFile;
+- RTCString const * const pStrTarballDigest = &a_pExtPackFile->m->strDigest;
+-
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (SUCCEEDED(hrc))
+- {
+- AutoWriteLock autoLock(this COMMA_LOCKVAL_SRC_POS);
+-
+- /*
+- * Refresh the data we have on the extension pack as it
+- * may be made stale by direct meddling or some other user.
+- */
+- ExtPack *pExtPack;
+- hrc = refreshExtPack(pStrName->c_str(), false /*a_fUnusableIsError*/, &pExtPack);
+- if (SUCCEEDED(hrc))
+- {
+- if (pExtPack && a_fReplace)
+- hrc = pExtPack->callUninstallHookAndClose(m->pVirtualBox, false /*a_ForcedRemoval*/);
+- else if (pExtPack)
+- hrc = setError(E_FAIL,
+- tr("Extension pack '%s' is already installed."
+- " In case of a reinstallation, please uninstall it first"),
+- pStrName->c_str());
+- }
+- if (SUCCEEDED(hrc))
+- {
+- /*
+- * Run the privileged helper binary that performs the actual
+- * installation. Then create an object for the packet (we do this
+- * even on failure, to be on the safe side).
+- */
+- hrc = runSetUidToRootHelper(a_pstrDisplayInfo,
+- "install",
+- "--base-dir", m->strBaseDir.c_str(),
+- "--cert-dir", m->strCertificatDirPath.c_str(),
+- "--name", pStrName->c_str(),
+- "--tarball", pStrTarball->c_str(),
+- "--sha-256", pStrTarballDigest->c_str(),
+- pExtPack ? "--replace" : (const char *)NULL,
+- (const char *)NULL);
+- if (SUCCEEDED(hrc))
+- {
+- hrc = refreshExtPack(pStrName->c_str(), true /*a_fUnusableIsError*/, &pExtPack);
+- if (SUCCEEDED(hrc) && pExtPack)
+- {
+- RTERRINFOSTATIC ErrInfo;
+- RTErrInfoInitStatic(&ErrInfo);
+- pExtPack->callInstalledHook(m->pVirtualBox, &autoLock, &ErrInfo.Core);
+- if (RT_SUCCESS(ErrInfo.Core.rc))
+- LogRel(("ExtPackManager: Successfully installed extension pack '%s'.\n", pStrName->c_str()));
+- else
+- {
+- LogRel(("ExtPackManager: Installated hook for '%s' failed: %Rrc - %s\n",
+- pStrName->c_str(), ErrInfo.Core.rc, ErrInfo.Core.pszMsg));
+-
+- /*
+- * Uninstall the extpack if the error indicates that.
+- */
+- if (ErrInfo.Core.rc == VERR_EXTPACK_UNSUPPORTED_HOST_UNINSTALL)
+- runSetUidToRootHelper(a_pstrDisplayInfo,
+- "uninstall",
+- "--base-dir", m->strBaseDir.c_str(),
+- "--name", pStrName->c_str(),
+- "--forced",
+- (const char *)NULL);
+- hrc = setError(E_FAIL, tr("The installation hook failed: %Rrc - %s"),
+- ErrInfo.Core.rc, ErrInfo.Core.pszMsg);
+- }
+- }
+- else if (SUCCEEDED(hrc))
+- hrc = setError(E_FAIL, tr("Installing extension pack '%s' failed under mysterious circumstances"),
+- pStrName->c_str());
+- }
+- else
+- {
+- ErrorInfoKeeper Eik;
+- refreshExtPack(pStrName->c_str(), false /*a_fUnusableIsError*/, NULL);
+- }
+- }
+-
+- /*
+- * Do VirtualBoxReady callbacks now for any freshly installed
+- * extension pack (old ones will not be called).
+- */
+- if (m->enmContext == VBOXEXTPACKCTX_PER_USER_DAEMON)
+- {
+- autoLock.release();
+- callAllVirtualBoxReadyHooks();
+- }
+- }
+-
+- return hrc;
+-}
+-
+-/**
+- * Thread wrapper around doUninstall.
+- *
+- * @returns VINF_SUCCESS (ignored)
+- * @param hThread The thread handle (ignored).
+- * @param pvJob The job structure.
+- */
+-/*static*/ DECLCALLBACK(int) ExtPackManager::doUninstallThreadProc(RTTHREAD hThread, void *pvJob)
+-{
+- PEXTPACKUNINSTALLJOB pJob = (PEXTPACKUNINSTALLJOB)pvJob;
+- HRESULT hrc = pJob->ptrExtPackMgr->doUninstall(&pJob->strName, pJob->fForcedRemoval, &pJob->strDisplayInfo);
+- pJob->ptrProgress->notifyComplete(hrc);
+- delete pJob;
+-
+- NOREF(hThread);
+- return VINF_SUCCESS;
+-}
+-
+-/**
+- * Worker for IExtPackManager::Uninstall.
+- *
+- * Called on a worker thread via doUninstallThreadProc.
+- *
+- * @returns COM status code.
+- * @param a_pstrName The name of the extension pack to uninstall.
+- * @param a_fForcedRemoval Whether to be skip and ignore certain bits of
+- * the extpack feedback. To deal with misbehaving
+- * extension pack hooks.
+- * @param a_pstrDisplayInfo Host specific display information hacks.
+- */
+-HRESULT ExtPackManager::doUninstall(Utf8Str const *a_pstrName, bool a_fForcedRemoval, Utf8Str const *a_pstrDisplayInfo)
+-{
+- Assert(m->enmContext == VBOXEXTPACKCTX_PER_USER_DAEMON);
+-
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (SUCCEEDED(hrc))
+- {
+- AutoWriteLock autoLock(this COMMA_LOCKVAL_SRC_POS);
+-
+- /*
+- * Refresh the data we have on the extension pack as it may be made
+- * stale by direct meddling or some other user.
+- */
+- ExtPack *pExtPack;
+- hrc = refreshExtPack(a_pstrName->c_str(), false /*a_fUnusableIsError*/, &pExtPack);
+- if (SUCCEEDED(hrc))
+- {
+- if (!pExtPack)
+- {
+- LogRel(("ExtPackManager: Extension pack '%s' is not installed, so nothing to uninstall.\n", a_pstrName->c_str()));
+- hrc = S_OK; /* nothing to uninstall */
+- }
+- else
+- {
+- /*
+- * Call the uninstall hook and unload the main dll.
+- */
+- hrc = pExtPack->callUninstallHookAndClose(m->pVirtualBox, a_fForcedRemoval);
+- if (SUCCEEDED(hrc))
+- {
+- /*
+- * Run the set-uid-to-root binary that performs the
+- * uninstallation. Then refresh the object.
+- *
+- * This refresh is theorically subject to races, but it's of
+- * the don't-do-that variety.
+- */
+- const char *pszForcedOpt = a_fForcedRemoval ? "--forced" : NULL;
+- hrc = runSetUidToRootHelper(a_pstrDisplayInfo,
+- "uninstall",
+- "--base-dir", m->strBaseDir.c_str(),
+- "--name", a_pstrName->c_str(),
+- pszForcedOpt, /* Last as it may be NULL. */
+- (const char *)NULL);
+- if (SUCCEEDED(hrc))
+- {
+- hrc = refreshExtPack(a_pstrName->c_str(), false /*a_fUnusableIsError*/, &pExtPack);
+- if (SUCCEEDED(hrc))
+- {
+- if (!pExtPack)
+- LogRel(("ExtPackManager: Successfully uninstalled extension pack '%s'.\n", a_pstrName->c_str()));
+- else
+- hrc = setError(E_FAIL,
+- tr("Uninstall extension pack '%s' failed under mysterious circumstances"),
+- a_pstrName->c_str());
+- }
+- }
+- else
+- {
+- ErrorInfoKeeper Eik;
+- refreshExtPack(a_pstrName->c_str(), false /*a_fUnusableIsError*/, NULL);
+- }
+- }
+- }
+- }
+-
+- /*
+- * Do VirtualBoxReady callbacks now for any freshly installed
+- * extension pack (old ones will not be called).
+- */
+- if (m->enmContext == VBOXEXTPACKCTX_PER_USER_DAEMON)
+- {
+- autoLock.release();
+- callAllVirtualBoxReadyHooks();
+- }
+- }
+-
+- return hrc;
+-}
+-
+-
+-/**
+- * Calls the pfnVirtualBoxReady hook for all working extension packs.
+- *
+- * @remarks The caller must not hold any locks.
+- */
+-void ExtPackManager::callAllVirtualBoxReadyHooks(void)
+-{
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (FAILED(hrc))
+- return;
+- AutoWriteLock autoLock(this COMMA_LOCKVAL_SRC_POS);
+- ComPtr<ExtPackManager> ptrSelfRef = this;
+-
+- for (ExtPackList::iterator it = m->llInstalledExtPacks.begin();
+- it != m->llInstalledExtPacks.end();
+- /* advancing below */)
+- {
+- if ((*it)->callVirtualBoxReadyHook(m->pVirtualBox, &autoLock))
+- it = m->llInstalledExtPacks.begin();
+- else
+- it++;
+- }
+-}
+-
+-/**
+- * Calls the pfnConsoleReady hook for all working extension packs.
+- *
+- * @param a_pConsole The console interface.
+- * @remarks The caller must not hold any locks.
+- */
+-void ExtPackManager::callAllConsoleReadyHooks(IConsole *a_pConsole)
+-{
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (FAILED(hrc))
+- return;
+- AutoWriteLock autoLock(this COMMA_LOCKVAL_SRC_POS);
+- ComPtr<ExtPackManager> ptrSelfRef = this;
+-
+- for (ExtPackList::iterator it = m->llInstalledExtPacks.begin();
+- it != m->llInstalledExtPacks.end();
+- /* advancing below */)
+- {
+- if ((*it)->callConsoleReadyHook(a_pConsole, &autoLock))
+- it = m->llInstalledExtPacks.begin();
+- else
+- it++;
+- }
+-}
+-
+-/**
+- * Calls the pfnVMCreated hook for all working extension packs.
+- *
+- * @param a_pMachine The machine interface of the new VM.
+- */
+-void ExtPackManager::callAllVmCreatedHooks(IMachine *a_pMachine)
+-{
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (FAILED(hrc))
+- return;
+- AutoWriteLock autoLock(this COMMA_LOCKVAL_SRC_POS);
+- ComPtr<ExtPackManager> ptrSelfRef = this; /* paranoia */
+- ExtPackList llExtPacks = m->llInstalledExtPacks;
+-
+- for (ExtPackList::iterator it = llExtPacks.begin(); it != llExtPacks.end(); it++)
+- (*it)->callVmCreatedHook(m->pVirtualBox, a_pMachine, &autoLock);
+-}
+-
+-/**
+- * Calls the pfnVMConfigureVMM hook for all working extension packs.
+- *
+- * @returns VBox status code. Stops on the first failure, expecting the caller
+- * to signal this to the caller of the CFGM constructor.
+- * @param a_pConsole The console interface for the VM.
+- * @param a_pVM The VM handle.
+- */
+-int ExtPackManager::callAllVmConfigureVmmHooks(IConsole *a_pConsole, PVM a_pVM)
+-{
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (FAILED(hrc))
+- return Global::vboxStatusCodeFromCOM(hrc);
+- AutoWriteLock autoLock(this COMMA_LOCKVAL_SRC_POS);
+- ComPtr<ExtPackManager> ptrSelfRef = this; /* paranoia */
+- ExtPackList llExtPacks = m->llInstalledExtPacks;
+-
+- for (ExtPackList::iterator it = llExtPacks.begin(); it != llExtPacks.end(); it++)
+- {
+- int vrc;
+- (*it)->callVmConfigureVmmHook(a_pConsole, a_pVM, &autoLock, &vrc);
+- if (RT_FAILURE(vrc))
+- return vrc;
+- }
+-
+- return VINF_SUCCESS;
+-}
+-
+-/**
+- * Calls the pfnVMPowerOn hook for all working extension packs.
+- *
+- * @returns VBox status code. Stops on the first failure, expecting the caller
+- * to not power on the VM.
+- * @param a_pConsole The console interface for the VM.
+- * @param a_pVM The VM handle.
+- */
+-int ExtPackManager::callAllVmPowerOnHooks(IConsole *a_pConsole, PVM a_pVM)
+-{
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (FAILED(hrc))
+- return Global::vboxStatusCodeFromCOM(hrc);
+- AutoWriteLock autoLock(this COMMA_LOCKVAL_SRC_POS);
+- ComPtr<ExtPackManager> ptrSelfRef = this; /* paranoia */
+- ExtPackList llExtPacks = m->llInstalledExtPacks;
+-
+- for (ExtPackList::iterator it = llExtPacks.begin(); it != llExtPacks.end(); it++)
+- {
+- int vrc;
+- (*it)->callVmPowerOnHook(a_pConsole, a_pVM, &autoLock, &vrc);
+- if (RT_FAILURE(vrc))
+- return vrc;
+- }
+-
+- return VINF_SUCCESS;
+-}
+-
+-/**
+- * Calls the pfnVMPowerOff hook for all working extension packs.
+- *
+- * @param a_pConsole The console interface for the VM.
+- * @param a_pVM The VM handle. Can be NULL.
+- */
+-void ExtPackManager::callAllVmPowerOffHooks(IConsole *a_pConsole, PVM a_pVM)
+-{
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (FAILED(hrc))
+- return;
+- AutoWriteLock autoLock(this COMMA_LOCKVAL_SRC_POS);
+- ComPtr<ExtPackManager> ptrSelfRef = this; /* paranoia */
+- ExtPackList llExtPacks = m->llInstalledExtPacks;
+-
+- for (ExtPackList::iterator it = llExtPacks.begin(); it != llExtPacks.end(); it++)
+- (*it)->callVmPowerOffHook(a_pConsole, a_pVM, &autoLock);
+-}
+-
+-
+-/**
+- * Checks that the specified extension pack contains a VRDE module and that it
+- * is shipshape.
+- *
+- * @returns S_OK if ok, appropriate failure status code with details.
+- * @param a_pstrExtPack The name of the extension pack.
+- */
+-HRESULT ExtPackManager::checkVrdeExtPack(Utf8Str const *a_pstrExtPack)
+-{
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (SUCCEEDED(hrc))
+- {
+- AutoReadLock autoLock(this COMMA_LOCKVAL_SRC_POS);
+-
+- ExtPack *pExtPack = findExtPack(a_pstrExtPack->c_str());
+- if (pExtPack)
+- hrc = pExtPack->checkVrde();
+- else
+- hrc = setError(VBOX_E_OBJECT_NOT_FOUND, tr("No extension pack by the name '%s' was found"), a_pstrExtPack->c_str());
+- }
+-
+- return hrc;
+-}
+-
+-/**
+- * Gets the full path to the VRDE library of the specified extension pack.
+- *
+- * This will do extacly the same as checkVrdeExtPack and then resolve the
+- * library path.
+- *
+- * @returns S_OK if a path is returned, COM error status and message return if
+- * not.
+- * @param a_pstrExtPack The extension pack.
+- * @param a_pstrVrdeLibrary Where to return the path.
+- */
+-int ExtPackManager::getVrdeLibraryPathForExtPack(Utf8Str const *a_pstrExtPack, Utf8Str *a_pstrVrdeLibrary)
+-{
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (SUCCEEDED(hrc))
+- {
+- AutoReadLock autoLock(this COMMA_LOCKVAL_SRC_POS);
+-
+- ExtPack *pExtPack = findExtPack(a_pstrExtPack->c_str());
+- if (pExtPack)
+- hrc = pExtPack->getVrdpLibraryName(a_pstrVrdeLibrary);
+- else
+- hrc = setError(VBOX_E_OBJECT_NOT_FOUND, tr("No extension pack by the name '%s' was found"), a_pstrExtPack->c_str());
+- }
+-
+- return hrc;
+-}
+-
+-/**
+- * Gets the name of the default VRDE extension pack.
+- *
+- * @returns S_OK or some COM error status on red tape failure.
+- * @param a_pstrExtPack Where to return the extension pack name. Returns
+- * empty if no extension pack wishes to be the default
+- * VRDP provider.
+- */
+-HRESULT ExtPackManager::getDefaultVrdeExtPack(Utf8Str *a_pstrExtPack)
+-{
+- a_pstrExtPack->setNull();
+-
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (SUCCEEDED(hrc))
+- {
+- AutoReadLock autoLock(this COMMA_LOCKVAL_SRC_POS);
+-
+- for (ExtPackList::iterator it = m->llInstalledExtPacks.begin();
+- it != m->llInstalledExtPacks.end();
+- it++)
+- {
+- if ((*it)->wantsToBeDefaultVrde())
+- {
+- *a_pstrExtPack = (*it)->m->Desc.strName;
+- break;
+- }
+- }
+- }
+- return hrc;
+-}
+-
+-/**
+- * Checks if an extension pack is (present and) usable.
+- *
+- * @returns @c true if it is, otherwise @c false.
+- * @param a_pszExtPack The name of the extension pack.
+- */
+-bool ExtPackManager::isExtPackUsable(const char *a_pszExtPack)
+-{
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (FAILED(hrc))
+- return false;
+- AutoReadLock autoLock(this COMMA_LOCKVAL_SRC_POS);
+-
+- ExtPack *pExtPack = findExtPack(a_pszExtPack);
+- return pExtPack != NULL
+- && pExtPack->m->fUsable;
+-}
+-
+-/**
+- * Dumps all extension packs to the release log.
+- */
+-void ExtPackManager::dumpAllToReleaseLog(void)
+-{
+- AutoCaller autoCaller(this);
+- HRESULT hrc = autoCaller.rc();
+- if (FAILED(hrc))
+- return;
+- AutoReadLock autoLock(this COMMA_LOCKVAL_SRC_POS);
+-
+- LogRel(("Installed Extension Packs:\n"));
+- for (ExtPackList::iterator it = m->llInstalledExtPacks.begin();
+- it != m->llInstalledExtPacks.end();
+- it++)
+- {
+- ExtPack::Data *pExtPackData = (*it)->m;
+- if (pExtPackData)
+- {
+- if (pExtPackData->fUsable)
+- LogRel((" %s (Version: %s r%u%s%s; VRDE Module: %s)\n",
+- pExtPackData->Desc.strName.c_str(),
+- pExtPackData->Desc.strVersion.c_str(),
+- pExtPackData->Desc.uRevision,
+- pExtPackData->Desc.strEdition.isEmpty() ? "" : " ",
+- pExtPackData->Desc.strEdition.c_str(),
+- pExtPackData->Desc.strVrdeModule.c_str() ));
+- else
+- LogRel((" %s (Version: %s r%u%s%s; VRDE Module: %s unusable because of '%s')\n",
+- pExtPackData->Desc.strName.c_str(),
+- pExtPackData->Desc.strVersion.c_str(),
+- pExtPackData->Desc.uRevision,
+- pExtPackData->Desc.strEdition.isEmpty() ? "" : " ",
+- pExtPackData->Desc.strEdition.c_str(),
+- pExtPackData->Desc.strVrdeModule.c_str(),
+- pExtPackData->strWhyUnusable.c_str() ));
+- }
+- else
+- LogRel((" pExtPackData is NULL\n"));
+- }
+-
+- if (!m->llInstalledExtPacks.size())
+- LogRel((" None installed!\n"));
+-}
+-
+-/* vi: set tabstop=4 shiftwidth=4 expandtab: */
+--- VirtualBox-4.1.18.orig/src/VBox/Main/src-all/ExtPackUtil.cpp 2012-06-20 10:17:34.000000000 -0300
++++ /dev/null 2012-07-24 14:48:18.638572110 -0300
+@@ -1,1385 +0,0 @@
+-/* $Id: ExtPackUtil.cpp $ */
+-/** @file
+- * VirtualBox Main - Extension Pack Utilities and definitions, VBoxC, VBoxSVC, ++.
+- */
+-
+-/*
+- * Copyright (C) 2010-2012 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.
+- */
+-
+-
+-/*******************************************************************************
+-* Header Files *
+-*******************************************************************************/
+-#include "../include/ExtPackUtil.h"
+-
+-#include <iprt/ctype.h>
+-#include <iprt/dir.h>
+-#include <iprt/file.h>
+-#include <iprt/manifest.h>
+-#include <iprt/param.h>
+-#include <iprt/path.h>
+-#include <iprt/sha.h>
+-#include <iprt/string.h>
+-#include <iprt/vfs.h>
+-#include <iprt/tar.h>
+-#include <iprt/zip.h>
+-#include <iprt/cpp/xml.h>
+-
+-#include <VBox/log.h>
+-
+-
+-/**
+- * Worker for VBoxExtPackLoadDesc that loads the plug-in descriptors.
+- *
+- * @returns Same as VBoxExtPackLoadDesc.
+- * @param pVBoxExtPackElm
+- * @param pcPlugIns Where to return the number of plug-ins in the
+- * array.
+- * @param paPlugIns Where to return the plug-in descriptor array.
+- * (RTMemFree it even on failure)
+- */
+-static RTCString *
+-vboxExtPackLoadPlugInDescs(const xml::ElementNode *pVBoxExtPackElm,
+- uint32_t *pcPlugIns, PVBOXEXTPACKPLUGINDESC *paPlugIns)
+-{
+- *pcPlugIns = 0;
+- *paPlugIns = NULL;
+-
+- /** @todo plug-ins */
+- NOREF(pVBoxExtPackElm);
+-
+- return NULL;
+-}
+-
+-/**
+- * Clears the extension pack descriptor.
+- *
+- * @param a_pExtPackDesc The descriptor to clear.
+- */
+-static void vboxExtPackClearDesc(PVBOXEXTPACKDESC a_pExtPackDesc)
+-{
+- a_pExtPackDesc->strName.setNull();
+- a_pExtPackDesc->strDescription.setNull();
+- a_pExtPackDesc->strVersion.setNull();
+- a_pExtPackDesc->strEdition.setNull();
+- a_pExtPackDesc->uRevision = 0;
+- a_pExtPackDesc->strMainModule.setNull();
+- a_pExtPackDesc->strVrdeModule.setNull();
+- a_pExtPackDesc->cPlugIns = 0;
+- a_pExtPackDesc->paPlugIns = NULL;
+- a_pExtPackDesc->fShowLicense = false;
+-}
+-
+-/**
+- * Initializes an extension pack descriptor so that it's safe to call free on
+- * it whatever happens later on.
+- *
+- * @param a_pExtPackDesc The descirptor to initialize.
+- */
+-void VBoxExtPackInitDesc(PVBOXEXTPACKDESC a_pExtPackDesc)
+-{
+- vboxExtPackClearDesc(a_pExtPackDesc);
+-}
+-
+-
+-/**
+- * Load the extension pack descriptor from an XML document.
+- *
+- * @returns NULL on success, pointer to an error message on failure (caller
+- * deletes it).
+- * @param a_pDoc Pointer to the the XML document.
+- * @param a_pExtPackDesc Where to store the extension pack descriptor.
+- */
+-static RTCString *vboxExtPackLoadDescFromDoc(xml::Document *a_pDoc, PVBOXEXTPACKDESC a_pExtPackDesc)
+-{
+- /*
+- * Get the main element and check its version.
+- */
+- const xml::ElementNode *pVBoxExtPackElm = a_pDoc->getRootElement();
+- if ( !pVBoxExtPackElm
+- || strcmp(pVBoxExtPackElm->getName(), "VirtualBoxExtensionPack") != 0)
+- return new RTCString("No VirtualBoxExtensionPack element");
+-
+- RTCString strFormatVersion;
+- if (!pVBoxExtPackElm->getAttributeValue("version", strFormatVersion))
+- return new RTCString("Missing format version");
+- if (!strFormatVersion.equals("1.0"))
+- return &(new RTCString("Unsupported format version: "))->append(strFormatVersion);
+-
+- /*
+- * Read and validate mandatory bits.
+- */
+- const xml::ElementNode *pNameElm = pVBoxExtPackElm->findChildElement("Name");
+- if (!pNameElm)
+- return new RTCString("The 'Name' element is missing");
+- const char *pszName = pNameElm->getValue();
+- if (!VBoxExtPackIsValidName(pszName))
+- return &(new RTCString("Invalid name: "))->append(pszName);
+-
+- const xml::ElementNode *pDescElm = pVBoxExtPackElm->findChildElement("Description");
+- if (!pDescElm)
+- return new RTCString("The 'Description' element is missing");
+- const char *pszDesc = pDescElm->getValue();
+- if (!pszDesc || *pszDesc == '\0')
+- return new RTCString("The 'Description' element is empty");
+- if (strpbrk(pszDesc, "\n\r\t\v\b") != NULL)
+- return new RTCString("The 'Description' must not contain control characters");
+-
+- const xml::ElementNode *pVersionElm = pVBoxExtPackElm->findChildElement("Version");
+- if (!pVersionElm)
+- return new RTCString("The 'Version' element is missing");
+- const char *pszVersion = pVersionElm->getValue();
+- if (!pszVersion || *pszVersion == '\0')
+- return new RTCString("The 'Version' element is empty");
+- if (!VBoxExtPackIsValidVersionString(pszVersion))
+- return &(new RTCString("Invalid version string: "))->append(pszVersion);
+-
+- uint32_t uRevision;
+- if (!pVersionElm->getAttributeValue("revision", uRevision))
+- uRevision = 0;
+-
+- const char *pszEdition;
+- if (!pVersionElm->getAttributeValue("edition", pszEdition))
+- pszEdition = "";
+- if (!VBoxExtPackIsValidEditionString(pszEdition))
+- return &(new RTCString("Invalid edition string: "))->append(pszEdition);
+-
+- const xml::ElementNode *pMainModuleElm = pVBoxExtPackElm->findChildElement("MainModule");
+- if (!pMainModuleElm)
+- return new RTCString("The 'MainModule' element is missing");
+- const char *pszMainModule = pMainModuleElm->getValue();
+- if (!pszMainModule || *pszMainModule == '\0')
+- return new RTCString("The 'MainModule' element is empty");
+- if (!VBoxExtPackIsValidModuleString(pszMainModule))
+- return &(new RTCString("Invalid main module string: "))->append(pszMainModule);
+-
+- /*
+- * The VRDE module, optional.
+- * Accept both none and empty as tokens of no VRDE module.
+- */
+- const char *pszVrdeModule = NULL;
+- const xml::ElementNode *pVrdeModuleElm = pVBoxExtPackElm->findChildElement("VRDEModule");
+- if (pVrdeModuleElm)
+- {
+- pszVrdeModule = pVrdeModuleElm->getValue();
+- if (!pszVrdeModule || *pszVrdeModule == '\0')
+- pszVrdeModule = NULL;
+- else if (!VBoxExtPackIsValidModuleString(pszVrdeModule))
+- return &(new RTCString("Invalid VRDE module string: "))->append(pszVrdeModule);
+- }
+-
+- /*
+- * Whether to show the license, optional. (presense is enough here)
+- */
+- const xml::ElementNode *pShowLicenseElm = pVBoxExtPackElm->findChildElement("ShowLicense");
+- bool fShowLicense = pShowLicenseElm != NULL;
+-
+- /*
+- * Parse plug-in descriptions (last because of the manual memory management).
+- */
+- uint32_t cPlugIns = 0;
+- PVBOXEXTPACKPLUGINDESC paPlugIns = NULL;
+- RTCString *pstrRet = vboxExtPackLoadPlugInDescs(pVBoxExtPackElm, &cPlugIns, &paPlugIns);
+- if (pstrRet)
+- {
+- RTMemFree(paPlugIns);
+- return pstrRet;
+- }
+-
+- /*
+- * Everything seems fine, fill in the return values and return successfully.
+- */
+- a_pExtPackDesc->strName = pszName;
+- a_pExtPackDesc->strDescription = pszDesc;
+- a_pExtPackDesc->strVersion = pszVersion;
+- a_pExtPackDesc->strEdition = pszEdition;
+- a_pExtPackDesc->uRevision = uRevision;
+- a_pExtPackDesc->strMainModule = pszMainModule;
+- a_pExtPackDesc->strVrdeModule = pszVrdeModule;
+- a_pExtPackDesc->cPlugIns = cPlugIns;
+- a_pExtPackDesc->paPlugIns = paPlugIns;
+- a_pExtPackDesc->fShowLicense = fShowLicense;
+-
+- return NULL;
+-}
+-
+-/**
+- * Reads the extension pack descriptor.
+- *
+- * @returns NULL on success, pointer to an error message on failure (caller
+- * deletes it).
+- * @param a_pszDir The directory containing the description file.
+- * @param a_pExtPackDesc Where to store the extension pack descriptor.
+- * @param a_pObjInfo Where to store the object info for the file (unix
+- * attribs). Optional.
+- */
+-RTCString *VBoxExtPackLoadDesc(const char *a_pszDir, PVBOXEXTPACKDESC a_pExtPackDesc, PRTFSOBJINFO a_pObjInfo)
+-{
+- vboxExtPackClearDesc(a_pExtPackDesc);
+-
+- /*
+- * Validate, open and parse the XML file.
+- */
+- char szFilePath[RTPATH_MAX];
+- int vrc = RTPathJoin(szFilePath, sizeof(szFilePath), a_pszDir, VBOX_EXTPACK_DESCRIPTION_NAME);
+- if (RT_FAILURE(vrc))
+- return new RTCString("RTPathJoin failed with %Rrc", vrc);
+-
+- RTFSOBJINFO ObjInfo;
+- vrc = RTPathQueryInfoEx(szFilePath, &ObjInfo, RTFSOBJATTRADD_UNIX, RTPATH_F_ON_LINK);
+- if (RT_FAILURE(vrc))
+- return &(new RTCString())->printf("RTPathQueryInfoEx failed with %Rrc", vrc);
+- if (a_pObjInfo)
+- *a_pObjInfo = ObjInfo;
+- if (!RTFS_IS_FILE(ObjInfo.Attr.fMode))
+- {
+- if (RTFS_IS_SYMLINK(ObjInfo.Attr.fMode))
+- return new RTCString("The XML file is symlinked, that is not allowed");
+- return &(new RTCString)->printf("The XML file is not a file (fMode=%#x)", ObjInfo.Attr.fMode);
+- }
+-
+- xml::Document Doc;
+- {
+- xml::XmlFileParser Parser;
+- try
+- {
+- Parser.read(szFilePath, Doc);
+- }
+- catch (xml::XmlError Err)
+- {
+- return new RTCString(Err.what());
+- }
+- }
+-
+- /*
+- * Hand the xml doc over to the common code.
+- */
+- return vboxExtPackLoadDescFromDoc(&Doc, a_pExtPackDesc);
+-}
+-
+-/**
+- * Reads the extension pack descriptor.
+- *
+- * @returns NULL on success, pointer to an error message on failure (caller
+- * deletes it).
+- * @param a_pszDir The directory containing the description file.
+- * @param a_pExtPackDesc Where to store the extension pack descriptor.
+- * @param a_pObjInfo Where to store the object info for the file (unix
+- * attribs). Optional.
+- */
+-RTCString *VBoxExtPackLoadDescFromVfsFile(RTVFSFILE hVfsFile, PVBOXEXTPACKDESC a_pExtPackDesc, PRTFSOBJINFO a_pObjInfo)
+-{
+- vboxExtPackClearDesc(a_pExtPackDesc);
+-
+- /*
+- * Query the object info.
+- */
+- RTFSOBJINFO ObjInfo;
+- int rc = RTVfsFileQueryInfo(hVfsFile, &ObjInfo, RTFSOBJATTRADD_UNIX);
+- if (RT_FAILURE(rc))
+- return &(new RTCString)->printf("RTVfsFileQueryInfo failed: %Rrc", rc);
+- if (a_pObjInfo)
+- *a_pObjInfo = ObjInfo;
+-
+- /*
+- * The simple approach, read the whole thing into memory and pass this to
+- * the XML parser.
+- */
+-
+- /* Check the file size. */
+- if (ObjInfo.cbObject > _1M || ObjInfo.cbObject < 0)
+- return &(new RTCString)->printf("The XML file is too large (%'RU64 bytes)", ObjInfo.cbObject);
+- size_t const cbFile = (size_t)ObjInfo.cbObject;
+-
+- /* Rewind to the start of the file. */
+- rc = RTVfsFileSeek(hVfsFile, 0, RTFILE_SEEK_BEGIN, NULL);
+- if (RT_FAILURE(rc))
+- return &(new RTCString)->printf("RTVfsFileSeek(,0,BEGIN) failed: %Rrc", rc);
+-
+- /* Allocate memory and read the file content into it. */
+- void *pvFile = RTMemTmpAlloc(cbFile);
+- if (!pvFile)
+- return &(new RTCString)->printf("RTMemTmpAlloc(%zu) failed", cbFile);
+-
+- RTCString *pstrErr = NULL;
+- rc = RTVfsFileRead(hVfsFile, pvFile, cbFile, NULL);
+- if (RT_FAILURE(rc))
+- pstrErr = &(new RTCString)->printf("RTVfsFileRead failed: %Rrc", rc);
+-
+- /*
+- * Parse the file.
+- */
+- xml::Document Doc;
+- if (RT_SUCCESS(rc))
+- {
+- xml::XmlMemParser Parser;
+- RTCString strFileName = VBOX_EXTPACK_DESCRIPTION_NAME;
+- try
+- {
+- Parser.read(pvFile, cbFile, strFileName, Doc);
+- }
+- catch (xml::XmlError Err)
+- {
+- pstrErr = new RTCString(Err.what());
+- rc = VERR_PARSE_ERROR;
+- }
+- }
+- RTMemTmpFree(pvFile);
+-
+- /*
+- * Hand the xml doc over to the common code.
+- */
+- if (RT_SUCCESS(rc))
+- pstrErr = vboxExtPackLoadDescFromDoc(&Doc, a_pExtPackDesc);
+-
+- return pstrErr;
+-}
+-
+-/**
+- * Frees all resources associated with a extension pack descriptor.
+- *
+- * @param a_pExtPackDesc The extension pack descriptor which members
+- * should be freed.
+- */
+-void VBoxExtPackFreeDesc(PVBOXEXTPACKDESC a_pExtPackDesc)
+-{
+- if (!a_pExtPackDesc)
+- return;
+-
+- a_pExtPackDesc->strName.setNull();
+- a_pExtPackDesc->strDescription.setNull();
+- a_pExtPackDesc->strVersion.setNull();
+- a_pExtPackDesc->strEdition.setNull();
+- a_pExtPackDesc->uRevision = 0;
+- a_pExtPackDesc->strMainModule.setNull();
+- a_pExtPackDesc->strVrdeModule.setNull();
+- a_pExtPackDesc->cPlugIns = 0;
+- RTMemFree(a_pExtPackDesc->paPlugIns);
+- a_pExtPackDesc->paPlugIns = NULL;
+- a_pExtPackDesc->fShowLicense = false;
+-}
+-
+-/**
+- * Extract the extension pack name from the tarball path.
+- *
+- * @returns String containing the name on success, the caller must delete it.
+- * NULL if no valid name was found or if we ran out of memory.
+- * @param pszTarball The path to the tarball.
+- */
+-RTCString *VBoxExtPackExtractNameFromTarballPath(const char *pszTarball)
+-{
+- /*
+- * Skip ahead to the filename part and count the number of characters
+- * that matches the criteria for a mangled extension pack name.
+- */
+- const char *pszSrc = RTPathFilename(pszTarball);
+- if (!pszSrc)
+- return NULL;
+-
+- size_t off = 0;
+- while (RT_C_IS_ALNUM(pszSrc[off]) || pszSrc[off] == '_')
+- off++;
+-
+- /*
+- * Check min and max name limits.
+- */
+- if ( off > VBOX_EXTPACK_NAME_MAX_LEN
+- || off < VBOX_EXTPACK_NAME_MIN_LEN)
+- return NULL;
+-
+- /*
+- * Return the unmangled name.
+- */
+- return VBoxExtPackUnmangleName(pszSrc, off);
+-}
+-
+-/**
+- * Validates the extension pack name.
+- *
+- * @returns true if valid, false if not.
+- * @param pszName The name to validate.
+- * @sa VBoxExtPackExtractNameFromTarballPath
+- */
+-bool VBoxExtPackIsValidName(const char *pszName)
+-{
+- if (!pszName)
+- return false;
+-
+- /*
+- * Check the characters making up the name, only english alphabet
+- * characters, decimal digits and spaces are allowed.
+- */
+- size_t off = 0;
+- while (pszName[off])
+- {
+- if (!RT_C_IS_ALNUM(pszName[off]) && pszName[off] != ' ')
+- return false;
+- off++;
+- }
+-
+- /*
+- * Check min and max name limits.
+- */
+- if ( off > VBOX_EXTPACK_NAME_MAX_LEN
+- || off < VBOX_EXTPACK_NAME_MIN_LEN)
+- return false;
+-
+- return true;
+-}
+-
+-/**
+- * Checks if an alledged manged extension pack name.
+- *
+- * @returns true if valid, false if not.
+- * @param pszMangledName The mangled name to validate.
+- * @param cchMax The max number of chars to test.
+- * @sa VBoxExtPackMangleName
+- */
+-bool VBoxExtPackIsValidMangledName(const char *pszMangledName, size_t cchMax /*= RTSTR_MAX*/)
+-{
+- if (!pszMangledName)
+- return false;
+-
+- /*
+- * Check the characters making up the name, only english alphabet
+- * characters, decimal digits and underscores (=space) are allowed.
+- */
+- size_t off = 0;
+- while (off < cchMax && pszMangledName[off])
+- {
+- if (!RT_C_IS_ALNUM(pszMangledName[off]) && pszMangledName[off] != '_')
+- return false;
+- off++;
+- }
+-
+- /*
+- * Check min and max name limits.
+- */
+- if ( off > VBOX_EXTPACK_NAME_MAX_LEN
+- || off < VBOX_EXTPACK_NAME_MIN_LEN)
+- return false;
+-
+- return true;
+-}
+-
+-/**
+- * Mangle an extension pack name so it can be used by a directory or file name.
+- *
+- * @returns String containing the mangled name on success, the caller must
+- * delete it. NULL on failure.
+- * @param pszName The unmangled name.
+- * @sa VBoxExtPackUnmangleName, VBoxExtPackIsValidMangledName
+- */
+-RTCString *VBoxExtPackMangleName(const char *pszName)
+-{
+- AssertReturn(VBoxExtPackIsValidName(pszName), NULL);
+-
+- char szTmp[VBOX_EXTPACK_NAME_MAX_LEN + 1];
+- size_t off = 0;
+- char ch;
+- while ((ch = pszName[off]) != '\0')
+- {
+- if (ch == ' ')
+- ch = '_';
+- szTmp[off++] = ch;
+- }
+- szTmp[off] = '\0';
+- Assert(VBoxExtPackIsValidMangledName(szTmp));
+-
+- return new RTCString(szTmp, off);
+-}
+-
+-/**
+- * Unmangle an extension pack name (reverses VBoxExtPackMangleName).
+- *
+- * @returns String containing the mangled name on success, the caller must
+- * delete it. NULL on failure.
+- * @param pszMangledName The mangled name.
+- * @param cchMax The max name length. RTSTR_MAX is fine.
+- * @sa VBoxExtPackMangleName, VBoxExtPackIsValidMangledName
+- */
+-RTCString *VBoxExtPackUnmangleName(const char *pszMangledName, size_t cchMax)
+-{
+- AssertReturn(VBoxExtPackIsValidMangledName(pszMangledName, cchMax), NULL);
+-
+- char szTmp[VBOX_EXTPACK_NAME_MAX_LEN + 1];
+- size_t off = 0;
+- char ch;
+- while ( off < cchMax
+- && (ch = pszMangledName[off]) != '\0')
+- {
+- if (ch == '_')
+- ch = ' ';
+- else
+- AssertReturn(RT_C_IS_ALNUM(ch) || ch == ' ', NULL);
+- szTmp[off++] = ch;
+- }
+- szTmp[off] = '\0';
+- AssertReturn(VBoxExtPackIsValidName(szTmp), NULL);
+-
+- return new RTCString(szTmp, off);
+-}
+-
+-/**
+- * Constructs the extension pack directory path.
+- *
+- * A combination of RTPathJoin and VBoxExtPackMangleName.
+- *
+- * @returns IPRT status code like RTPathJoin.
+- * @param pszExtPackDir Where to return the directory path.
+- * @param cbExtPackDir The size of the return buffer.
+- * @param pszParentDir The parent directory (".../Extensions").
+- * @param pszName The extension pack name, unmangled.
+- */
+-int VBoxExtPackCalcDir(char *pszExtPackDir, size_t cbExtPackDir, const char *pszParentDir, const char *pszName)
+-{
+- AssertReturn(VBoxExtPackIsValidName(pszName), VERR_INTERNAL_ERROR_5);
+-
+- RTCString *pstrMangledName = VBoxExtPackMangleName(pszName);
+- if (!pstrMangledName)
+- return VERR_INTERNAL_ERROR_4;
+-
+- int vrc = RTPathJoin(pszExtPackDir, cbExtPackDir, pszParentDir, pstrMangledName->c_str());
+- delete pstrMangledName;
+-
+- return vrc;
+-}
+-
+-
+-/**
+- * Validates the extension pack version string.
+- *
+- * @returns true if valid, false if not.
+- * @param pszVersion The version string to validate.
+- */
+-bool VBoxExtPackIsValidVersionString(const char *pszVersion)
+-{
+- if (!pszVersion || *pszVersion == '\0')
+- return false;
+-
+- /* 1.x.y.z... */
+- for (;;)
+- {
+- if (!RT_C_IS_DIGIT(*pszVersion))
+- return false;
+- do
+- pszVersion++;
+- while (RT_C_IS_DIGIT(*pszVersion));
+- if (*pszVersion != '.')
+- break;
+- pszVersion++;
+- }
+-
+- /* upper case string + numbers indicating the build type */
+- if (*pszVersion == '-' || *pszVersion == '_')
+- {
+- /** @todo Should probably restrict this to known build types (alpha,
+- * beta, rc, ++). */
+- do
+- pszVersion++;
+- while ( RT_C_IS_DIGIT(*pszVersion)
+- || RT_C_IS_UPPER(*pszVersion)
+- || *pszVersion == '-'
+- || *pszVersion == '_');
+- }
+-
+- return *pszVersion == '\0';
+-}
+-
+-/**
+- * Validates the extension pack edition string.
+- *
+- * @returns true if valid, false if not.
+- * @param pszEdition The edition string to validate.
+- */
+-bool VBoxExtPackIsValidEditionString(const char *pszEdition)
+-{
+- if (*pszEdition)
+- {
+- if (!RT_C_IS_UPPER(*pszEdition))
+- return false;
+-
+- do
+- pszEdition++;
+- while ( RT_C_IS_UPPER(*pszEdition)
+- || RT_C_IS_DIGIT(*pszEdition)
+- || *pszEdition == '-'
+- || *pszEdition == '_');
+- }
+- return *pszEdition == '\0';
+-}
+-
+-/**
+- * Validates an extension pack module string.
+- *
+- * @returns true if valid, false if not.
+- * @param pszModule The module string to validate.
+- */
+-bool VBoxExtPackIsValidModuleString(const char *pszModule)
+-{
+- if (!pszModule || *pszModule == '\0')
+- return false;
+-
+- /* Restricted charset, no extensions (dots). */
+- while ( RT_C_IS_ALNUM(*pszModule)
+- || *pszModule == '-'
+- || *pszModule == '_')
+- pszModule++;
+-
+- return *pszModule == '\0';
+-}
+-
+-/**
+- * RTStrPrintfv wrapper.
+- *
+- * @returns @a rc
+- * @param rc The status code to return.
+- * @param pszError The error buffer.
+- * @param cbError The size of the buffer.
+- * @param pszFormat The error message format string.
+- * @param ... Format arguments.
+- */
+-static int vboxExtPackReturnError(int rc, char *pszError, size_t cbError, const char *pszFormat, ...)
+-{
+- va_list va;
+- va_start(va, pszFormat);
+- RTStrPrintfV(pszError, cbError, pszFormat, va);
+- va_end(va);
+- return rc;
+-}
+-
+-/**
+- * RTStrPrintfv wrapper.
+- *
+- * @param pszError The error buffer.
+- * @param cbError The size of the buffer.
+- * @param pszFormat The error message format string.
+- * @param ... Format arguments.
+- */
+-static void vboxExtPackSetError(char *pszError, size_t cbError, const char *pszFormat, ...)
+-{
+- va_list va;
+- va_start(va, pszFormat);
+- RTStrPrintfV(pszError, cbError, pszFormat, va);
+- va_end(va);
+-}
+-
+-/**
+- * Verifies the manifest and its signature.
+- *
+- * @returns VBox status code, failures with message.
+- * @param hManifestFile The xml from the extension pack.
+- * @param pszExtPackName The expected extension pack name. This can be
+- * NULL, in which we don't have any expectations.
+- * @param pszError Where to store an error message on failure.
+- * @param cbError The size of the buffer @a pszError points to.
+- */
+-static int vboxExtPackVerifyXml(RTVFSFILE hXmlFile, const char *pszExtPackName, char *pszError, size_t cbError)
+-{
+- /*
+- * Load the XML.
+- */
+- VBOXEXTPACKDESC ExtPackDesc;
+- RTCString *pstrErr = VBoxExtPackLoadDescFromVfsFile(hXmlFile, &ExtPackDesc, NULL);
+- if (pstrErr)
+- {
+- RTStrCopy(pszError, cbError, pstrErr->c_str());
+- delete pstrErr;
+- return VERR_PARSE_ERROR;
+- }
+-
+- /*
+- * Check the name.
+- */
+- /** @todo drop this restriction after the old install interface is
+- * dropped. */
+- int rc = VINF_SUCCESS;
+- if ( pszExtPackName
+- && !ExtPackDesc.strName.equalsIgnoreCase(pszExtPackName))
+- rc = vboxExtPackReturnError(VERR_NOT_EQUAL, pszError, cbError,
+- "The name of the downloaded file and the name stored inside the extension pack does not match"
+- " (xml='%s' file='%s')", ExtPackDesc.strName.c_str(), pszExtPackName);
+- return rc;
+-}
+-
+-/**
+- * Verifies the manifest and its signature.
+- *
+- * @returns VBox status code, failures with message.
+- * @param hOurManifest The manifest we compiled.
+- * @param hManifestFile The manifest file in the extension pack.
+- * @param hSignatureFile The manifest signature file.
+- * @param pszError Where to store an error message on failure.
+- * @param cbError The size of the buffer @a pszError points to.
+- */
+-static int vboxExtPackVerifyManifestAndSignature(RTMANIFEST hOurManifest, RTVFSFILE hManifestFile, RTVFSFILE hSignatureFile,
+- char *pszError, size_t cbError)
+-{
+- /*
+- * Read the manifest from the extension pack.
+- */
+- int rc = RTVfsFileSeek(hManifestFile, 0, RTFILE_SEEK_BEGIN, NULL);
+- if (RT_FAILURE(rc))
+- return vboxExtPackReturnError(rc, pszError, cbError, "RTVfsFileSeek failed: %Rrc", rc);
+-
+- RTMANIFEST hTheirManifest;
+- rc = RTManifestCreate(0 /*fFlags*/, &hTheirManifest);
+- if (RT_FAILURE(rc))
+- return vboxExtPackReturnError(rc, pszError, cbError, "RTManifestCreate failed: %Rrc", rc);
+-
+- RTVFSIOSTREAM hVfsIos = RTVfsFileToIoStream(hManifestFile);
+- rc = RTManifestReadStandard(hTheirManifest, hVfsIos);
+- RTVfsIoStrmRelease(hVfsIos);
+- if (RT_SUCCESS(rc))
+- {
+- /*
+- * Compare the manifests.
+- */
+- static const char *s_apszIgnoreEntries[] =
+- {
+- VBOX_EXTPACK_MANIFEST_NAME,
+- VBOX_EXTPACK_SIGNATURE_NAME,
+- "./" VBOX_EXTPACK_MANIFEST_NAME,
+- "./" VBOX_EXTPACK_SIGNATURE_NAME,
+- NULL
+- };
+- char szError[RTPATH_MAX];
+- rc = RTManifestEqualsEx(hOurManifest, hTheirManifest, &s_apszIgnoreEntries[0], NULL,
+- RTMANIFEST_EQUALS_IGN_MISSING_ATTRS /*fFlags*/,
+- szError, sizeof(szError));
+- if (RT_SUCCESS(rc))
+- {
+- /*
+- * Validate the manifest file signature.
+- */
+- /** @todo implement signature stuff */
+- NOREF(hSignatureFile);
+-
+- }
+- else if (rc == VERR_NOT_EQUAL && szError[0])
+- vboxExtPackSetError(pszError, cbError, "Manifest mismatch: %s", szError);
+- else
+- vboxExtPackSetError(pszError, cbError, "RTManifestEqualsEx failed: %Rrc", rc);
+-#if 0
+- RTVFSIOSTREAM hVfsIosStdOut = NIL_RTVFSIOSTREAM;
+- RTVfsIoStrmFromStdHandle(RTHANDLESTD_OUTPUT, RTFILE_O_WRITE, true, &hVfsIosStdOut);
+- RTVfsIoStrmWrite(hVfsIosStdOut, "Our:\n", sizeof("Our:\n") - 1, true, NULL);
+- RTManifestWriteStandard(hOurManifest, hVfsIosStdOut);
+- RTVfsIoStrmWrite(hVfsIosStdOut, "Their:\n", sizeof("Their:\n") - 1, true, NULL);
+- RTManifestWriteStandard(hTheirManifest, hVfsIosStdOut);
+-#endif
+- }
+- else
+- vboxExtPackSetError(pszError, cbError, "Error parsing '%s': %Rrc", VBOX_EXTPACK_MANIFEST_NAME, rc);
+-
+- RTManifestRelease(hTheirManifest);
+- return rc;
+-}
+-
+-
+-/**
+- * Verifies the file digest (if specified) and returns the SHA-256 of the file.
+- *
+- * @returns
+- * @param hFileManifest Manifest containing a SHA-256 digest of the file
+- * that was calculated as the file was processed.
+- * @param pszFileDigest SHA-256 digest of the file.
+- * @param pStrDigest Where to return the SHA-256 digest. Optional.
+- * @param pszError Where to write an error message on failure.
+- * @param cbError The size of the @a pszError buffer.
+- */
+-static int vboxExtPackVerifyFileDigest(RTMANIFEST hFileManifest, const char *pszFileDigest,
+- RTCString *pStrDigest, char *pszError, size_t cbError)
+-{
+- /*
+- * Extract the SHA-256 entry for the extpack file.
+- */
+- char szCalculatedDigest[RTSHA256_DIGEST_LEN + 1];
+- int rc = RTManifestEntryQueryAttr(hFileManifest, "extpack", NULL /*no name*/, RTMANIFEST_ATTR_SHA256,
+- szCalculatedDigest, sizeof(szCalculatedDigest), NULL);
+- if (RT_SUCCESS(rc))
+- {
+- /*
+- * Convert the two strings to binary form before comparing.
+- * We convert the calculated hash even if we don't have anything to
+- * compare with, just to validate it.
+- */
+- uint8_t abCalculatedHash[RTSHA256_HASH_SIZE];
+- rc = RTSha256FromString(szCalculatedDigest, abCalculatedHash);
+- if (RT_SUCCESS(rc))
+- {
+- if ( pszFileDigest
+- && *pszFileDigest != '\0')
+- {
+- uint8_t abFileHash[RTSHA256_HASH_SIZE];
+- rc = RTSha256FromString(pszFileDigest, abFileHash);
+- if (RT_SUCCESS(rc))
+- {
+- if (memcmp(abFileHash, abCalculatedHash, sizeof(abFileHash)))
+- {
+- vboxExtPackSetError(pszError, cbError, "The extension pack file has changed (SHA-256 mismatch)");
+- rc = VERR_NOT_EQUAL;
+- }
+- }
+- else
+- vboxExtPackSetError(pszError, cbError, "Bad SHA-256 '%s': %Rrc", szCalculatedDigest, rc);
+- }
+-
+- /*
+- * Set the output hash on success.
+- */
+- if (pStrDigest && RT_SUCCESS(rc))
+- {
+- try
+- {
+- *pStrDigest = szCalculatedDigest;
+- }
+- catch (std::bad_alloc)
+- {
+- rc = VERR_NO_MEMORY;
+- }
+- }
+- }
+- else
+- vboxExtPackSetError(pszError, cbError, "Bad SHA-256 '%s': %Rrc", szCalculatedDigest, rc);
+- }
+- else
+- vboxExtPackSetError(pszError, cbError, "RTManifestEntryGetAttr: %Rrc", rc);
+- return rc;
+-}
+-
+-
+-
+-/**
+- * Validates a standard file.
+- *
+- * Generally all files are
+- *
+- * @returns VBox status code, failure message in @a pszError.
+- * @param pszAdjName The adjusted member name.
+- * @param enmType The VFS object type.
+- * @param phVfsObj The pointer to the VFS object handle variable.
+- * This is both input and output.
+- * @param phVfsFile Where to store the handle to the memorized
+- * file. This is NULL for license files.
+- * @param pszError Where to write an error message on failure.
+- * @param cbError The size of the @a pszError buffer.
+- */
+-static int VBoxExtPackValidateStandardFile(const char *pszAdjName, RTVFSOBJTYPE enmType,
+- PRTVFSOBJ phVfsObj, PRTVFSFILE phVfsFile, char *pszError, size_t cbError)
+-{
+- int rc;
+-
+- /*
+- * Make sure it's a file and that it isn't too large.
+- */
+- if (phVfsFile && *phVfsFile != NIL_RTVFSFILE)
+- rc = vboxExtPackReturnError(VERR_DUPLICATE, pszError, cbError,
+- "There can only be one '%s'", pszAdjName);
+- else if (enmType != RTVFSOBJTYPE_IO_STREAM && enmType != RTVFSOBJTYPE_FILE)
+- rc = vboxExtPackReturnError(VERR_NOT_A_FILE, pszError, cbError,
+- "Standard member '%s' is not a file", pszAdjName);
+- else
+- {
+- RTFSOBJINFO ObjInfo;
+- rc = RTVfsObjQueryInfo(*phVfsObj, &ObjInfo, RTFSOBJATTRADD_NOTHING);
+- if (RT_SUCCESS(rc))
+- {
+- if (!RTFS_IS_FILE(ObjInfo.Attr.fMode))
+- rc = vboxExtPackReturnError(VERR_NOT_A_FILE, pszError, cbError,
+- "Standard member '%s' is not a file", pszAdjName);
+- else if (ObjInfo.cbObject >= _1M)
+- rc = vboxExtPackReturnError(VERR_OUT_OF_RANGE, pszError, cbError,
+- "Standard member '%s' is too large: %'RU64 bytes (max 1 MB)",
+- pszAdjName, (uint64_t)ObjInfo.cbObject);
+- else
+- {
+- /*
+- * Make an in memory copy of the stream and check that the file
+- * is UTF-8 clean.
+- */
+- RTVFSIOSTREAM hVfsIos = RTVfsObjToIoStream(*phVfsObj);
+- RTVFSFILE hVfsFile;
+- rc = RTVfsMemorizeIoStreamAsFile(hVfsIos, RTFILE_O_READ, &hVfsFile);
+- if (RT_SUCCESS(rc))
+- {
+- rc = RTVfsIoStrmValidateUtf8Encoding(hVfsIos,
+- RTVFS_VALIDATE_UTF8_BY_RTC_3629 | RTVFS_VALIDATE_UTF8_NO_NULL,
+- NULL);
+- if (RT_SUCCESS(rc))
+- {
+- /*
+- * Replace *phVfsObj with the memorized file.
+- */
+- rc = RTVfsFileSeek(hVfsFile, 0, RTFILE_SEEK_BEGIN, NULL);
+- if (RT_SUCCESS(rc))
+- {
+- RTVfsObjRelease(*phVfsObj);
+- *phVfsObj = RTVfsObjFromFile(hVfsFile);
+- }
+- else
+- vboxExtPackSetError(pszError, cbError, "RTVfsFileSeek failed on '%s': %Rrc", pszAdjName, rc);
+- }
+-
+- if (phVfsFile && RT_SUCCESS(rc))
+- *phVfsFile = hVfsFile;
+- else
+- RTVfsFileRelease(hVfsFile);
+- }
+- else
+- vboxExtPackSetError(pszError, cbError, "RTVfsMemorizeIoStreamAsFile failed on '%s': %Rrc", pszAdjName, rc);
+- RTVfsIoStrmRelease(hVfsIos);
+- }
+- }
+- else
+- vboxExtPackSetError(pszError, cbError, "RTVfsObjQueryInfo failed on '%s': %Rrc", pszAdjName, rc);
+- }
+- return rc;
+-}
+-
+-
+-/**
+- * Validates a name in an extension pack.
+- *
+- * We restrict the charset to try make sure the extension pack can be unpacked
+- * on all file systems.
+- *
+- * @returns VBox status code, failures with message.
+- * @param pszName The name to validate.
+- * @param pszError Where to store an error message on failure.
+- * @param cbError The size of the buffer @a pszError points to.
+- */
+-static int vboxExtPackValidateMemberName(const char *pszName, char *pszError, size_t cbError)
+-{
+- if (RTPathStartsWithRoot(pszName))
+- return vboxExtPackReturnError(VERR_PATH_IS_NOT_RELATIVE, pszError, cbError, "'%s': starts with root spec", pszName);
+-
+- const char *pszErr = NULL;
+- const char *psz = pszName;
+- int ch;
+- while ((ch = *psz) != '\0')
+- {
+- /* Character set restrictions. */
+- if (ch < 0 || ch >= 128)
+- {
+- pszErr = "Only 7-bit ASCII allowed";
+- break;
+- }
+- if (ch <= 31 || ch == 127)
+- {
+- pszErr = "No control characters are not allowed";
+- break;
+- }
+- if (ch == '\\')
+- {
+- pszErr = "Only backward slashes are not allowed";
+- break;
+- }
+- if (strchr("'\":;*?|[]<>(){}", ch))
+- {
+- pszErr = "The characters ', \", :, ;, *, ?, |, [, ], <, >, (, ), { and } are not allowed";
+- break;
+- }
+-
+- /* Take the simple way out and ban all ".." sequences. */
+- if ( ch == '.'
+- && psz[1] == '.')
+- {
+- pszErr = "Double dot sequence are not allowed";
+- break;
+- }
+-
+- /* Keep the tree shallow or the hardening checks will fail. */
+- if (psz - pszName > VBOX_EXTPACK_MAX_MEMBER_NAME_LENGTH)
+- {
+- pszErr = "Too long";
+- break;
+- }
+-
+- /* advance */
+- psz++;
+- }
+-
+- if (pszErr)
+- return vboxExtPackReturnError(VERR_INVALID_NAME, pszError, cbError,
+- "Bad member name '%s' (pos %zu): %s", pszName, (size_t)(psz - pszName), pszErr);
+- return RTEXITCODE_SUCCESS;
+-}
+-
+-
+-/**
+- * Validates a file in an extension pack.
+- *
+- * @returns VBox status code, failures with message.
+- * @param pszName The name of the file.
+- * @param hVfsObj The VFS object.
+- * @param pszError Where to store an error message on failure.
+- * @param cbError The size of the buffer @a pszError points to.
+- */
+-static int vboxExtPackValidateMemberFile(const char *pszName, RTVFSOBJ hVfsObj, char *pszError, size_t cbError)
+-{
+- int rc = vboxExtPackValidateMemberName(pszName, pszError, cbError);
+- if (RT_SUCCESS(rc))
+- {
+- RTFSOBJINFO ObjInfo;
+- rc = RTVfsObjQueryInfo(hVfsObj, &ObjInfo, RTFSOBJATTRADD_NOTHING);
+- if (RT_SUCCESS(rc))
+- {
+- if (ObjInfo.cbObject >= 9*_1G64)
+- rc = vboxExtPackReturnError(VERR_OUT_OF_RANGE, pszError, cbError,
+- "'%s': too large (%'RU64 bytes)",
+- pszName, (uint64_t)ObjInfo.cbObject);
+- if (!RTFS_IS_FILE(ObjInfo.Attr.fMode))
+- rc = vboxExtPackReturnError(VERR_NOT_A_FILE, pszError, cbError,
+- "The alleged file '%s' has a mode mask stating otherwise (%RTfmode)",
+- pszName, ObjInfo.Attr.fMode);
+- }
+- else
+- vboxExtPackSetError(pszError, cbError, "RTVfsObjQueryInfo failed on '%s': %Rrc", pszName, rc);
+- }
+- return rc;
+-}
+-
+-
+-/**
+- * Validates a directory in an extension pack.
+- *
+- * @returns VBox status code, failures with message.
+- * @param pszName The name of the directory.
+- * @param hVfsObj The VFS object.
+- * @param pszError Where to store an error message on failure.
+- * @param cbError The size of the buffer @a pszError points to.
+- */
+-static int vboxExtPackValidateMemberDir(const char *pszName, RTVFSOBJ hVfsObj, char *pszError, size_t cbError)
+-{
+- int rc = vboxExtPackValidateMemberName(pszName, pszError, cbError);
+- if (RT_SUCCESS(rc))
+- {
+- RTFSOBJINFO ObjInfo;
+- rc = RTVfsObjQueryInfo(hVfsObj, &ObjInfo, RTFSOBJATTRADD_NOTHING);
+- if (RT_SUCCESS(rc))
+- {
+- if (!RTFS_IS_DIRECTORY(ObjInfo.Attr.fMode))
+- rc = vboxExtPackReturnError(VERR_NOT_A_DIRECTORY, pszError, cbError,
+- "The alleged directory '%s' has a mode mask saying differently (%RTfmode)",
+- pszName, ObjInfo.Attr.fMode);
+- }
+- else
+- vboxExtPackSetError(pszError, cbError, "RTVfsObjQueryInfo failed on '%s': %Rrc", pszName, rc);
+- }
+- return rc;
+-}
+-
+-/**
+- * Validates a member of an extension pack.
+- *
+- * @returns VBox status code, failures with message.
+- * @param pszName The name of the directory.
+- * @param enmType The object type.
+- * @param hVfsObj The VFS object.
+- * @param pszError Where to store an error message on failure.
+- * @param cbError The size of the buffer @a pszError points to.
+- */
+-int VBoxExtPackValidateMember(const char *pszName, RTVFSOBJTYPE enmType, RTVFSOBJ hVfsObj, char *pszError, size_t cbError)
+-{
+- Assert(cbError > 0);
+- *pszError = '\0';
+-
+- int rc;
+- if ( enmType == RTVFSOBJTYPE_FILE
+- || enmType == RTVFSOBJTYPE_IO_STREAM)
+- rc = vboxExtPackValidateMemberFile(pszName, hVfsObj, pszError, cbError);
+- else if ( enmType == RTVFSOBJTYPE_DIR
+- || enmType == RTVFSOBJTYPE_BASE)
+- rc = vboxExtPackValidateMemberDir(pszName, hVfsObj, pszError, cbError);
+- else
+- rc = vboxExtPackReturnError(VERR_UNEXPECTED_FS_OBJ_TYPE, pszError, cbError,
+- "'%s' is not a file or directory (enmType=%d)", pszName, enmType);
+- return rc;
+-}
+-
+-
+-/**
+- * Rewinds the tarball file handle and creates a gunzip | tar chain that
+- * results in a filesystem stream.
+- *
+- * @returns VBox status code, failures with message.
+- * @param hTarballFile The handle to the tarball file.
+- * @param pszError Where to store an error message on failure.
+- * @param cbError The size of the buffer @a pszError points to.
+- * @param phTarFss Where to return the filesystem stream handle.
+- * @param phFileManifest Where to return a manifest where the tarball is
+- * gettting hashed. The entry will be called
+- * "extpack" and be ready when the file system
+- * stream is at an end. Optional.
+- */
+-int VBoxExtPackOpenTarFss(RTFILE hTarballFile, char *pszError, size_t cbError, PRTVFSFSSTREAM phTarFss, PRTMANIFEST phFileManifest)
+-{
+- Assert(cbError > 0);
+- *pszError = '\0';
+- *phTarFss = NIL_RTVFSFSSTREAM;
+-
+- /*
+- * Rewind the file and set up a VFS chain for it.
+- */
+- int rc = RTFileSeek(hTarballFile, 0, RTFILE_SEEK_BEGIN, NULL);
+- if (RT_FAILURE(rc))
+- return vboxExtPackReturnError(rc, pszError, cbError, "Failed seeking to the start of the tarball: %Rrc", rc);
+-
+- RTVFSIOSTREAM hTarballIos;
+- rc = RTVfsIoStrmFromRTFile(hTarballFile, RTFILE_O_READ | RTFILE_O_DENY_WRITE | RTFILE_O_OPEN, true /*fLeaveOpen*/,
+- &hTarballIos);
+- if (RT_FAILURE(rc))
+- return vboxExtPackReturnError(rc, pszError, cbError, "RTVfsIoStrmFromRTFile failed: %Rrc", rc);
+-
+- RTMANIFEST hFileManifest = NIL_RTMANIFEST;
+- rc = RTManifestCreate(0 /*fFlags*/, &hFileManifest);
+- if (RT_SUCCESS(rc))
+- {
+- RTVFSIOSTREAM hPtIos;
+- rc = RTManifestEntryAddPassthruIoStream(hFileManifest, hTarballIos, "extpack", RTMANIFEST_ATTR_SHA256, true /*read*/, &hPtIos);
+- if (RT_SUCCESS(rc))
+- {
+- RTVFSIOSTREAM hGunzipIos;
+- rc = RTZipGzipDecompressIoStream(hPtIos, 0 /*fFlags*/, &hGunzipIos);
+- if (RT_SUCCESS(rc))
+- {
+- RTVFSFSSTREAM hTarFss;
+- rc = RTZipTarFsStreamFromIoStream(hGunzipIos, 0 /*fFlags*/, &hTarFss);
+- if (RT_SUCCESS(rc))
+- {
+- RTVfsIoStrmRelease(hPtIos);
+- RTVfsIoStrmRelease(hGunzipIos);
+- RTVfsIoStrmRelease(hTarballIos);
+- *phTarFss = hTarFss;
+- if (phFileManifest)
+- *phFileManifest = hFileManifest;
+- else
+- RTManifestRelease(hFileManifest);
+- return VINF_SUCCESS;
+- }
+-
+- vboxExtPackSetError(pszError, cbError, "RTZipTarFsStreamFromIoStream failed: %Rrc", rc);
+- RTVfsIoStrmRelease(hGunzipIos);
+- }
+- else
+- vboxExtPackSetError(pszError, cbError, "RTZipGzipDecompressIoStream failed: %Rrc", rc);
+- RTVfsIoStrmRelease(hPtIos);
+- }
+- else
+- vboxExtPackSetError(pszError, cbError, "RTManifestEntryAddPassthruIoStream failed: %Rrc", rc);
+- RTManifestRelease(hFileManifest);
+- }
+- else
+- vboxExtPackSetError(pszError, cbError, "RTManifestCreate failed: %Rrc", rc);
+-
+- RTVfsIoStrmRelease(hTarballIos);
+- return rc;
+-}
+-
+-
+-/**
+- * Validates the extension pack tarball prior to unpacking.
+- *
+- * Operations performed:
+- * - Mandatory files.
+- * - Manifest check.
+- * - Manifest seal check.
+- * - XML check, match name.
+- *
+- * @returns VBox status code, failures with message.
+- * @param hTarballFile The handle to open the @a pszTarball file.
+- * @param pszExtPackName The name of the extension pack name. NULL if
+- * the name is not fixed.
+- * @param pszTarball The name of the tarball in case we have to
+- * complain about something.
+- * @param pszTarballDigest The SHA-256 digest of the tarball. Empty string
+- * if no digest available.
+- * @param pszError Where to store an error message on failure.
+- * @param cbError The size of the buffer @a pszError points to.
+- * @param phValidManifest Where to optionally return the handle to fully
+- * validated the manifest for the extension pack.
+- * This includes all files.
+- * @param phXmlFile Where to optionally return the memorized XML
+- * file.
+- * @param pStrDigest Where to return the digest of the file.
+- * Optional.
+- */
+-int VBoxExtPackValidateTarball(RTFILE hTarballFile, const char *pszExtPackName,
+- const char *pszTarball, const char *pszTarballDigest,
+- char *pszError, size_t cbError,
+- PRTMANIFEST phValidManifest, PRTVFSFILE phXmlFile, RTCString *pStrDigest)
+-{
+- /*
+- * Clear return values.
+- */
+- if (phValidManifest)
+- *phValidManifest = NIL_RTMANIFEST;
+- if (phXmlFile)
+- *phXmlFile = NIL_RTVFSFILE;
+- Assert(cbError > 1);
+- *pszError = '\0';
+- NOREF(pszTarball);
+-
+- /*
+- * Open the tar.gz filesystem stream and set up an manifest in-memory file.
+- */
+- RTMANIFEST hFileManifest;
+- RTVFSFSSTREAM hTarFss;
+- int rc = VBoxExtPackOpenTarFss(hTarballFile, pszError, cbError, &hTarFss, &hFileManifest);
+- if (RT_FAILURE(rc))
+- return rc;
+-
+- RTMANIFEST hOurManifest;
+- rc = RTManifestCreate(0 /*fFlags*/, &hOurManifest);
+- if (RT_SUCCESS(rc))
+- {
+- /*
+- * Process the tarball (would be nice to move this to a function).
+- */
+- RTVFSFILE hXmlFile = NIL_RTVFSFILE;
+- RTVFSFILE hManifestFile = NIL_RTVFSFILE;
+- RTVFSFILE hSignatureFile = NIL_RTVFSFILE;
+- for (;;)
+- {
+- /*
+- * Get the next stream object.
+- */
+- char *pszName;
+- RTVFSOBJ hVfsObj;
+- RTVFSOBJTYPE enmType;
+- rc = RTVfsFsStrmNext(hTarFss, &pszName, &enmType, &hVfsObj);
+- if (RT_FAILURE(rc))
+- {
+- if (rc != VERR_EOF)
+- vboxExtPackSetError(pszError, cbError, "RTVfsFsStrmNext failed: %Rrc", rc);
+- else
+- rc = VINF_SUCCESS;
+- break;
+- }
+- const char *pszAdjName = pszName[0] == '.' && pszName[1] == '/' ? &pszName[2] : pszName;
+-
+- /*
+- * Check the type & name validity, performing special tests on
+- * standard extension pack member files.
+- *
+- * N.B. We will always reach the end of the loop before breaking on
+- * failure - cleanup reasons.
+- */
+- rc = VBoxExtPackValidateMember(pszName, enmType, hVfsObj, pszError, cbError);
+- if (RT_SUCCESS(rc))
+- {
+- PRTVFSFILE phVfsFile = NULL;
+- if (!strcmp(pszAdjName, VBOX_EXTPACK_DESCRIPTION_NAME))
+- phVfsFile = &hXmlFile;
+- else if (!strcmp(pszAdjName, VBOX_EXTPACK_MANIFEST_NAME))
+- phVfsFile = &hManifestFile;
+- else if (!strcmp(pszAdjName, VBOX_EXTPACK_SIGNATURE_NAME))
+- phVfsFile = &hSignatureFile;
+- else if (!strncmp(pszAdjName, VBOX_EXTPACK_LICENSE_NAME_PREFIX, sizeof(VBOX_EXTPACK_LICENSE_NAME_PREFIX) - 1))
+- rc = VBoxExtPackValidateStandardFile(pszAdjName, enmType, &hVfsObj, NULL, pszError, cbError);
+- if (phVfsFile)
+- rc = VBoxExtPackValidateStandardFile(pszAdjName, enmType, &hVfsObj, phVfsFile, pszError, cbError);
+- }
+-
+- /*
+- * Add any I/O stream to the manifest
+- */
+- if ( RT_SUCCESS(rc)
+- && ( enmType == RTVFSOBJTYPE_FILE
+- || enmType == RTVFSOBJTYPE_IO_STREAM))
+- {
+- RTVFSIOSTREAM hVfsIos = RTVfsObjToIoStream(hVfsObj);
+- rc = RTManifestEntryAddIoStream(hOurManifest, hVfsIos, pszAdjName, RTMANIFEST_ATTR_SIZE | RTMANIFEST_ATTR_SHA256);
+- if (RT_FAILURE(rc))
+- vboxExtPackSetError(pszError, cbError, "RTManifestEntryAddIoStream failed on '%s': %Rrc", pszAdjName, rc);
+- RTVfsIoStrmRelease(hVfsIos);
+- }
+-
+- /*
+- * Clean up and break out on failure.
+- */
+- RTVfsObjRelease(hVfsObj);
+- RTStrFree(pszName);
+- if (RT_FAILURE(rc))
+- break;
+- }
+-
+- /*
+- * Check the integrity of the tarball file.
+- */
+- if (RT_SUCCESS(rc))
+- {
+- RTVfsFsStrmRelease(hTarFss);
+- hTarFss = NIL_RTVFSFSSTREAM;
+- rc = vboxExtPackVerifyFileDigest(hFileManifest, pszTarballDigest, pStrDigest, pszError, cbError);
+- }
+-
+- /*
+- * If we've successfully processed the tarball, verify that the
+- * mandatory files are present.
+- */
+- if (RT_SUCCESS(rc))
+- {
+- if (hXmlFile == NIL_RTVFSFILE)
+- rc = vboxExtPackReturnError(VERR_MISSING, pszError, cbError, "Mandator file '%s' is missing", VBOX_EXTPACK_DESCRIPTION_NAME);
+- if (hManifestFile == NIL_RTVFSFILE)
+- rc = vboxExtPackReturnError(VERR_MISSING, pszError, cbError, "Mandator file '%s' is missing", VBOX_EXTPACK_MANIFEST_NAME);
+- if (hSignatureFile == NIL_RTVFSFILE)
+- rc = vboxExtPackReturnError(VERR_MISSING, pszError, cbError, "Mandator file '%s' is missing", VBOX_EXTPACK_SIGNATURE_NAME);
+- }
+-
+- /*
+- * Check the manifest and it's signature.
+- */
+- if (RT_SUCCESS(rc))
+- rc = vboxExtPackVerifyManifestAndSignature(hOurManifest, hManifestFile, hSignatureFile, pszError, cbError);
+-
+- /*
+- * Check the XML.
+- */
+- if (RT_SUCCESS(rc))
+- rc = vboxExtPackVerifyXml(hXmlFile, pszExtPackName, pszError, cbError);
+-
+- /*
+- * Returns objects.
+- */
+- if (RT_SUCCESS(rc))
+- {
+- if (phValidManifest)
+- {
+- RTManifestRetain(hOurManifest);
+- *phValidManifest = hOurManifest;
+- }
+- if (phXmlFile)
+- {
+- RTVfsFileRetain(hXmlFile);
+- *phXmlFile = hXmlFile;
+- }
+- }
+-
+- /*
+- * Release our object references.
+- */
+- RTManifestRelease(hOurManifest);
+- RTVfsFileRelease(hXmlFile);
+- RTVfsFileRelease(hManifestFile);
+- RTVfsFileRelease(hSignatureFile);
+- }
+- else
+- vboxExtPackSetError(pszError, cbError, "RTManifestCreate failed: %Rrc", rc);
+- RTVfsFsStrmRelease(hTarFss);
+- RTManifestRelease(hFileManifest);
+-
+- return rc;
+-}
+-
+--- VirtualBox-4.1.18.orig/include/Makefile.kmk 2012-06-20 10:07:49.000000000 -0300
++++ VirtualBox-4.1.18/include/Makefile.kmk 2012-07-24 21:11:57.007068865 -0300
+@@ -51,7 +51,6 @@
+ VBox/vd-cache-plugin.h \
+ VBox/vmm/uvm.h \
+ VBox/vscsi.h \
+- $(wildcard VBox/ExtPack/*.h ) \
+ iprt/alloca.h \
+ iprt/tcp.h \
+ iprt/localipc.h \
+--- VirtualBox-4.1.18.orig/src/Makefile.kmk 2012-06-20 10:07:57.000000000 -0300
++++ VirtualBox-4.1.18/src/Makefile.kmk 2012-07-24 22:51:10.206996034 -0300
+@@ -26,14 +26,6 @@
+ include $(PATH_SUB_CURRENT)/VBox/Makefile.kmk
+ include $(PATH_SUB_CURRENT)/libs/Makefile.kmk
+
+-else if defined(VBOX_ONLY_EXTPACKS)
+- include $(PATH_SUB_CURRENT)/bldprogs/Makefile.kmk
+- include $(PATH_SUB_CURRENT)/VBox/Makefile.kmk
+- include $(PATH_SUB_CURRENT)/libs/Makefile.kmk
+- ifndef VBOX_ONLY_EXTPACKS_USE_IMPLIBS
+- include $(PATH_SUB_CURRENT)/recompiler/Makefile.kmk
+- endif
+-
+ else if defined(VBOX_ONLY_TESTSUITE)
+ include $(PATH_SUB_CURRENT)/libs/Makefile.kmk
+ include $(PATH_SUB_CURRENT)/VBox/Makefile.kmk
+--- VirtualBox-4.1.18.orig/src/VBox/Makefile.kmk 2012-07-24 21:19:55.565641784 -0300
++++ VirtualBox-4.1.18/src/VBox/Makefile.kmk 2012-07-24 22:12:55.429156962 -0300
+@@ -33,19 +33,6 @@
+ include $(PATH_SUB_CURRENT)/HostDrivers/Makefile.kmk
+ include $(PATH_SUB_CURRENT)/Frontends/Makefile.kmk
+
+-else ifdef VBOX_ONLY_EXTPACKS
+- include $(PATH_SUB_CURRENT)/Runtime/Makefile.kmk
+- include $(PATH_SUB_CURRENT)/Devices/Makefile.kmk
+- include $(PATH_SUB_CURRENT)/HostDrivers/Makefile.kmk
+- include $(PATH_SUB_CURRENT)/ExtPacks/Makefile.kmk
+- ifdef VBOX_WITH_VRDP
+- include $(PATH_SUB_CURRENT)/RDP/Makefile.kmk
+- endif
+- include $(PATH_SUB_CURRENT)/VMM/Makefile.kmk
+- ifndef VBOX_ONLY_EXTPACKS_USE_IMPLIBS
+- include $(PATH_SUB_CURRENT)/Disassembler/Makefile.kmk
+- endif
+-
+ else ifdef VBOX_ONLY_SDK
+ include $(PATH_SUB_CURRENT)/Main/Makefile.kmk
+ ifdef VBOX_WITH_VRDP
+@@ -92,9 +79,6 @@
+ if1of ($(KBUILD_TARGET_ARCH), amd64 x86)
+ include $(PATH_SUB_CURRENT)/NetworkServices/Makefile.kmk
+ endif
+- ifndef VBOX_OSE
+- include $(PATH_SUB_CURRENT)/ExtPacks/Makefile.kmk
+- endif
+ ifdef VBOX_WITH_INSTALLER
+ include $(PATH_SUB_CURRENT)/Installer/Makefile.kmk # Keep this last.
+ endif
+--- VirtualBox-4.1.18/src/libs/Makefile.kmk.orig 2012-07-24 21:23:26.938013023 -0300
++++ VirtualBox-4.1.18/src/libs/Makefile.kmk 2012-07-24 21:43:42.557911752 -0300
+@@ -48,13 +48,6 @@
+ include $(PATH_SUB_CURRENT)/kStuff/Makefile.kmk
+ endif
+
+-# OpenSSL.
+-if !defined(VBOX_ONLY_SDK) \
+- && ( "$(SDK_VBOX_OPENSSL_INCS)" == "$(SDK_VBOX_OPENSSL_VBOX_DEFAULT_INCS)" \
+- || defined(VBOX_WITH_EXTPACK_PUEL_BUILD))
+- include $(PATH_SUB_CURRENT)/openssl-0.9.8t/Makefile.kmk
+-endif
+-
+ # libjpeg for VRDP video redirection
+ if defined(VBOX_WITH_VRDP) && defined(VBOX_WITH_VRDP_VIDEO_CHANNEL)
+ include $(PATH_SUB_CURRENT)/jpeg-8a/Makefile.kmk
+--- VirtualBox-4.1.18.orig/src/VBox/Devices/Makefile.kmk 2012-07-24 23:06:45.916276235 -0300
++++ VirtualBox-4.1.18/src/VBox/Devices/Makefile.kmk 2012-07-24 23:17:00.202963228 -0300
+@@ -21,9 +21,7 @@
+
+ # Include sub-makefiles.
+ include $(PATH_SUB_CURRENT)/testcase/Makefile.kmk
+-if defined(VBOX_WITH_INTEL_PXE) || defined(VBOX_ONLY_EXTPACKS)
+- include $(PATH_SUB_CURRENT)/PC/PXE/Makefile.kmk
+-else if defined(VBOX_WITH_PXE_ROM) && !defined(VBOX_WITHOUT_ETHERBOOT)
++if defined(VBOX_WITH_PXE_ROM) && !defined(VBOX_WITHOUT_ETHERBOOT)
+ include $(PATH_SUB_CURRENT)/PC/Etherboot-src/Makefile.kmk
+ endif
+ if !defined(VBOX_ONLY_EXTPACKS) # Goes on almost to the end of the file.
+@@ -57,9 +55,6 @@
+ ifdef VBOX_WITH_USB
+ VBoxDDU_DEFS += VBOX_WITH_USB IN_USBLIB
+ VBoxDDU_SDKS.win = WINPSDK W2K3DDK
+- if defined(VBOX_WITH_EHCI_IMPL) && !defined(VBOX_WITH_EXTPACK_PUEL)
+- VBoxDDU_DEFS += VBOX_WITH_EHCI_IMPL
+- endif
+ ifdef VBOX_WITH_NEW_USB_CODE_ON_DARWIN
+ VBoxDDU_DEFS.darwin += VBOX_WITH_NEW_USB_CODE_ON_DARWIN
+ endif
+@@ -122,9 +117,6 @@
+ VBoxDD_DEFS = VBOX_ACPI
+ ifdef VBOX_WITH_USB
+ VBoxDD_DEFS += VBOX_WITH_USB
+- if defined(VBOX_WITH_EHCI_IMPL) && !defined(VBOX_WITH_EXTPACK_PUEL)
+- VBoxDD_DEFS += VBOX_WITH_EHCI_IMPL
+- endif
+ endif
+ ifdef VBOX_WITH_VUSB
+ VBoxDD_DEFS += VBOX_WITH_VUSB
+@@ -446,11 +438,6 @@
+ endif
+ ifdef VBOX_WITH_USB
+ DevicesR3_DEFS += VBOX_WITH_USB
+- if defined(VBOX_WITH_EHCI_IMPL) && !defined(VBOX_WITH_EXTPACK_PUEL)
+- DevicesR3_DEFS += VBOX_WITH_EHCI_IMPL
+- DevicesR3_SOURCES += \
+- USB/DevEHCI.cpp
+- endif
+ endif
+ if defined(VBOX_WITH_PCI_PASSTHROUGH_IMPL) && !defined(VBOX_WITH_EXTPACK_PUEL)
+ DevicesR3_DEFS += VBOX_WITH_PCI_PASSTHROUGH_IMPL
+@@ -607,11 +594,6 @@
+
+ ifdef VBOX_WITH_USB
+ VBoxDDGC_DEFS += VBOX_WITH_USB
+- if defined(VBOX_WITH_EHCI_IMPL) && !defined(VBOX_WITH_EXTPACK_PUEL)
+- VBoxDDGC_DEFS += VBOX_WITH_EHCI_IMPL
+- VBoxDDGC_SOURCES += \
+- USB/DevEHCI.cpp
+- endif
+ endif
+
+ ifdef VBOX_WITH_VIDEOHWACCEL
+@@ -711,11 +693,6 @@
+ endif
+ ifdef VBOX_WITH_USB
+ VBoxDDR0_DEFS += VBOX_WITH_USB
+- if defined(VBOX_WITH_EHCI_IMPL) && !defined(VBOX_WITH_EXTPACK_PUEL)
+- VBoxDDR0_DEFS += VBOX_WITH_EHCI_IMPL
+- VBoxDDR0_SOURCES += \
+- USB/DevEHCI.cpp
+- endif
+ endif
+
+ if defined(VBOX_WITH_PCI_PASSTHROUGH_IMPL) && !defined(VBOX_WITH_EXTPACK_PUEL)
+@@ -1204,49 +1181,5 @@
+
+ endif # !VBOX_ONLY_EXTPACKS
+
+-if defined(VBOX_WITH_EXTPACK_PUEL) && defined(VBOX_WITH_EXTPACK_PUEL_BUILD)
+- #
+- # The EHCI (USB 2.0) Extension Pack Modules.
+- #
+- if defined(VBOX_WITH_USB)
+- DLLS += VBoxEhciR3
+- VBoxEhciR3_TEMPLATE = VBoxR3ExtPackPuel
+- VBoxEhciR3_SOURCES = USB/DevEHCI.cpp
+-
+- SYSMODS += VBoxEhciR0
+- VBoxEhciR0_TEMPLATE = VBoxR0ExtPackPuel
+- VBoxEhciR0_SOURCES = USB/DevEHCI.cpp
+-
+- ifdef VBOX_WITH_RAW_MODE
+- SYSMODS += VBoxEhciRC
+- VBoxEhciRC_TEMPLATE = VBoxRcExtPackPuel
+- VBoxEhciRC_SOURCES = USB/DevEHCI.cpp
+- endif
+- endif
+-
+- if defined(VBOX_WITH_PCI_PASSTHROUGH)
+- DLLS += VBoxPciRawR3
+- VBoxPciRawR3_TEMPLATE = VBoxR3ExtPackPuel
+- VBoxPciRawR3_SOURCES = Bus/DevPciRaw.cpp
+-
+- DLLS += VBoxPciRawDrv
+- VBoxPciRawDrv_TEMPLATE = VBoxR3ExtPackPuel
+- VBoxPciRawDrv_SOURCES = Bus/DrvPciRaw.cpp
+-
+- SYSMODS += VBoxPciRawR0
+- VBoxPciRawR0_TEMPLATE = VBoxR0ExtPackPuel
+- VBoxPciRawR0_SOURCES = Bus/DevPciRaw.cpp
+-
+- Bus/DevPciRaw.cpp_INCS = Bus
+- endif
+-
+- #
+- # The Intel PXE rom.
+- #
+- INSTALLS += VBoxExtPackPuelInsRoms
+- VBoxExtPackPuelInsRoms_TEMPLATE = VBoxInsExtPackPuel
+- VBoxExtPackPuelInsRoms_SOURCES = PC/PXE/PXE-Intel.rom=>PXE-Intel.rom
+-endif # VBOX_WITH_EXTPACK_PUEL
+-
+ include $(KBUILD_PATH)/subfooter.kmk
+
+--- VirtualBox-4.1.18.orig/src/VBox/Main/Makefile.kmk 2012-07-24 23:38:25.304126039 -0300
++++ VirtualBox-4.1.18/src/VBox/Main/Makefile.kmk 2012-07-24 23:38:25.350789964 -0300
+@@ -230,14 +230,12 @@
+ $(if $(VBOX_USB_WITH_SYSFS),VBOX_USB_WITH_SYSFS,) \
+ $(if $(VBOX_USB_WITH_INOTIFY),VBOX_USB_WITH_INOTIFY,) \
+ $(if $(VBOX_WITH_LIVE_MIGRATION),VBOX_WITH_LIVE_MIGRATION,) \
+- $(if $(VBOX_WITH_EXTPACK),VBOX_WITH_EXTPACK,) \
+ $(if $(VBOX_WITH_VUSB),VBOX_WITH_VUSB,) \
+ $(if $(VBOX_WITH_S3),VBOX_WITH_S3,) \
+ $(if $(VBOX_WITH_PCI_PASSTHROUGH),VBOX_WITH_PCI_PASSTHROUGH,)
+ ifdef VBOX_WITH_USB
+ VBoxSVC_DEFS += \
+ VBOX_WITH_USB \
+- $(if $(VBOX_WITH_EHCI),VBOX_WITH_EHCI,) \
+ $(if $(VBOX_WITH_NEW_USB_CODE_ON_DARWIN),VBOX_WITH_NEW_USB_CODE_ON_DARWIN,)
+ endif
+ VBoxSVC_DEFS.win += VBOX_COM_OUTOFPROC_MODULE
+@@ -290,7 +288,6 @@
+ src-all/SharedFolderImpl.cpp \
+ src-all/VirtualBoxBase.cpp \
+ src-all/VirtualBoxErrorInfoImpl.cpp \
+- $(if $(VBOX_WITH_EXTPACK),src-all/ExtPackManagerImpl.cpp src-all/ExtPackUtil.cpp,) \
+ src-server/ApplianceImpl.cpp \
+ src-server/ApplianceImplExport.cpp \
+ src-server/ApplianceImplImport.cpp \
+@@ -543,8 +540,6 @@
+ $(if $(VBOX_WITH_HGSMI),VBOX_WITH_HGSMI,) \
+ $(if $(VBOX_WITH_VIDEOHWACCEL),VBOX_WITH_VIDEOHWACCEL,) \
+ $(if $(VBOX_WITH_USB),VBOX_WITH_USB,) \
+- $(if-expr defined(VBOX_WITH_EHCI) && defined(VBOX_WITH_USB),VBOX_WITH_EHCI,) \
+- $(if $(VBOX_WITH_EXTPACK),VBOX_WITH_EXTPACK,) \
+ $(if $(VBOX_WITH_PCI_PASSTHROUGH),VBOX_WITH_PCI_PASSTHROUGH,)
+
+ VBoxC_DEFS.darwin.x86 = VBOX_WITH_2X_4GB_ADDR_SPACE
+@@ -602,7 +597,6 @@
+ src-all/SharedFolderImpl.cpp \
+ src-all/VirtualBoxBase.cpp \
+ src-all/VirtualBoxErrorInfoImpl.cpp \
+- $(if $(VBOX_WITH_EXTPACK),src-all/ExtPackManagerImpl.cpp src-all/ExtPackUtil.cpp,) \
+ $(if $(VBOX_WITH_USB_VIDEO),src-client/UsbWebcamInterface.cpp,) \
+ $(if $(VBOX_WITH_USB_CARDREADER),src-client/UsbCardReader.cpp,) \
+ src-client/AdditionsFacilityImpl.cpp \
+@@ -711,22 +705,6 @@
+ endif # !win
+
+
+-#
+-# The VBoxExtPackHelperApp.
+-#
+-ifdef VBOX_WITH_EXTPACK
+- PROGRAMS += VBoxExtPackHelperApp
+- VBoxExtPackHelperApp_TEMPLATE = VBoxR3SetUidToRoot
+- VBoxExtPackHelperApp_LDFLAGS.darwin = -framework Security
+- VBoxExtPackHelperApp_LDFLAGS.win = /SUBSYSTEM:windows
+- VBoxExtPackHelperApp_SOURCES = \
+- src-helper-apps/VBoxExtPackHelperApp.cpp \
+- src-all/ExtPackUtil.cpp
+- VBoxExtPackHelperApp_LIBS = \
+- $(LIB_RUNTIME)
+-endif # VBOX_WITH_EXTPACK
+-
+-
+ endif # !VBOX_ONLY_SDK (the ifndef is far above)
+
+
+--- VirtualBox-4.1.18.orig/src/VBox/Frontends/VirtualBox/Makefile.kmk 2012-07-24 23:25:04.575825175 -0300
++++ VirtualBox-4.1.18/src/VBox/Frontends/VirtualBox/Makefile.kmk 2012-07-24 23:25:04.619156084 -0300
+@@ -888,7 +888,6 @@
+ $(VBOX_MACOSX_ICON_FILE)=>Resources/virtualbox.icns \
+ $(VBOX_BRAND_GUI_VBOX_64PX_PNG)=>Resources/virtualbox.png \
+ $(PATH_ROOT)/src/VBox/Resources/darwin/virtualbox-vbox.icns=>Resources/virtualbox-vbox.icns \
+- $(PATH_ROOT)/src/VBox/Resources/darwin/virtualbox-vbox-extpack.icns=>Resources/virtualbox-vbox-extpack.icns \
+ $(PATH_ROOT)/src/VBox/Resources/darwin/virtualbox-ovf.icns=>Resources/virtualbox-ovf.icns \
+ $(PATH_ROOT)/src/VBox/Resources/darwin/virtualbox-ova.icns=>Resources/virtualbox-ova.icns \
+ $(PATH_ROOT)/src/VBox/Resources/darwin/virtualbox-vdi.icns=>Resources/virtualbox-vdi.icns \
+--- VirtualBox-4.1.18.orig/src/VBox/Frontends/VirtualBox/VirtualBox2.qrc 2012-07-24 23:28:17.985011038 -0300
++++ VirtualBox-4.1.18/src/VBox/Frontends/VirtualBox/VirtualBox2.qrc 2012-07-24 23:28:18.051673913 -0300
+@@ -167,18 +167,6 @@
+ <file alias="status_check_32px.png">images/status_check_32px.png</file>
+ <file alias="status_error_16px.png">images/status_error_16px.png</file>
+ <file alias="status_error_32px.png">images/status_error_32px.png</file>
+- <file alias="extension_pack_16px.png">images/extension_pack_16px.png</file>
+- <file alias="extension_pack_disabled_16px.png">images/extension_pack_disabled_16px.png</file>
+- <file alias="extension_pack_32px.png">images/extension_pack_32px.png</file>
+- <file alias="extension_pack_disabled_32px.png">images/extension_pack_disabled_32px.png</file>
+- <file alias="extension_pack_install_16px.png">images/extension_pack_install_16px.png</file>
+- <file alias="extension_pack_install_disabled_16px.png">images/extension_pack_install_disabled_16px.png</file>
+- <file alias="extension_pack_install_32px.png">images/extension_pack_install_32px.png</file>
+- <file alias="extension_pack_install_disabled_32px.png">images/extension_pack_install_disabled_32px.png</file>
+- <file alias="extension_pack_uninstall_16px.png">images/extension_pack_uninstall_16px.png</file>
+- <file alias="extension_pack_uninstall_disabled_16px.png">images/extension_pack_uninstall_disabled_16px.png</file>
+- <file alias="extension_pack_uninstall_32px.png">images/extension_pack_uninstall_32px.png</file>
+- <file alias="extension_pack_uninstall_disabled_32px.png">images/extension_pack_uninstall_disabled_32px.png</file>
+ <file alias="proxy_16px.png">images/proxy_16px.png</file>
+ <file alias="proxy_disabled_16px.png">images/proxy_disabled_16px.png</file>
+ <file alias="proxy_32px.png">images/proxy_32px.png</file>
+--- VirtualBox-4.1.18.orig/src/VBox/Installer/linux/Makefile.kmk 2012-07-25 00:32:00.780012664 -0300
++++ VirtualBox-4.1.18/src/VBox/Installer/linux/Makefile.kmk 2012-07-25 00:32:00.806677728 -0300
+@@ -170,11 +170,6 @@
+ VBox.sh \
+ VBox.png
+
+-ifdef VBOX_WITH_EXTPACK
+- VBOX_LNX_STRIP_BIN += \
+- VBoxExtPackHelperApp
+-endif
+-
+ # Qt4 GUI
+ ifdef VBOX_WITH_QTGUI
+ include $(PATH_ROOT)/src/VBox/Frontends/VirtualBox/nls/ApprovedLanguages.kmk
+@@ -286,7 +281,7 @@
+
+ VBOX_MIME_ICONS = \
+ $(addprefix $(PATH_ROOT)/src/VBox/Resources/other/,\
+- $(foreach f,ova ovf vbox vbox-extpack vdi vmdk vhd hdd, \
++ $(foreach f,ova ovf vbox vdi vmdk vhd hdd, \
+ $(foreach s,16 20 24 32 48 64 72 96 128 256,\
+ virtualbox-$(f)-$(s)px.png=>$(s)x$(s)/virtualbox-$(f).png)))
+
+--- VirtualBox-4.1.18.orig/src/VBox/Installer/win/Makefile.kmk 2012-07-25 00:34:52.253398525 -0300
++++ VirtualBox-4.1.18/src/VBox/Installer/win/Makefile.kmk 2012-07-25 00:34:52.300062531 -0300
+@@ -435,7 +435,6 @@
+ -E 'VBOX_WITH_DEBUGGER_GUI=$(if-expr defined(VBOX_WITH_DEBUGGER_GUI) && defined(VBOX_WITH_QTGUI),yes,no)' \
+ -E 'VBOX_WITH_DOCS_PACKING=$(if $(VBOX_WITH_DOCS_PACKING),yes,no)' \
+ -E 'VBOX_WITH_EFIFW_PACKING=$(if $(VBOX_WITH_EFIFW_PACKING),yes,no)' \
+- -E 'VBOX_WITH_EXTPACK=$(if $(VBOX_WITH_EXTPACK),yes,no)' \
+ -E 'VBOX_WITH_GUEST_CONTROL=$(if $(VBOX_WITH_GUEST_CONTROL),yes,no)' \
+ -E 'VBOX_WITH_GUEST_PROPS=$(if $(VBOX_WITH_GUEST_PROPS),yes,no)' \
+ -E 'VBOX_WITH_NETFLT=$(if $(VBOX_WITH_NETFLT),yes,no)' \
+--- VirtualBox-4.1.18.orig/src/VBox/Installer/darwin/Makefile.kmk 2012-07-25 00:36:55.929571374 -0300
++++ VirtualBox-4.1.18/src/VBox/Installer/darwin/Makefile.kmk 2012-07-25 00:36:55.959569630 -0300
+@@ -629,7 +629,6 @@
+ MacOS/VirtualBoxVM \
+ MacOS/VBoxNetAdpCtl \
+ MacOS/VBoxNetDHCP \
+- MacOS/VBoxExtPackHelperApp \
+ MacOS/VBoxBalloonCtrl
+ ifdef VBOX_WITH_WEBSERVICES
+ VBOX_DI_VBAPP_PROGS += \
+@@ -659,7 +658,6 @@
+ Resources/virtualbox.icns \
+ Resources/virtualbox.png \
+ Resources/virtualbox-vbox.icns \
+- Resources/virtualbox-vbox-extpack.icns \
+ Resources/virtualbox-ovf.icns \
+ Resources/virtualbox-ova.icns \
+ Resources/virtualbox-vdi.icns \
+--- VirtualBox-4.1.18/src/VBox/Installer/solaris/Makefile.kmk.orig 2012-07-25 00:38:48.476398293 -0300
++++ VirtualBox-4.1.18/src/VBox/Installer/solaris/Makefile.kmk 2012-07-25 00:38:48.516396159 -0300
+@@ -185,12 +185,12 @@
+
+ VBOX_MIME_ICONS = \
+ $(addprefix $(PATH_ROOT)/src/VBox/Resources/other/,\
+- $(foreach f,ova ovf vbox vbox-extpack vdi vmdk vhd hdd, \
++ $(foreach f,ova ovf vbox vdi vmdk vhd hdd, \
+ $(foreach s,16 20 24 32 48 64 72 96 128 256,\
+ virtualbox-$(f)-$(s)px.png=>$(s)x$(s)/mimetypes/virtualbox-$(f).png)))
+
+ SOLARIS_COMMON_ICONS = \
+- $(foreach f,ova ovf vbox vbox-extpack vdi vmdk vhd hdd, \
++ $(foreach f,ova ovf vbox vdi vmdk vhd hdd, \
+ $(foreach s,16 20 24 32 48 64 72 96 128 256,\
+ $(s)x$(s)/mimetypes/virtualbox-$(f).png))
+
+@@ -210,7 +210,6 @@
+ $(if $(VBOX_WITH_VBOXSDL),VBoxSDL,) \
+ $(if $(VBOX_WITH_NETADP),VBoxNetAdpCtl,) \
+ VBoxNetDHCP \
+- $(if $(VBOX_WITH_EXTPACK),VBoxExtPackHelperApp,) \
+ VBoxSVC \
+ $(if $(VBOX_WITH_CROGL),VBoxTestOGL,) \
+ VBoxXPCOMIPCD \
+--- VirtualBox-4.1.18.orig/src/VBox/Runtime/Makefile.kmk 2012-07-25 00:40:58.745522450 -0300
++++ VirtualBox-4.1.18/src/VBox/Runtime/Makefile.kmk 2012-07-25 00:40:58.782186960 -0300
+@@ -53,15 +53,6 @@
+ #
+ LIBRARIES += RuntimeR3 RuntimeBldProg
+
+-else ifdef VBOX_ONLY_EXTPACKS_USE_IMPLIBS
+- #
+- # Build docs only - need just regular R3 runtime.
+- #
+- LIBRARIES += RuntimeBldProg
+- LIBRARIES.solaris += RuntimeR0Stub
+- LIBRARIES.win += RuntimeR0Stub RuntimeRCStub
+- include $(PATH_SUB_CURRENT)/tools/Makefile.kmk
+-
+ else # !VBOX_ONLY_ADDITIONS && !VBOX_ONLY_TESTSUITE && !VBOX_ONLY_DOCS
+
+ #