Index: /trunk/src/VBox/Installer/win/Stub/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Installer/win/Stub/Makefile.kmk	(revision 45319)
+++ /trunk/src/VBox/Installer/win/Stub/Makefile.kmk	(revision 45320)
@@ -22,57 +22,58 @@
 if "$(KBUILD_TARGET_ARCH)" == "x86"
 
-TEMPLATE_VBOXSTUB = Drop the signing, we will sign it later.
-TEMPLATE_VBOXSTUB_EXTENDS = VBOXR3STATIC
-TEMPLATE_VBOXSTUB_POST_CMDS = $(NO_SUCH_VARIABLE)
+ TEMPLATE_VBOXSTUB = Drop the signing, we will sign it later.
+ TEMPLATE_VBOXSTUB_EXTENDS = VBOXR3STATIC
+ TEMPLATE_VBOXSTUB_POST_CMDS = $(NO_SUCH_VARIABLE)
 
-PROGRAMS.x86 += VBoxStub
-VBoxStub_TEMPLATE= VBOXSTUB
-VBoxStub_DEFS    = _WIN32_WINNT=0x0501 IN_RT_R3
+ PROGRAMS += VBoxStub
+ VBoxStub_TEMPLATE= VBOXSTUB
+ VBoxStub_DEFS    = _WIN32_WINNT=0x0501 IN_RT_R3
 
-VBoxStub_SOURCES = \
-	VBoxStub.cpp \
-	VBoxStub.rc
+ VBoxStub_SOURCES = \
+ 	VBoxStub.cpp \
+ 	VBoxStub.rc
 
-VBoxStub_SDKS += \
-	VBOX_NTDLL
-VBoxStub_LIBS = \
-	$(VBOX_LIB_RUNTIME_STATIC) \
-	$(PATH_SDK_$(VBOX_WINPSDK)_LIB)/Msi.lib
+ VBoxStub_SDKS += \
+ 	VBOX_NTDLL
+ VBoxStub_LIBS = \
+ 	$(VBOX_LIB_RUNTIME_STATIC) \
+ 	$(PATH_SDK_$(VBOX_WINPSDK)_LIB)/Msi.lib
 
-VBoxStub.cpp_DEFS += VBOX_SVN_REV=$(VBOX_SVN_REV)
-VBoxStub.cpp_DEPS  = $(VBOX_SVN_REV_KMK)
+ VBoxStub.cpp_DEFS += VBOX_SVN_REV=$(VBOX_SVN_REV)
+ VBoxStub.cpp_DEPS  = $(VBOX_SVN_REV_KMK)
 
-# If signing mode is enabled, then add the possibility to
-# install public certificate automatically in /silent mode
-ifdef VBOX_SIGNING_MODE
+ # If signing mode is enabled, then add the possibility to
+ # install public certificate automatically in /silent mode
+ ifdef VBOX_SIGNING_MODE
 
-VBoxStub_SOURCES  += VBoxStubCertUtil.cpp
-VBoxStub_LIBS     += crypt32.lib
-VBoxStub.cpp_DEPS += $(VBoxStub_0_OUTDIR)/VBoxStubPublicCert.h
-VBoxStub.cpp_INCS += $(VBoxStub_0_OUTDIR)
-VBoxStub.cpp_DEFS += VBOX_SIGNING_MODE
+  VBoxStub_SOURCES  += VBoxStubCertUtil.cpp
+  VBoxStub_LIBS     += crypt32.lib
+  VBoxStub.cpp_DEPS += $(VBoxStub_0_OUTDIR)/VBoxStubPublicCert.h
+  VBoxStub.cpp_INCS += $(VBoxStub_0_OUTDIR)
+  VBoxStub.cpp_DEFS += VBOX_WITH_CODE_SIGNING
 
-$$(VBoxStub_0_OUTDIR)/VBoxStubPublicCert.h: $(VBOX_BIN2C) $(PATH_ROOT)/src/VBox/Additions/WINNT/tools/oracle-vbox.cer
+  $$(VBoxStub_0_OUTDIR)/VBoxStubPublicCert.h: $(VBOX_BIN2C) $(PATH_ROOT)/src/VBox/Additions/WINNT/tools/oracle-vbox.cer
 	$(VBOX_BIN2C) _VBoxStubPublicCert $(PATH_ROOT)/src/VBox/Additions/WINNT/tools/oracle-vbox.cer $@
 
-endif
+ endif
 
-# The icon location is configurable.
-VBoxStub.rc_INCS += $(VBoxStub_0_OUTDIR)
-VBoxStub.rc_DEPS += \
-	$(VBoxStub_0_OUTDIR)/VBoxStub-icon.rc \
-	$(VBoxStub_0_OUTDIR)/VBoxStub-manifest.rc
-VBoxStub.rc_CLEAN = \
-	$(VBoxStub_0_OUTDIR)/VBoxStub-icon.rc \
-	$(VBoxStub_0_OUTDIR)/VBoxStub-manifest.rc
+ # The icon location is configurable.
+ VBoxStub.rc_INCS += $(VBoxStub_0_OUTDIR)
+ VBoxStub.rc_DEPS += \
+ 	$(VBoxStub_0_OUTDIR)/VBoxStub-icon.rc \
+ 	$(VBoxStub_0_OUTDIR)/VBoxStub-manifest.rc
+ VBoxStub.rc_CLEAN = \
+ 	$(VBoxStub_0_OUTDIR)/VBoxStub-icon.rc \
+ 	$(VBoxStub_0_OUTDIR)/VBoxStub-manifest.rc
 
-# Icon include file.
-$$(VBoxStub_0_OUTDIR)/VBoxStub-icon.rc: $(VBOX_WINDOWS_ICON_FILE) $(MAKEFILE_CURRENT) | $$(dir $$@)
+ # Icon include file.
+ $$(VBoxStub_0_OUTDIR)/VBoxStub-icon.rc: $(VBOX_WINDOWS_ICON_FILE) $(MAKEFILE_CURRENT) | $$(dir $$@)
 	$(APPEND) -t $@ 'IDI_VIRTUALBOX ICON DISCARDABLE "$(subst /,\\,$(VBOX_WINDOWS_ICON_FILE))"'
 
-# Manifest.
-VBOX_STUB_MANIFEST_FILE := $(PATH_SUB_CURRENT)/VBoxStub.manifest
-$$(VBoxStub_0_OUTDIR)/VBoxStub-manifest.rc: $(VBOX_STUB_MANIFEST_FILE) $(MAKEFILE_CURRENT) | $$(dir $$@)
+ # Manifest.
+ VBOX_STUB_MANIFEST_FILE := $(PATH_SUB_CURRENT)/VBoxStub.manifest
+ $$(VBoxStub_0_OUTDIR)/VBoxStub-manifest.rc: $(VBOX_STUB_MANIFEST_FILE) $(MAKEFILE_CURRENT) | $$(dir $$@)
 	$(APPEND) -t $@ 'APP_MANIFEST RT_MANIFEST "$(subst /,\\,$(VBOX_STUB_MANIFEST_FILE))"'
+
 
 endif # x86 only
Index: /trunk/src/VBox/Installer/win/Stub/VBoxStub.cpp
===================================================================
--- /trunk/src/VBox/Installer/win/Stub/VBoxStub.cpp	(revision 45319)
+++ /trunk/src/VBox/Installer/win/Stub/VBoxStub.cpp	(revision 45320)
@@ -49,10 +49,10 @@
 #include "resource.h"
 
-#ifdef VBOX_SIGNING_MODE
-#include "VBoxStubCertUtil.h"
-#include "VBoxStubPublicCert.h"
+#ifdef VBOX_WITH_CODE_SIGNING
+# include "VBoxStubCertUtil.h"
+# include "VBoxStubPublicCert.h"
 #endif
 
-#ifndef  _UNICODE
+#ifndef  _UNICODE /* Isn't this a little late? */
 #define  _UNICODE
 #endif
@@ -68,8 +68,9 @@
  * Shows an error message box with a printf() style formatted string.
  *
+ * @returns RTEXITCODE_FAILURE
  * @param   pszFmt              Printf-style format string to show in the message box body.
  *
  */
-static void ShowError(const char *pszFmt, ...)
+static RTEXITCODE ShowError(const char *pszFmt, ...)
 {
     char       *pszMsg;
@@ -88,4 +89,5 @@
         AssertMsgFailed(("Failed to format error text of format string: %s!\n", pszFmt));
     va_end(va);
+    return RTEXITCODE_FAILURE;
 }
 
@@ -119,20 +121,20 @@
 
 /**
- * Reads data from a built-in resource.
- *
- * @returns iprt status code.
- *
- * @param   hInst               Instance to read the data from.
+ * Finds the specified in the resource section of the executable.
+ *
+ * @returns IPRT status code.
+ *
  * @param   pszDataName         Name of resource to read.
- * @param   ppvResource         Pointer to buffer which holds the read resource data.
- * @param   pdwSize             Pointer which holds the read data size.
- *
- */
-static int ReadData(HINSTANCE   hInst,
-                    const char *pszDataName,
+ * @param   ppvResource         Where to return the pointer to the data.
+ * @param   pdwSize             Where to return the size of the data (if found).
+ *                              Optional.
+ *
+ */
+static int FindData(const char *pszDataName,
                     PVOID      *ppvResource,
                     DWORD      *pdwSize)
 {
     AssertReturn(pszDataName, VERR_INVALID_PARAMETER);
+    HINSTANCE hInst = NULL;
 
     /* Find our resource. */
@@ -141,6 +143,8 @@
 
     /* Get resource size. */
-    *pdwSize = SizeofResource(hInst, hRsrc);
-    AssertReturn(*pdwSize > 0, VERR_NO_DATA);
+    DWORD cb = SizeofResource(hInst, hRsrc);
+    AssertReturn(cb > 0, VERR_NO_DATA);
+    if (pdwSize)
+        *pdwSize = cb;
 
     /* Get pointer to resource. */
@@ -156,4 +160,30 @@
 
 /**
+ * Finds the header for the given package.
+ *
+ * @returns Pointer to the package header on success.  On failure NULL is
+ *          returned after ShowError has been invoked.
+ * @param   iPackage            The package number.
+ */
+static PVBOXSTUBPKG FindPackageHeader(unsigned iPackage)
+{
+    char szHeaderName[32];
+    RTStrPrintf(szHeaderName, sizeof(szHeaderName), "HDR_%02d", iPackage);
+
+    PVBOXSTUBPKG pPackage;
+    int rc = FindData(szHeaderName, (PVOID *)&pPackage, NULL);
+    if (RT_FAILURE(rc))
+    {
+        ShowError("Internal error: Could not find package header #%u: %Rrc", iPackage, rc);
+        return NULL;
+    }
+
+    /** @todo validate it. */
+    return pPackage;
+}
+
+
+
+/**
  * Constructs a full temporary file path from the given parameters.
  *
@@ -199,5 +229,5 @@
         PVOID pvData = NULL;
         DWORD dwDataSize = 0;
-        rc = ReadData(NULL, pszResourceName, &pvData, &dwDataSize);
+        rc = FindData(pszResourceName, &pvData, &dwDataSize);
         AssertMsgRCBreak(rc, ("Could not read resource data!\n"));
 
@@ -298,34 +328,312 @@
 
 /**
- * Recursively copies a directory to another location.
- *
- * @returns iprt status code.
- *
- * @param   pszDestDir          Location to copy the source directory to.
- * @param   pszSourceDir        The source directory to copy.
- *
- */
-int CopyDir(const char *pszDestDir, const char *pszSourceDir)
-{
-    char szDest[RTPATH_MAX + 1];
-    char szSource[RTPATH_MAX + 1];
-
-    AssertStmt(pszDestDir, "Destination directory invalid!");
-    AssertStmt(pszSourceDir, "Source directory invalid!");
-
-    SHFILEOPSTRUCT s = {0};
-    if (   RTStrPrintf(szDest, _MAX_PATH, "%s%c", pszDestDir, '\0') > 0
-        && RTStrPrintf(szSource, _MAX_PATH, "%s%c", pszSourceDir, '\0') > 0)
-    {
-        s.hwnd = NULL;
-        s.wFunc = FO_COPY;
-        s.pTo = szDest;
-        s.pFrom = szSource;
-        s.fFlags = FOF_SILENT
-                 | FOF_NOCONFIRMATION
-                 | FOF_NOCONFIRMMKDIR
-                 | FOF_NOERRORUI;
-    }
-    return RTErrConvertFromWin32(SHFileOperation(&s));
+ * Processes an MSI package.
+ *
+ * @returns Fully complained exit code.
+ * @param   iPackage            The package number.
+ * @param   pszMsi              The path to the MSI to process.
+ * @param   pszMsiArgs          Any additional installer (MSI) argument
+ * @param   fLogging            Whether to enable installer logging.
+ */
+static RTEXITCODE ProcessMsiPackage(unsigned iPackage, const char *pszMsi, const char *pszMsiArgs, bool fLogging)
+{
+    int rc;
+
+    /*
+     * Set UI level.
+     */
+    INSTALLUILEVEL enmDesiredUiLevel = g_fSilent ? INSTALLUILEVEL_NONE : INSTALLUILEVEL_FULL;
+    INSTALLUILEVEL enmRet = MsiSetInternalUI(enmDesiredUiLevel, NULL);
+    if (enmRet == INSTALLUILEVEL_NOCHANGE /* means error */)
+        return ShowError("Internal error: MsiSetInternalUI failed.");
+
+    /*
+     * Enable logging?
+     */
+    if (fLogging)
+    {
+        char szLogFile[RTPATH_MAX];
+        rc = RTStrCopy(szLogFile, sizeof(szLogFile), pszMsi);
+        if (RT_SUCCESS(rc))
+        {
+            RTPathStripFilename(szLogFile);
+            rc = RTPathAppend(szLogFile, sizeof(szLogFile), "VBoxInstallLog.txt");
+        }
+        if (RT_FAILURE(rc))
+            return ShowError("Internal error: Filename path too long.");
+
+        PRTUTF16 pwszLogFile;
+        rc = RTStrToUtf16(szLogFile, &pwszLogFile);
+        if (RT_FAILURE(rc))
+            return ShowError("RTStrToUtf16 failed on '%s': %Rrc", szLogFile, rc);
+
+        UINT uLogLevel = MsiEnableLogW(INSTALLLOGMODE_VERBOSE,
+                                       pwszLogFile,
+                                       INSTALLLOGATTRIBUTES_FLUSHEACHLINE | (iPackage > 0 ? INSTALLLOGATTRIBUTES_APPEND : 0));
+        RTUtf16Free(pwszLogFile);
+        if (uLogLevel != ERROR_SUCCESS)
+            return ShowError("MsiEnableLogW failed");
+    }
+
+    /*
+     * Initialize the common controls (extended version). This is necessary to
+     * run the actual .MSI installers with the new fancy visual control
+     * styles (XP+). Also, an integrated manifest is required.
+     */
+    INITCOMMONCONTROLSEX ccEx;
+    ccEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
+    ccEx.dwICC = ICC_LINK_CLASS | ICC_LISTVIEW_CLASSES | ICC_PAGESCROLLER_CLASS |
+                 ICC_PROGRESS_CLASS | ICC_STANDARD_CLASSES | ICC_TAB_CLASSES | ICC_TREEVIEW_CLASSES |
+                 ICC_UPDOWN_CLASS | ICC_USEREX_CLASSES | ICC_WIN95_CLASSES;
+    InitCommonControlsEx(&ccEx); /* Ignore failure. */
+
+    /*
+     * Convert both strings to UTF-16 and start the installation.
+     */
+    PRTUTF16 pwszMsi;
+    rc = RTStrToUtf16(pszMsi, &pwszMsi);
+    if (RT_FAILURE(rc))
+        return ShowError("RTStrToUtf16 failed on '%s': %Rrc", pszMsi, rc);
+    PRTUTF16 pwszMsiArgs;
+    rc = RTStrToUtf16(pszMsiArgs, &pwszMsiArgs);
+    if (RT_FAILURE(rc))
+    {
+        RTUtf16Free(pwszMsi);
+        return ShowError("RTStrToUtf16 failed on '%s': %Rrc", pszMsi, rc);
+    }
+
+    UINT uStatus = MsiInstallProductW(pwszMsi, pwszMsiArgs);
+    RTUtf16Free(pwszMsi);
+    RTUtf16Free(pwszMsiArgs);
+
+    if (uStatus == ERROR_SUCCESS)
+        return RTEXITCODE_SUCCESS;
+    if (uStatus == ERROR_SUCCESS_REBOOT_REQUIRED)
+        return RTEXITCODE_SUCCESS; /* we currently don't indicate this */
+
+    /*
+     * Installation failed. Figure out what to say.
+     */
+    switch (uStatus)
+    {
+        case ERROR_INSTALL_USEREXIT:
+            /* Don't say anything? */
+            break;
+
+        case ERROR_INSTALL_PACKAGE_VERSION:
+            ShowError("This installation package cannot be installed by the Windows Installer service.\n"
+                      "You must install a Windows service pack that contains a newer version of the Windows Installer service.");
+            break;
+
+        case ERROR_INSTALL_PLATFORM_UNSUPPORTED:
+            ShowError("This installation package is not supported on this platform.");
+            break;
+
+        default:
+        {
+            /*
+             * Try get windows to format the message.
+             */
+            DWORD dwFormatFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER
+                                | FORMAT_MESSAGE_IGNORE_INSERTS
+                                | FORMAT_MESSAGE_FROM_SYSTEM;
+            HMODULE hModule = NULL;
+            if (uStatus >= NERR_BASE && uStatus <= MAX_NERR)
+            {
+                hModule = LoadLibraryEx(TEXT("netmsg.dll"),
+                                        NULL,
+                                        LOAD_LIBRARY_AS_DATAFILE);
+                if (hModule != NULL)
+                    dwFormatFlags |= FORMAT_MESSAGE_FROM_HMODULE;
+            }
+
+            /** @todo this is totally WRONG wrt to string code pages. We expect UTF-8
+             *        while the ANSI code page might be one of the special Chinese ones,
+             *        IPRT is going to be so angry with us (and so will the users). */
+            DWORD dwBufferLength;
+            LPSTR szMessageBuffer;
+            if (dwBufferLength = FormatMessageA(dwFormatFlags,
+                                                hModule, /* If NULL, load system stuff. */
+                                                uStatus,
+                                                MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+                                                (LPSTR)&szMessageBuffer,
+                                                0,
+                                                NULL))
+            {
+                ShowError("Installation failed! Error: %s", szMessageBuffer);
+                LocalFree(szMessageBuffer);
+            }
+            else /* If text lookup failed, show at least the error number. */
+                ShowError("Installation failed! Error: %u", uStatus);
+
+            if (hModule)
+                FreeLibrary(hModule);
+            break;
+        }
+    }
+
+    return RTEXITCODE_FAILURE;
+}
+
+
+/**
+ * Processes a package.
+ *
+ * @returns Fully complained exit code.
+ * @param   iPackage            The package number.
+ * @param   pszPkgDir           The package directory (aka extraction dir).
+ * @param   pszMsiArgs          Any additional installer (MSI) argument
+ * @param   fLogging            Whether to enable installer logging.
+ */
+static RTEXITCODE ProcessPackage(unsigned iPackage, const char *pszPkgDir, const char *pszMsiArgs, bool fLogging)
+{
+    /*
+     * Get the package header and check if it's needed.
+     */
+    PVBOXSTUBPKG pPackage = FindPackageHeader(iPackage);
+    if (pPackage == NULL)
+        return RTEXITCODE_FAILURE;
+
+    if (!PackageIsNeeded(pPackage))
+        return RTEXITCODE_SUCCESS;
+
+    /*
+     * Deal with the file based on it's extension.
+     */
+    char *pszPkgFile = RTPathJoinA(pszPkgDir, pPackage->szFileName);
+    if (!pszPkgFile)
+        return ShowError("Out of memory on line #%u!", __LINE__);
+    RTPathChangeToDosSlashes(pszPkgFile, true /* Force conversion. */); /* paranoia */
+
+    RTEXITCODE rcExit;
+    const char *pszExt = RTPathExt(pszPkgFile);
+    if (RTStrICmp(pszExt, ".msi") == 0)
+        rcExit = ProcessMsiPackage(iPackage, pszPkgFile, pszMsiArgs, fLogging);
+    else
+        rcExit = ShowError("Internal error: Do not know how to handle file '%s'.", pPackage->szFileName);
+
+    RTStrFree(pszPkgFile);
+    return rcExit;
+}
+
+
+#ifdef VBOX_WITH_CODE_SIGNING
+/**
+ * Install the public certificate into TrustedPublishers so the installer won't
+ * prompt the user during silent installs.
+ *
+ * @returns Fully complained exit code.
+ */
+static RTEXITCODE InstallCertificate(void)
+{
+    if (addCertToStore(CERT_SYSTEM_STORE_LOCAL_MACHINE,
+                       "TrustedPublisher",
+                       g_ab_VBoxStubPublicCert,
+                       sizeof(g_ab_VBoxStubPublicCert)))
+        return RTEXITCODE_SUCCESS;
+    return ShowError("Failed to construct install certificate.");
+}
+#endif /* VBOX_WITH_CODE_SIGNING */
+
+
+/**
+ * Copies the "<exepath>.custom" directory to the extraction path if it exists.
+ *
+ * This is used by the MSI packages from the resource section.
+ *
+ * @returns Fully complained exit code.
+ * @param   pszDstDir       The destination directory.
+ */
+static RTEXITCODE CopyCustomDir(const char *pszDstDir)
+{
+    char szSrcDir[RTPATH_MAX];
+    int rc = RTPathExecDir(szSrcDir, sizeof(szSrcDir) - 1);
+    if (RT_SUCCESS(rc))
+        rc = RTPathAppend(szSrcDir, sizeof(szSrcDir) - 1, ".custom");
+    if (RT_FAILURE(rc))
+        return ShowError("Failed to construct '.custom' dir path: %Rrc", rc);
+
+    if (RTDirExists(szSrcDir))
+    {
+        /*
+         * Use SHFileOperation w/ FO_COPY to do the job.  This API requires an
+         * extra zero at the end of both source and destination paths.  Thus
+         * the -1 above and below.
+         */
+        size_t   cwc;
+        RTUTF16  wszSrcDir[RTPATH_MAX + 2];
+        PRTUTF16 pwszSrcDir = wszSrcDir;
+        rc = RTStrToUtf16Ex(szSrcDir, RTSTR_MAX, &pwszSrcDir, RTPATH_MAX, &cwc);
+        if (RT_FAILURE(rc))
+            return ShowError("RTStrToUtf16Ex failed on '%s': %Rrc", szSrcDir, rc);
+        wszSrcDir[cwc] = '\0';
+
+        RTUTF16  wszDstDir[RTPATH_MAX + 2];
+        PRTUTF16 pwszDstDir = wszSrcDir;
+        rc = RTStrToUtf16Ex(pszDstDir, RTSTR_MAX, &pwszDstDir, RTPATH_MAX, &cwc);
+        if (RT_FAILURE(rc))
+            return ShowError("RTStrToUtf16Ex failed on '%s': %Rrc", pszDstDir, rc);
+        wszDstDir[cwc] = '\0';
+
+        SHFILEOPSTRUCTW FileOp;
+        RT_ZERO(FileOp); /* paranoia */
+        FileOp.hwnd     = NULL;
+        FileOp.wFunc    = FO_COPY;
+        FileOp.pFrom    = wszSrcDir;
+        FileOp.pTo      = wszDstDir;
+        FileOp.fFlags   = FOF_SILENT
+                        | FOF_NOCONFIRMATION
+                        | FOF_NOCONFIRMMKDIR
+                        | FOF_NOERRORUI;
+        FileOp.fAnyOperationsAborted = FALSE;
+        FileOp.hNameMappings = NULL;
+        FileOp.lpszProgressTitle = NULL;
+
+        rc = SHFileOperationW(&FileOp);
+        if (rc != 0)    /* Not a Win32 status code! */
+            return ShowError("Copying the '.custom' dir failed: %#x", rc);
+    }
+
+    return RTEXITCODE_SUCCESS;
+}
+
+
+static RTEXITCODE ExtractFiles(unsigned cPackages, const char *pszDstDir, bool fExtractOnly)
+{
+    int rc;
+
+    /*
+     * Make sure the directory exists.
+     */
+    if (!RTDirExists(pszDstDir))
+    {
+        rc = RTDirCreate(pszDstDir, 0700, 0);
+        if (RT_FAILURE(rc))
+            return ShowError("Failed to create extraction path '%s': %Rrc", pszDstDir, rc);
+    }
+
+    /*
+     * Extract files.
+     */
+    for (unsigned k = 0; k < cPackages; k++)
+    {
+        PVBOXSTUBPKG pPackage = FindPackageHeader(k);
+        if (!pPackage)
+            return RTEXITCODE_FAILURE; /* Done complaining already. */
+
+        if (fExtractOnly || PackageIsNeeded(pPackage))
+        {
+            char *pszDstFile = RTPathJoinA(pszDstDir, pPackage->szFileName);
+            if (!pszDstFile)
+                return ShowError("Out of memory on line %u!", __LINE__);
+
+            rc = Extract(pPackage, pszDstFile);
+            RTStrFree(pszDstFile);
+            if (RT_FAILURE(rc))
+                return ShowError("Error extracting package #%u: %Rrc", k, rc);
+        }
+    }
+
+    return RTEXITCODE_SUCCESS;
 }
 
@@ -363,5 +671,5 @@
     bool fExtractOnly              = false;
     bool fEnableLogging            = false;
-#ifdef VBOX_SIGNING_MODE
+#ifdef VBOX_WITH_CODE_SIGNING
     bool fEnableSilentCert         = true;
 #endif
@@ -378,5 +686,5 @@
         { "-silent",            's', RTGETOPT_REQ_NOTHING },
         { "/silent",            's', RTGETOPT_REQ_NOTHING },
-#ifdef VBOX_SIGNING_MODE
+#ifdef VBOX_WITH_CODE_SIGNING
         { "--no-silent-cert",   'c', RTGETOPT_REQ_NOTHING },
         { "-no-silent-cert",    'c', RTGETOPT_REQ_NOTHING },
@@ -418,5 +726,5 @@
                 break;
 
-#ifdef VBOX_SIGNING_MODE
+#ifdef VBOX_WITH_CODE_SIGNING
             case 'c':
                 fEnableSilentCert = false;
@@ -431,8 +739,5 @@
                 vrc = RTStrCopy(szExtractPath, sizeof(szExtractPath), ValueUnion.psz);
                 if (RT_FAILURE(vrc))
-                {
-                    ShowError("Extraction path is too long.");
-                    return RTEXITCODE_FAILURE;
-                }
+                    return ShowError("Extraction path is too long.");
                 break;
 
@@ -443,8 +748,5 @@
                     vrc = RTStrCat(szMSIArgs, sizeof(szMSIArgs), ValueUnion.psz);
                 if (RT_FAILURE(vrc))
-                {
-                    ShowError("MSI parameters are too long.");
-                    return RTEXITCODE_FAILURE;
-                }
+                    return ShowError("MSI parameters are too long.");
                 break;
 
@@ -488,212 +790,59 @@
     }
 
-    /** @todo The rest of this function should be done in smaller functions,
-     *        we've lost the overview here! Too much state going around! */
-
-    HRESULT hr = S_OK;
-
-    do /* break loop */
-    {
-        /*
-         * Determine and create our temp path (only if not already set).
-         */
-        if (szExtractPath[0] == '\0')
+    /*
+     * Determine the extration path if not given by the user, and gather some
+     * other bits we'll be needing later.
+     */
+    if (szExtractPath[0] == '\0')
+    {
+        vrc = RTPathTemp(szExtractPath, sizeof(szExtractPath));
+        if (RT_SUCCESS(vrc))
+            vrc = RTPathAppend(szExtractPath, sizeof(szExtractPath), "VirtualBox");
+        if (RT_FAILURE(vrc))
+            return ShowError("Failed to determin extraction path (%Rrc)", vrc);
+
+    }
+    RTPathChangeToDosSlashes(szExtractPath, true /* Force conversion. */); /* MSI requirement. */
+
+    /* Read our manifest. */
+    PVBOXSTUBPKGHEADER pHeader;
+    vrc = FindData("MANIFEST", (PVOID *)&pHeader, NULL);
+    if (RT_FAILURE(vrc))
+        return ShowError("Internal package error: Manifest not found (%Rrc)", vrc);
+    /** @todo If we could, we should validate the header. Only the magic isn't
+     *        commonly defined, nor the version number... */
+
+    /*
+     * Up to this point, we haven't done anything that requires any cleanup.
+     * From here on, we do everything in function so we can counter clean up.
+     */
+    RTEXITCODE rcExit = ExtractFiles(pHeader->byCntPkgs, szExtractPath, fExtractOnly);
+    if (rcExit == RTEXITCODE_SUCCESS)
+    {
+        if (fExtractOnly)
         {
-            vrc = RTPathTemp(szExtractPath, sizeof(szExtractPath));
-            AssertMsgRCBreak(vrc, ("Could not retrieve temp directory!\n"));
-
-            vrc = RTPathAppend(szExtractPath, sizeof(szExtractPath), "VirtualBox");
-            AssertMsgRCBreak(vrc, ("Could not construct temp directory!\n"));
-
-            /* Convert slahes; this is necessary for MSI routines later! */
-            RTPathChangeToDosSlashes(szExtractPath, true /* Force conversion. */);
+            if (!g_fSilent)
+                ShowInfo("Files were extracted to: %s", szExtractPath);
         }
-        if (!RTDirExists(szExtractPath))
+        else
         {
-            vrc = RTDirCreate(szExtractPath, 0700, 0);
-            AssertMsgRCBreak(vrc, ("Could not create temp directory!\n"));
-        }
-
-        /* Get our executable path */
-        char szPathExe[_MAX_PATH];
-        vrc = RTPathExecDir(szPathExe, sizeof(szPathExe));
-        /** @todo error checking */
-
-        /* Read our manifest. */
-        PVBOXSTUBPKGHEADER pHeader = NULL;
-        DWORD cbHeader = 0;
-        vrc = ReadData(NULL, "MANIFEST", (LPVOID*)&pHeader, &cbHeader);
-        AssertMsgRCBreak(vrc, ("Manifest not found!\n"));
-
-        /* Extract files. */
-        for (BYTE k = 0; k < pHeader->byCntPkgs; k++)
-        {
-            PVBOXSTUBPKG pPackage = NULL;
-            DWORD cbPackage = 0;
-            char szHeaderName[RTPATH_MAX + 1] = {0};
-
-            hr = ::StringCchPrintf(szHeaderName, RTPATH_MAX, "HDR_%02d", k);
-            vrc = ReadData(NULL, szHeaderName, (LPVOID*)&pPackage, &cbPackage);
-            AssertMsgRCBreak(vrc, ("Header not found!\n")); /** @todo include header name, how? */
-
-            if (PackageIsNeeded(pPackage) || fExtractOnly)
+            rcExit = CopyCustomDir(szExtractPath);
+#ifdef VBOX_WITH_CODE_SIGNING
+            if (rcExit == RTEXITCODE_SUCCESS && fEnableSilentCert && g_fSilent)
+                InstallCertificate();
+#endif
+            unsigned iPackage = 0;
+            while (iPackage < pHeader->byCntPkgs && rcExit == RTEXITCODE_SUCCESS)
             {
-                char *pszTempFile = NULL;
-                vrc = GetTempFileAlloc(szExtractPath, pPackage->szFileName, &pszTempFile);
-                AssertMsgRCBreak(vrc, ("Could not create name for temporary extracted file!\n"));
-                vrc = Extract(pPackage, pszTempFile);
-                AssertMsgRCBreak(vrc, ("Could not extract file!\n"));
-                RTStrFree(pszTempFile);
+                rcExit = ProcessPackage(iPackage, szExtractPath, szMSIArgs, fEnableLogging);
+                iPackage++;
             }
         }
-
-        if (FALSE == fExtractOnly && !RT_FAILURE(vrc))
-        {
-            /*
-             * Copy ".custom" directory into temp directory so that the extracted .MSI
-             * file(s) can use it.
-             */
-            char *pszPathCustomDir = RTPathJoinA(szPathExe, ".custom");
-            pszPathCustomDir = RTPathChangeToDosSlashes(pszPathCustomDir, true /* Force conversion. */);
-            if (pszPathCustomDir && RTDirExists(pszPathCustomDir))
-            {
-                vrc = CopyDir(szExtractPath, pszPathCustomDir);
-                if (RT_FAILURE(vrc)) /* Don't fail if it's missing! */
-                    vrc = VINF_SUCCESS;
-
-                RTStrFree(pszPathCustomDir);
-            }
-
-#ifdef VBOX_SIGNING_MODE
-            /*
-             * If --silent command line option is specified, do force public
-             * certificate install in background (i.e. completely prevent
-             * user interaction)
-             */
-            if (TRUE == g_fSilent && TRUE == fEnableSilentCert)
-            {
-                if (!addCertToStore(CERT_SYSTEM_STORE_LOCAL_MACHINE,
-                                    "TrustedPublisher",
-                                    g_ab_VBoxStubPublicCert,
-                                    sizeof(g_ab_VBoxStubPublicCert)))
-                {
-                    /* Interrupt installation */
-                    vrc = VERR_NO_CHANGE;
-                    break;
-                }
-            }
-#endif
-            /* Do actions on files. */
-            for (BYTE k = 0; k < pHeader->byCntPkgs; k++)
-            {
-                PVBOXSTUBPKG pPackage = NULL;
-                DWORD cbPackage = 0;
-                char szHeaderName[RTPATH_MAX] = {0};
-
-                hr = StringCchPrintf(szHeaderName, RTPATH_MAX, "HDR_%02d", k);
-                vrc = ReadData(NULL, szHeaderName, (LPVOID*)&pPackage, &cbPackage);
-                AssertMsgRCBreak(vrc, ("Package not found!\n"));
-
-                if (PackageIsNeeded(pPackage))
-                {
-                    char *pszTempFile = NULL;
-
-                    vrc = GetTempFileAlloc(szExtractPath, pPackage->szFileName, &pszTempFile);
-                    AssertMsgRCBreak(vrc, ("Could not create name for temporary action file!\n"));
-
-                    /* Handle MSI files. */
-                    if (RTStrICmp(RTPathExt(pszTempFile), ".msi") == 0)
-                    {
-                        /* Set UI level. */
-                        INSTALLUILEVEL UILevel = MsiSetInternalUI(  g_fSilent
-                                                                  ? INSTALLUILEVEL_NONE
-                                                                  : INSTALLUILEVEL_FULL,
-                                                                    NULL);
-                        AssertMsgBreak(UILevel != INSTALLUILEVEL_NOCHANGE, ("Could not set installer UI level!\n"));
-
-                        /* Enable logging? */
-                        if (fEnableLogging)
-                        {
-                            char *pszLog = RTPathJoinA(szExtractPath, "VBoxInstallLog.txt");
-                            /* Convert slahes; this is necessary for MSI routines! */
-                            pszLog = RTPathChangeToDosSlashes(pszLog, true /* Force conversion. */);
-                            AssertMsgBreak(pszLog, ("Could not construct path for log file!\n"));
-                            UINT uLogLevel = MsiEnableLog(INSTALLLOGMODE_VERBOSE,
-                                                          pszLog, INSTALLLOGATTRIBUTES_FLUSHEACHLINE);
-                            RTStrFree(pszLog);
-                            AssertMsgBreak(uLogLevel == ERROR_SUCCESS, ("Could not set installer logging level!\n"));
-                        }
-
-                        /* Initialize the common controls (extended version). This is necessary to
-                         * run the actual .MSI installers with the new fancy visual control
-                         * styles (XP+). Also, an integrated manifest is required. */
-                        INITCOMMONCONTROLSEX ccEx;
-                        ccEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
-                        ccEx.dwICC = ICC_LINK_CLASS | ICC_LISTVIEW_CLASSES | ICC_PAGESCROLLER_CLASS |
-                                     ICC_PROGRESS_CLASS | ICC_STANDARD_CLASSES | ICC_TAB_CLASSES | ICC_TREEVIEW_CLASSES |
-                                     ICC_UPDOWN_CLASS | ICC_USEREX_CLASSES | ICC_WIN95_CLASSES;
-                        InitCommonControlsEx(&ccEx); /* Ignore failure. */
-
-                        UINT uStatus = ::MsiInstallProductA(pszTempFile, szMSIArgs);
-                        if (   (uStatus != ERROR_SUCCESS)
-                            && (uStatus != ERROR_SUCCESS_REBOOT_REQUIRED)
-                            && (uStatus != ERROR_INSTALL_USEREXIT))
-                        {
-                            switch (uStatus)
-                            {
-                                case ERROR_INSTALL_PACKAGE_VERSION:
-                                    ShowError("This installation package cannot be installed by the Windows Installer service.\n"
-                                              "You must install a Windows service pack that contains a newer version of the Windows Installer service.");
-                                    break;
-
-                                case ERROR_INSTALL_PLATFORM_UNSUPPORTED:
-                                    ShowError("This installation package is not supported on this platform.");
-                                    break;
-
-                                default:
-                                {
-                                    DWORD dwFormatFlags =   FORMAT_MESSAGE_ALLOCATE_BUFFER
-                                                          | FORMAT_MESSAGE_IGNORE_INSERTS
-                                                          | FORMAT_MESSAGE_FROM_SYSTEM;
-                                    HMODULE hModule = NULL;
-                                    if (uStatus >= NERR_BASE && uStatus <= MAX_NERR)
-                                    {
-                                        hModule = LoadLibraryEx(TEXT("netmsg.dll"),
-                                                                NULL,
-                                                                LOAD_LIBRARY_AS_DATAFILE);
-                                        if (hModule != NULL)
-                                            dwFormatFlags |= FORMAT_MESSAGE_FROM_HMODULE;
-                                    }
-
-                                    DWORD dwBufferLength;
-                                    LPSTR szMessageBuffer;
-                                    if (dwBufferLength = FormatMessageA(dwFormatFlags,
-                                                                        hModule, /* If NULL, load system stuff. */
-                                                                        uStatus,
-                                                                        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-                                                                        (LPSTR)&szMessageBuffer,
-                                                                        0,
-                                                                        NULL))
-                                    {
-                                        ShowError("Installation failed! Error: %s", szMessageBuffer);
-                                        LocalFree(szMessageBuffer);
-                                    }
-                                    else /* If text lookup failed, show at least the error number. */
-                                        ShowError("Installation failed! Error: %u", uStatus);
-                                    if (hModule)
-                                        FreeLibrary(hModule);
-                                    /** @todo program exit code needs to be set */
-                                    break;
-                                }
-                            }
-
-                            vrc = VERR_NO_CHANGE; /* No change done to the system. */
-                        }
-                            /** @todo program exit code needs to be for ERROR_INSTALL_USEREXIT. */
-                    }
-                    RTStrFree(pszTempFile);
-                } /* Package needed? */
-            } /* For all packages */
-        }
+    }
+
+
+
+    do /* break loop */
+    {
 
         /* Clean up (only on success - prevent deleting the log). */
@@ -712,15 +861,4 @@
     } while (0);
 
-    if (RT_SUCCESS(vrc))
-    {
-        if (   fExtractOnly
-            && !g_fSilent)
-        {
-            ShowInfo("Files were extracted to: %s", szExtractPath);
-        }
-
-        /** @todo Add more post installation stuff here if required. */
-    }
-
     /* Release instance mutex. */
     if (hMutexAppRunning != NULL)
@@ -730,10 +868,4 @@
     }
 
-    /*
-     * Figure the exit code (not very difficult at the moment).
-     */
-    RTEXITCODE rcExit = RTEXITCODE_SUCCESS;
-    if (RT_FAILURE(vrc))
-        rcExit = RTEXITCODE_FAILURE;
     return rcExit;
 }
Index: /trunk/src/VBox/Installer/win/Stub/resource.h
===================================================================
--- /trunk/src/VBox/Installer/win/Stub/resource.h	(revision 45319)
+++ /trunk/src/VBox/Installer/win/Stub/resource.h	(revision 45320)
@@ -15,7 +15,11 @@
  * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
  */
+
+
 #define IDI_VIRTUALBOX 101
 
-#define RT_MANIFEST 24
+#ifndef RT_MANIFEST
+# define RT_MANIFEST 24
+#endif
 #define APP_MANIFEST 1
 
