ExtPackManagerImpl.cpp revision 8479df0918362ee801608d4f48c6d8ee8fdf505e
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync/* $Id$ */
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync/** @file
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync * VirtualBox Main - interface for Extension Packs, VBoxSVC & VBoxC.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync */
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync/*
c58f1213e628a545081c70e26c6b67a841cff880vboxsync * Copyright (C) 2010 Oracle Corporation
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync *
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * available from http://www.virtualbox.org. This file is free software;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * you can redistribute it and/or modify it under the terms of the GNU
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * General Public License (GPL) as published by the Free Software
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync */
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync/*******************************************************************************
c4bfe32373c55416bf49dc29ebf45dfa560b4692vboxsync* Header Files *
c4bfe32373c55416bf49dc29ebf45dfa560b4692vboxsync*******************************************************************************/
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync#include "ExtPackManagerImpl.h"
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync#include "ExtPackUtil.h"
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync#include <iprt/buildconfig.h>
61f058cfcc81ec889fc17ac84c25a118a91d1423vboxsync#include <iprt/ctype.h>
90fd0059d671978f9db54fab8d5daa3635a4b25avboxsync#include <iprt/dir.h>
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync#include <iprt/env.h>
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync#include <iprt/file.h>
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync#include <iprt/ldr.h>
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync#include <iprt/param.h>
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync#include <iprt/path.h>
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync#include <iprt/pipe.h>
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync#include <iprt/process.h>
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync#include <iprt/string.h>
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync#include <VBox/com/array.h>
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync#include <VBox/com/ErrorInfo.h>
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync#include <VBox/log.h>
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync#include <VBox/sup.h>
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync#include <VBox/version.h>
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync#include "AutoCaller.h"
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync#include "Global.h"
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync/*******************************************************************************
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync* Defined Constants And Macros *
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync*******************************************************************************/
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync/** @name VBOX_EXTPACK_HELPER_NAME
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync * The name of the utility application we employ to install and uninstall the
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync * extension packs. This is a set-uid-to-root binary on unixy platforms, which
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync * is why it has to be a separate application.
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync */
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync# define VBOX_EXTPACK_HELPER_NAME "VBoxExtPackHelper.exe"
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync#else
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync# define VBOX_EXTPACK_HELPER_NAME "VBoxExtPackHelper"
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync#endif
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync/*******************************************************************************
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync* Structures and Typedefs *
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync*******************************************************************************/
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync/**
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync * Private extension pack data.
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync */
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsyncstruct ExtPack::Data
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync{
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsyncpublic:
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync /** The extension pack descriptor (loaded from the XML, mostly). */
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync VBOXEXTPACKDESC Desc;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync /** The file system object info of the XML file.
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync * This is for detecting changes and save time in refresh(). */
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync RTFSOBJINFO ObjInfoDesc;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync /** Whether it's usable or not. */
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync bool fUsable;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync /** Why it is unusable. */
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync Utf8Str strWhyUnusable;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
730f8be51b729e8a3c1e32c756cd0f4ec088dd4dvboxsync /** Where the extension pack is located. */
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync Utf8Str strExtPackPath;
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync /** The file system object info of the extension pack directory.
730f8be51b729e8a3c1e32c756cd0f4ec088dd4dvboxsync * This is for detecting changes and save time in refresh(). */
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync RTFSOBJINFO ObjInfoExtPack;
77db08a24f69bca943d5abc40b1930ee97f593edvboxsync /** The full path to the main module. */
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync Utf8Str strMainModPath;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync /** The file system object info of the main module.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * This is used to determin whether to bother try reload it. */
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync RTFSOBJINFO ObjInfoMainMod;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync /** The module handle of the main extension pack module. */
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync RTLDRMOD hMainMod;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync /** The helper callbacks for the extension pack. */
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync VBOXEXTPACKHLP Hlp;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync /** Pointer back to the extension pack object (for Hlp methods). */
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync ExtPack *pThis;
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync /** The extension pack registration structure. */
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync PCVBOXEXTPACKREG pReg;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync};
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync/** List of extension packs. */
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsynctypedef std::list< ComObjPtr<ExtPack> > ExtPackList;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync/**
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * Private extension pack manager data.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync */
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsyncstruct ExtPackManager::Data
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync{
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync /** The directory where the extension packs are installed. */
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync Utf8Str strBaseDir;
aa131431882ca8e44b0480d4af0b5d139f1bde21vboxsync /** The directory where the extension packs can be dropped for automatic
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * installation. */
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync Utf8Str strDropZoneDir;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync /** The directory where the certificates this installation recognizes are
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * stored. */
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync Utf8Str strCertificatDirPath;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync /** The list of installed extension packs. */
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync ExtPackList llInstalledExtPacks;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync};
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsyncDEFINE_EMPTY_CTOR_DTOR(ExtPack)
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync/**
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * Called by ComObjPtr::createObject when creating the object.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync *
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * Just initialize the basic object state, do the rest in init().
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync *
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * @returns S_OK.
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync */
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsyncHRESULT ExtPack::FinalConstruct()
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync{
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync m = NULL;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync return S_OK;
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync}
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync/**
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync * Initializes the extension pack by reading its file.
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync *
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync * @returns COM status code.
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync * @param a_pszName The name of the extension pack. This is also the
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync * name of the subdirector under @a a_pszParentDir
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync * where the extension pack is installed.
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync * @param a_pszParentDir The parent directory.
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync */
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsyncHRESULT ExtPack::init(const char *a_pszName, const char *a_pszParentDir)
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync{
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync AutoInitSpan autoInitSpan(this);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync AssertReturn(autoInitSpan.isOk(), E_FAIL);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync static const VBOXEXTPACKHLP s_HlpTmpl =
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync {
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync /* u32Version = */ VBOXEXTPACKHLP_VERSION,
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync /* uVBoxFullVersion = */ VBOX_FULL_VERSION,
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync /* uVBoxVersionRevision = */ 0,
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync /* u32Padding = */ 0,
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync /* pszVBoxVersion = */ "",
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync /* pfnFindModule = */ ExtPack::hlpFindModule,
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync /* pfnGetFilePath = */ ExtPack::hlpGetFilePath,
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync /* u32EndMarker = */ VBOXEXTPACKHLP_VERSION
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync };
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync /*
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync * Figure out where we live and allocate + initialize our private data.
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync */
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync char szDir[RTPATH_MAX];
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync int vrc = RTPathJoin(szDir, sizeof(szDir), a_pszParentDir, a_pszName);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync AssertLogRelRCReturn(vrc, E_FAIL);
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync m = new Data;
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync m->Desc.strName = a_pszName;
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync RT_ZERO(m->ObjInfoDesc);
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync m->fUsable = false;
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync m->strWhyUnusable = tr("ExtPack::init failed");
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync m->strExtPackPath = szDir;
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync RT_ZERO(m->ObjInfoExtPack);
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync m->strMainModPath.setNull();
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync RT_ZERO(m->ObjInfoMainMod);
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync m->hMainMod = NIL_RTLDRMOD;
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync m->Hlp = s_HlpTmpl;
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync m->Hlp.pszVBoxVersion = RTBldCfgVersion();
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync m->Hlp.uVBoxInternalRevision = RTBldCfgRevision();
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync m->pThis = this;
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync m->pReg = NULL;
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync /*
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync * Probe the extension pack (this code is shared with refresh()).
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync */
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync probeAndLoad();
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync autoInitSpan.setSucceeded();
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync return S_OK;
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync}
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync/**
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync * COM cruft.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync */
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsyncvoid ExtPack::FinalRelease()
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync{
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync uninit();
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync}
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync/**
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * Do the actual cleanup.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync */
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsyncvoid ExtPack::uninit()
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync{
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync /* Enclose the state transition Ready->InUninit->NotReady */
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync AutoUninitSpan autoUninitSpan(this);
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync if (!autoUninitSpan.uninitDone() && m != NULL)
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync {
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync if (m->hMainMod != NIL_RTLDRMOD)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync AssertPtr(m->pReg);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (m->pReg->pfnUnload != NULL)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync m->pReg->pfnUnload(m->pReg);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync RTLdrClose(m->hMainMod);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync m->hMainMod = NIL_RTLDRMOD;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync m->pReg = NULL;
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync delete m;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync m = NULL;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync}
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync/**
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync * Calls the installed hook.
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync * @remarks Caller holds the extension manager lock.
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync */
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsyncvoid ExtPack::callInstalledHook(void)
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync{
32e575e61406701e77c0527bfc843fdc85c4003fvboxsync if ( m->hMainMod != NIL_RTLDRMOD
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync && m->pReg->pfnInstalled)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync m->pReg->pfnInstalled(m->pReg);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync}
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync/**
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * Calls the uninstall hook and closes the module.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync *
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * @returns S_OK or COM error status with error information.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * @param a_fForcedRemoval When set, we'll ignore complaints from the
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync * uninstall hook.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * @remarks The caller holds the manager's write lock.
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync */
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsyncHRESULT ExtPack::callUninstallHookAndClose(bool a_fForcedRemoval)
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync{
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync HRESULT hrc = S_OK;
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (m->hMainMod != NIL_RTLDRMOD)
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (m->pReg->pfnUninstall)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync int vrc = m->pReg->pfnUninstall(m->pReg);
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync if (RT_FAILURE(vrc))
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync {
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync LogRel(("ExtPack pfnUninstall returned %Rrc for %s\n", vrc, m->Desc.strName.c_str()));
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync if (!a_fForcedRemoval)
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync hrc = setError(E_FAIL, tr("pfnUninstall returned %Rrc"), vrc);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (SUCCEEDED(hrc))
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync RTLdrClose(m->hMainMod);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync m->hMainMod = NIL_RTLDRMOD;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync m->pReg = NULL;
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync }
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync return hrc;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync}
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync/**
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync * Calls the pfnVMCreate hook.
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync *
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync * @param a_pMachine The machine interface of the new VM.
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync * @remarks Caller holds the extension manager lock.
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync */
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsyncvoid ExtPack::callVmCreatedHook(IMachine *a_pMachine)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync{
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if ( m->hMainMod != NIL_RTLDRMOD
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync && m->pReg->pfnVMCreated)
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync m->pReg->pfnVMCreated(m->pReg, a_pMachine);
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync}
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync
3c9ed6defa3feca7e21adef4b5d1ba3002fc94c9vboxsync/**
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * Calls the pfnVMConfigureVMM hook.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync *
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync * @returns VBox status code, LogRel called on failure.
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync * @param a_pConsole The console interface.
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync * @param a_pVM The VM handle.
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync * @remarks Caller holds the extension manager lock.
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync */
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsyncint ExtPack::callVmConfigureVmmHook(IConsole *a_pConsole, PVM a_pVM)
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync{
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if ( m->hMainMod != NIL_RTLDRMOD
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync && m->pReg->pfnVMConfigureVMM)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync int vrc = m->pReg->pfnVMConfigureVMM(m->pReg, a_pConsole, a_pVM);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (RT_FAILURE(vrc))
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync LogRel(("ExtPack pfnVMConfigureVMM returned %Rrc for %s\n", vrc, m->Desc.strName.c_str()));
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync return vrc;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync }
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync return VINF_SUCCESS;
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync}
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync/**
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * Calls the pfnVMPowerOn hook.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync *
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * @returns VBox status code, LogRel called on failure.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * @param a_pConsole The console interface.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * @param a_pVM The VM handle.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * @remarks Caller holds the extension manager lock.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync */
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsyncint ExtPack::callVmPowerOnHook(IConsole *a_pConsole, PVM a_pVM)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync{
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if ( m->hMainMod != NIL_RTLDRMOD
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync && m->pReg->pfnVMPowerOn)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync int vrc = m->pReg->pfnVMPowerOn(m->pReg, a_pConsole, a_pVM);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (RT_FAILURE(vrc))
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync {
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync LogRel(("ExtPack pfnVMPowerOn returned %Rrc for %s\n", vrc, m->Desc.strName.c_str()));
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync return vrc;
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync }
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync }
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync return VINF_SUCCESS;
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync}
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync/**
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync * Calls the pfnVMPowerOff hook.
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync *
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync * @param a_pConsole The console interface.
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync * @param a_pVM The VM handle.
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync * @remarks Caller holds the extension manager lock.
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync */
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsyncvoid ExtPack::callVmPowerOffHook(IConsole *a_pConsole, PVM a_pVM)
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync{
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync if ( m->hMainMod != NIL_RTLDRMOD
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync && m->pReg->pfnVMPowerOff)
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync m->pReg->pfnVMPowerOff(m->pReg, a_pConsole, a_pVM);
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync}
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync/**
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync * Refreshes the extension pack state.
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync *
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync * This is called by the manager so that the on disk changes are picked up.
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync *
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync * @returns S_OK or COM error status with error information.
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync * @param pfCanDelete Optional can-delete-this-object output indicator.
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync * @remarks Caller holds the extension manager lock for writing.
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync */
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsyncHRESULT ExtPack::refresh(bool *pfCanDelete)
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync{
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync if (pfCanDelete)
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync *pfCanDelete = false;
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync AutoWriteLock autoLock(this COMMA_LOCKVAL_SRC_POS); /* for the COMGETTERs */
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync /*
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync * Has the module been deleted?
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync */
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync RTFSOBJINFO ObjInfoExtPack;
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync int vrc = RTPathQueryInfoEx(m->strExtPackPath.c_str(), &ObjInfoExtPack, RTFSOBJATTRADD_UNIX, RTPATH_F_ON_LINK);
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync if ( RT_FAILURE(vrc)
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync || !RTFS_IS_DIRECTORY(ObjInfoExtPack.Attr.fMode))
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync {
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync if (pfCanDelete)
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync *pfCanDelete = true;
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync return S_OK;
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync }
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync /*
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync * We've got a directory, so try query file system object info for the
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync * files we are interested in as well.
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync */
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync RTFSOBJINFO ObjInfoDesc;
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync char szDescFilePath[RTPATH_MAX];
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync vrc = RTPathJoin(szDescFilePath, sizeof(szDescFilePath), m->strExtPackPath.c_str(), VBOX_EXTPACK_DESCRIPTION_NAME);
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync if (RT_SUCCESS(vrc))
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync vrc = RTPathQueryInfoEx(szDescFilePath, &ObjInfoDesc, RTFSOBJATTRADD_UNIX, RTPATH_F_ON_LINK);
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync if (RT_FAILURE(vrc))
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync RT_ZERO(ObjInfoDesc);
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync RTFSOBJINFO ObjInfoMainMod;
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync if (m->strMainModPath.isNotEmpty())
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync vrc = RTPathQueryInfoEx(m->strMainModPath.c_str(), &ObjInfoMainMod, RTFSOBJATTRADD_UNIX, RTPATH_F_ON_LINK);
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync if (m->strMainModPath.isEmpty() || RT_FAILURE(vrc))
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync RT_ZERO(ObjInfoMainMod);
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync /*
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync * If we have a usable module already, just verify that things haven't
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync * changed since we loaded it.
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync */
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync if (m->fUsable)
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync {
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync /** @todo not important, so it can wait. */
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync }
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync /*
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync * Ok, it is currently not usable. If anything has changed since last time
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync * reprobe the extension pack.
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync */
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync else if ( !objinfoIsEqual(&ObjInfoDesc, &m->ObjInfoDesc)
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync || !objinfoIsEqual(&ObjInfoMainMod, &m->ObjInfoMainMod)
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync || !objinfoIsEqual(&ObjInfoExtPack, &m->ObjInfoExtPack) )
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync probeAndLoad();
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync return S_OK;
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync}
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync/**
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync * Probes the extension pack, loading the main dll and calling its registration
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync * entry point.
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync *
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync * This updates the state accordingly, the strWhyUnusable and fUnusable members
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync * being the most important ones.
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync */
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsyncvoid ExtPack::probeAndLoad(void)
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync{
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync m->fUsable = false;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync /*
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync * Query the file system info for the extension pack directory. This and
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync * all other file system info we save is for the benefit of refresh().
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync */
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync int vrc = RTPathQueryInfoEx(m->strExtPackPath.c_str(), &m->ObjInfoExtPack, RTFSOBJATTRADD_UNIX, RTPATH_F_ON_LINK);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync if (RT_FAILURE(vrc))
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync {
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync m->strWhyUnusable.printf(tr("RTPathQueryInfoEx on '%s' failed: %Rrc"), m->strExtPackPath.c_str(), vrc);
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync return;
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync }
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync if (!RTFS_IS_DIRECTORY(m->ObjInfoExtPack.Attr.fMode))
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync {
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync if (RTFS_IS_SYMLINK(m->ObjInfoExtPack.Attr.fMode))
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync m->strWhyUnusable.printf(tr("'%s' is a symbolic link, this is not allowed"), m->strExtPackPath.c_str(), vrc);
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync else if (RTFS_IS_FILE(m->ObjInfoExtPack.Attr.fMode))
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync m->strWhyUnusable.printf(tr("'%s' is a symbolic file, not a directory"), m->strExtPackPath.c_str(), vrc);
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync else
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync m->strWhyUnusable.printf(tr("'%s' is not a directory (fMode=%#x)"), m->strExtPackPath.c_str(), m->ObjInfoExtPack.Attr.fMode);
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync return;
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync }
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync char szErr[2048];
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync RT_ZERO(szErr);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync vrc = SUPR3HardenedVerifyDir(m->strExtPackPath.c_str(), true /*fRecursive*/, true /*fCheckFiles*/, szErr, sizeof(szErr));
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (RT_FAILURE(vrc))
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync m->strWhyUnusable.printf(tr("%s (rc=%Rrc)"), szErr, vrc);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync return;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync /*
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * Read the description file.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync */
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync iprt::MiniString strSavedName(m->Desc.strName);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync iprt::MiniString *pStrLoadErr = VBoxExtPackLoadDesc(m->strExtPackPath.c_str(), &m->Desc, &m->ObjInfoDesc);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (pStrLoadErr != NULL)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync m->strWhyUnusable.printf(tr("Failed to load '%s/%s': %s"),
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync m->strExtPackPath.c_str(), VBOX_EXTPACK_DESCRIPTION_NAME, pStrLoadErr->c_str());
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync m->Desc.strName = strSavedName;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync delete pStrLoadErr;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync return;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync /*
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * Make sure the XML name and directory matches.
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync */
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (!m->Desc.strName.equalsIgnoreCase(strSavedName))
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync m->strWhyUnusable.printf(tr("The description name ('%s') and directory name ('%s') does not match"),
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync m->Desc.strName.c_str(), strSavedName.c_str());
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync m->Desc.strName = strSavedName;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync return;
c9a593aa048a154e59b52d1237d89e3cdaee9b3dvboxsync }
c9a593aa048a154e59b52d1237d89e3cdaee9b3dvboxsync
c9a593aa048a154e59b52d1237d89e3cdaee9b3dvboxsync /*
c9a593aa048a154e59b52d1237d89e3cdaee9b3dvboxsync * Load the main DLL and call the predefined entry point.
c9a593aa048a154e59b52d1237d89e3cdaee9b3dvboxsync */
c9a593aa048a154e59b52d1237d89e3cdaee9b3dvboxsync bool fIsNative;
c9a593aa048a154e59b52d1237d89e3cdaee9b3dvboxsync if (!findModule(m->Desc.strMainModule.c_str(), NULL /* default extension */,
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync &m->strMainModPath, &fIsNative, &m->ObjInfoMainMod))
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync m->strWhyUnusable.printf(tr("Failed to locate the main module ('%s')"), m->Desc.strMainModule.c_str());
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync return;
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync vrc = SUPR3HardenedVerifyPlugIn(m->strMainModPath.c_str(), szErr, sizeof(szErr));
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (RT_FAILURE(vrc))
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync m->strWhyUnusable.printf(tr("%s"), szErr);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync return;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync if (fIsNative)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync vrc = RTLdrLoad(m->strMainModPath.c_str(), &m->hMainMod);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (RT_FAILURE(vrc))
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync m->hMainMod = NIL_RTLDRMOD;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync m->strWhyUnusable.printf(tr("Failed to locate load the main module ('%s'): %Rrc"),
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync m->strMainModPath.c_str(), vrc);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync return;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync }
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync else
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync m->strWhyUnusable.printf(tr("Only native main modules are currently supported"));
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync return;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync /*
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * Resolve the predefined entry point.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync */
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync PFNVBOXEXTPACKREGISTER pfnRegistration;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync vrc = RTLdrGetSymbol(m->hMainMod, VBOX_EXTPACK_MAIN_MOD_ENTRY_POINT, (void **)&pfnRegistration);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (RT_SUCCESS(vrc))
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync RT_ZERO(szErr);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync vrc = pfnRegistration(&m->Hlp, &m->pReg, szErr, sizeof(szErr) - 16);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if ( RT_SUCCESS(vrc)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync && szErr[0] == '\0'
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync && VALID_PTR(m->pReg))
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if ( m->pReg->u32Version == VBOXEXTPACKREG_VERSION
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync && m->pReg->u32EndMarker == VBOXEXTPACKREG_VERSION)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if ( (!m->pReg->pfnInstalled || RT_VALID_PTR(m->pReg->pfnInstalled))
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync && (!m->pReg->pfnUninstall || RT_VALID_PTR(m->pReg->pfnUninstall))
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync && (!m->pReg->pfnUnload || RT_VALID_PTR(m->pReg->pfnUnload))
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync && (!m->pReg->pfnVMCreated || RT_VALID_PTR(m->pReg->pfnVMCreated))
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync && (!m->pReg->pfnVMConfigureVMM || RT_VALID_PTR(m->pReg->pfnVMConfigureVMM))
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync && (!m->pReg->pfnVMPowerOn || RT_VALID_PTR(m->pReg->pfnVMPowerOn))
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync && (!m->pReg->pfnVMPowerOff || RT_VALID_PTR(m->pReg->pfnVMPowerOff))
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync && (!m->pReg->pfnQueryObject || RT_VALID_PTR(m->pReg->pfnQueryObject))
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync )
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync {
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync /*
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * We're good!
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync */
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync m->fUsable = true;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync m->strWhyUnusable.setNull();
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync return;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync m->strWhyUnusable = tr("The registration structure contains on or more invalid function pointers");
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync else
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync m->strWhyUnusable.printf(tr("Unsupported registration structure version %u.%u"),
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync RT_HIWORD(m->pReg->u32Version), RT_LOWORD(m->pReg->u32Version));
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync else
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync {
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync szErr[sizeof(szErr) - 1] = '\0';
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync m->strWhyUnusable.printf(tr("%s returned %Rrc, pReg=%p szErr='%s'"),
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync VBOX_EXTPACK_MAIN_MOD_ENTRY_POINT, vrc, m->pReg, szErr);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync m->pReg = NULL;
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync else
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync m->strWhyUnusable.printf(tr("Failed to resolve exported symbol '%s' in the main module: %Rrc"),
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync VBOX_EXTPACK_MAIN_MOD_ENTRY_POINT, vrc);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync RTLdrClose(m->hMainMod);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync m->hMainMod = NIL_RTLDRMOD;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync}
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync/**
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * Finds a module.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync *
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * @returns true if found, false if not.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * @param a_pszName The module base name (no extension).
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * @param a_pszExt The extension. If NULL we use default
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * extensions.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * @param a_pStrFound Where to return the path to the module we've
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * found.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * @param a_pfNative Where to return whether this is a native module
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * or an agnostic one. Optional.
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync * @param a_pObjInfo Where to return the file system object info for
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * the module. Optional.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync */
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsyncbool ExtPack::findModule(const char *a_pszName, const char *a_pszExt,
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync Utf8Str *a_pStrFound, bool *a_pfNative, PRTFSOBJINFO a_pObjInfo) const
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync{
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync /*
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync * Try the native path first.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync */
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync char szPath[RTPATH_MAX];
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync int vrc = RTPathJoin(szPath, sizeof(szPath), m->strExtPackPath.c_str(), RTBldCfgTargetDotArch());
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync AssertLogRelRCReturn(vrc, false);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync vrc = RTPathAppend(szPath, sizeof(szPath), a_pszName);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync AssertLogRelRCReturn(vrc, false);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (!a_pszExt)
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync {
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync vrc = RTStrCat(szPath, sizeof(szPath), RTLdrGetSuff());
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync AssertLogRelRCReturn(vrc, false);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync RTFSOBJINFO ObjInfo;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (!a_pObjInfo)
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync a_pObjInfo = &ObjInfo;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync vrc = RTPathQueryInfo(szPath, a_pObjInfo, RTFSOBJATTRADD_UNIX);
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync if (RT_SUCCESS(vrc) && RTFS_IS_FILE(a_pObjInfo->Attr.fMode))
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync if (a_pfNative)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync *a_pfNative = true;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync *a_pStrFound = szPath;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync return true;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync /*
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * Try the platform agnostic modules.
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync */
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync /* gcc.x86/module.rel */
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync char szSubDir[32];
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync RTStrPrintf(szSubDir, sizeof(szSubDir), "%s.%s", RTBldCfgCompiler(), RTBldCfgTargetArch());
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync vrc = RTPathJoin(szPath, sizeof(szPath), m->strExtPackPath.c_str(), szSubDir);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync AssertLogRelRCReturn(vrc, false);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync vrc = RTPathAppend(szPath, sizeof(szPath), a_pszName);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync AssertLogRelRCReturn(vrc, false);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (!a_pszExt)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync vrc = RTStrCat(szPath, sizeof(szPath), ".rel");
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync AssertLogRelRCReturn(vrc, false);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync vrc = RTPathQueryInfo(szPath, a_pObjInfo, RTFSOBJATTRADD_UNIX);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync if (RT_SUCCESS(vrc) && RTFS_IS_FILE(a_pObjInfo->Attr.fMode))
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync {
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync if (a_pfNative)
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync *a_pfNative = false;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync *a_pStrFound = szPath;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync return true;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync /* x86/module.rel */
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync vrc = RTPathJoin(szPath, sizeof(szPath), m->strExtPackPath.c_str(), RTBldCfgTargetArch());
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync AssertLogRelRCReturn(vrc, false);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync vrc = RTPathAppend(szPath, sizeof(szPath), a_pszName);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync AssertLogRelRCReturn(vrc, false);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (!a_pszExt)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync vrc = RTStrCat(szPath, sizeof(szPath), ".rel");
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync AssertLogRelRCReturn(vrc, false);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync }
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync vrc = RTPathQueryInfo(szPath, a_pObjInfo, RTFSOBJATTRADD_UNIX);
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync if (RT_SUCCESS(vrc) && RTFS_IS_FILE(a_pObjInfo->Attr.fMode))
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (a_pfNative)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync *a_pfNative = false;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync *a_pStrFound = szPath;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync return true;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync return false;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync}
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync/**
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * Compares two file system object info structures.
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync *
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * @returns true if equal, false if not.
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync * @param pObjInfo1 The first.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * @param pObjInfo2 The second.
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync * @todo IPRT should do this, really.
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync */
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync/* static */ bool ExtPack::objinfoIsEqual(PCRTFSOBJINFO pObjInfo1, PCRTFSOBJINFO pObjInfo2)
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync{
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync if (!RTTimeSpecIsEqual(&pObjInfo1->ModificationTime, &pObjInfo2->ModificationTime))
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync return false;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync if (!RTTimeSpecIsEqual(&pObjInfo1->ChangeTime, &pObjInfo2->ChangeTime))
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync return false;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync if (!RTTimeSpecIsEqual(&pObjInfo1->BirthTime, &pObjInfo2->BirthTime))
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync return false;
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync if (pObjInfo1->cbObject != pObjInfo2->cbObject)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync return false;
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync if (pObjInfo1->Attr.fMode != pObjInfo2->Attr.fMode)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync return false;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (pObjInfo1->Attr.enmAdditional == pObjInfo2->Attr.enmAdditional)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync switch (pObjInfo1->Attr.enmAdditional)
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync case RTFSOBJATTRADD_UNIX:
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (pObjInfo1->Attr.u.Unix.uid != pObjInfo2->Attr.u.Unix.uid)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync return false;
3c9ed6defa3feca7e21adef4b5d1ba3002fc94c9vboxsync if (pObjInfo1->Attr.u.Unix.gid != pObjInfo2->Attr.u.Unix.gid)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync return false;
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync if (pObjInfo1->Attr.u.Unix.INodeIdDevice != pObjInfo2->Attr.u.Unix.INodeIdDevice)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync return false;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (pObjInfo1->Attr.u.Unix.INodeId != pObjInfo2->Attr.u.Unix.INodeId)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync return false;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync if (pObjInfo1->Attr.u.Unix.GenerationId != pObjInfo2->Attr.u.Unix.GenerationId)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync return false;
3c9ed6defa3feca7e21adef4b5d1ba3002fc94c9vboxsync break;
3c9ed6defa3feca7e21adef4b5d1ba3002fc94c9vboxsync default:
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync break;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync return true;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync}
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
3c9ed6defa3feca7e21adef4b5d1ba3002fc94c9vboxsync/**
3c9ed6defa3feca7e21adef4b5d1ba3002fc94c9vboxsync * @interface_method_impl{VBOXEXTPACKHLP,pfnFindModule}
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync */
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync/*static*/ DECLCALLBACK(int)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsyncExtPack::hlpFindModule(PCVBOXEXTPACKHLP pHlp, const char *pszName, const char *pszExt,
3c9ed6defa3feca7e21adef4b5d1ba3002fc94c9vboxsync char *pszFound, size_t cbFound, bool *pfNative)
3c9ed6defa3feca7e21adef4b5d1ba3002fc94c9vboxsync{
3c9ed6defa3feca7e21adef4b5d1ba3002fc94c9vboxsync /*
3c9ed6defa3feca7e21adef4b5d1ba3002fc94c9vboxsync * Validate the input and get our bearings.
3c9ed6defa3feca7e21adef4b5d1ba3002fc94c9vboxsync */
3c9ed6defa3feca7e21adef4b5d1ba3002fc94c9vboxsync AssertPtrReturn(pszName, VERR_INVALID_POINTER);
3c9ed6defa3feca7e21adef4b5d1ba3002fc94c9vboxsync AssertPtrNullReturn(pszExt, VERR_INVALID_POINTER);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync AssertPtrReturn(pszFound, VERR_INVALID_POINTER);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync AssertPtrNullReturn(pfNative, VERR_INVALID_POINTER);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync AssertPtrReturn(pHlp, VERR_INVALID_POINTER);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync AssertReturn(pHlp->u32Version == VBOXEXTPACKHLP_VERSION, VERR_INVALID_POINTER);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync ExtPack::Data *m = RT_FROM_CPP_MEMBER(pHlp, Data, Hlp);
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync AssertPtrReturn(m, VERR_INVALID_POINTER);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync ExtPack *pThis = m->pThis;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync AssertPtrReturn(pThis, VERR_INVALID_POINTER);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync /*
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync * This is just a wrapper around findModule.
3c9ed6defa3feca7e21adef4b5d1ba3002fc94c9vboxsync */
3c9ed6defa3feca7e21adef4b5d1ba3002fc94c9vboxsync Utf8Str strFound;
3c9ed6defa3feca7e21adef4b5d1ba3002fc94c9vboxsync if (pThis->findModule(pszName, pszExt, &strFound, pfNative, NULL))
3c9ed6defa3feca7e21adef4b5d1ba3002fc94c9vboxsync return RTStrCopy(pszFound, cbFound, strFound.c_str());
3c9ed6defa3feca7e21adef4b5d1ba3002fc94c9vboxsync return VERR_FILE_NOT_FOUND;
3c9ed6defa3feca7e21adef4b5d1ba3002fc94c9vboxsync}
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync/*static*/ DECLCALLBACK(int)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsyncExtPack::hlpGetFilePath(PCVBOXEXTPACKHLP pHlp, const char *pszFilename, char *pszPath, size_t cbPath)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync{
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync /*
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * Validate the input and get our bearings.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync */
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync AssertPtrReturn(pszFilename, VERR_INVALID_POINTER);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync AssertReturn(cbPath > 0, VERR_BUFFER_OVERFLOW);
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync AssertPtrReturn(pHlp, VERR_INVALID_POINTER);
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync AssertReturn(pHlp->u32Version == VBOXEXTPACKHLP_VERSION, VERR_INVALID_POINTER);
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync ExtPack::Data *m = RT_FROM_CPP_MEMBER(pHlp, Data, Hlp);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync AssertPtrReturn(m, VERR_INVALID_POINTER);
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync ExtPack *pThis = m->pThis;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync AssertPtrReturn(pThis, VERR_INVALID_POINTER);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync /*
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync * This is a simple RTPathJoin, no checking if things exists or anything.
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync */
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync int vrc = RTPathJoin(pszPath, cbPath, pThis->m->strExtPackPath.c_str(), pszFilename);
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync if (RT_FAILURE(vrc))
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync RT_BZERO(pszPath, cbPath);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync return vrc;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync}
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsyncSTDMETHODIMP ExtPack::COMGETTER(Name)(BSTR *a_pbstrName)
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync{
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync CheckComArgOutPointerValid(a_pbstrName);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync AutoCaller autoCaller(this);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync HRESULT hrc = autoCaller.rc();
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (SUCCEEDED(hrc))
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync Bstr str(m->Desc.strName);
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync str.cloneTo(a_pbstrName);
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync return hrc;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync}
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsyncSTDMETHODIMP ExtPack::COMGETTER(Description)(BSTR *a_pbstrDescription)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync{
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync CheckComArgOutPointerValid(a_pbstrDescription);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync AutoCaller autoCaller(this);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync HRESULT hrc = autoCaller.rc();
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (SUCCEEDED(hrc))
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync {
aa131431882ca8e44b0480d4af0b5d139f1bde21vboxsync Bstr str(m->Desc.strDescription);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync str.cloneTo(a_pbstrDescription);
aa131431882ca8e44b0480d4af0b5d139f1bde21vboxsync }
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync return hrc;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync}
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsyncSTDMETHODIMP ExtPack::COMGETTER(Version)(BSTR *a_pbstrVersion)
aa131431882ca8e44b0480d4af0b5d139f1bde21vboxsync{
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync CheckComArgOutPointerValid(a_pbstrVersion);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync AutoCaller autoCaller(this);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync HRESULT hrc = autoCaller.rc();
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (SUCCEEDED(hrc))
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync Bstr str(m->Desc.strVersion);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync str.cloneTo(a_pbstrVersion);
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync }
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync return hrc;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync}
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsyncSTDMETHODIMP ExtPack::COMGETTER(Revision)(ULONG *a_puRevision)
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync{
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync CheckComArgOutPointerValid(a_puRevision);
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync AutoCaller autoCaller(this);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync HRESULT hrc = autoCaller.rc();
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync if (SUCCEEDED(hrc))
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync *a_puRevision = m->Desc.uRevision;
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync return hrc;
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync}
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsyncSTDMETHODIMP ExtPack::COMGETTER(PlugIns)(ComSafeArrayOut(IExtPackPlugIn *, a_paPlugIns))
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync{
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync /** @todo implement plug-ins. */
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync#ifdef VBOX_WITH_XPCOM
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync NOREF(a_paPlugIns);
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync NOREF(a_paPlugInsSize);
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync#endif
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync ReturnComNotImplemented();
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync}
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsyncSTDMETHODIMP ExtPack::COMGETTER(Usable)(BOOL *a_pfUsable)
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync{
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync CheckComArgOutPointerValid(a_pfUsable);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync AutoCaller autoCaller(this);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync HRESULT hrc = autoCaller.rc();
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync if (SUCCEEDED(hrc))
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync *a_pfUsable = m->fUsable;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync return hrc;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync}
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsyncSTDMETHODIMP ExtPack::COMGETTER(WhyUnusable)(BSTR *a_pbstrWhy)
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync{
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync CheckComArgOutPointerValid(a_pbstrWhy);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync AutoCaller autoCaller(this);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync HRESULT hrc = autoCaller.rc();
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (SUCCEEDED(hrc))
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync m->strWhyUnusable.cloneTo(a_pbstrWhy);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync return hrc;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync}
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsyncSTDMETHODIMP ExtPack::QueryObject(IN_BSTR a_bstrObjectId, IUnknown **a_ppUnknown)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync{
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync com::Guid ObjectId;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync CheckComArgGuid(a_bstrObjectId, ObjectId);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync CheckComArgOutPointerValid(a_ppUnknown);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync AutoCaller autoCaller(this);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync HRESULT hrc = autoCaller.rc();
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync if (SUCCEEDED(hrc))
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if ( m->pReg
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync && m->pReg->pfnQueryObject)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync void *pvUnknown = m->pReg->pfnQueryObject(m->pReg, ObjectId.raw());
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (pvUnknown)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync *a_ppUnknown = (IUnknown *)pvUnknown;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync else
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync hrc = E_NOINTERFACE;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync else
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync hrc = E_NOINTERFACE;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync }
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync return hrc;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync}
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsyncDEFINE_EMPTY_CTOR_DTOR(ExtPackManager)
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync/**
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync * Called by ComObjPtr::createObject when creating the object.
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync *
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync * Just initialize the basic object state, do the rest in init().
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync *
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * @returns S_OK.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync */
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsyncHRESULT ExtPackManager::FinalConstruct()
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync{
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync m = NULL;
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync return S_OK;
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync}
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync/**
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * Initializes the extension pack manager.
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync *
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * @returns COM status code.
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync * @param a_pszDropZoneDir The path to the drop zone directory.
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync * @param a_fCheckDropZone Whether to check the drop zone for new
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync * extensions or not. Only VBoxSVC does this
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync * and then only when wanted.
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync */
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsyncHRESULT ExtPackManager::init(const char *a_pszDropZoneDir, bool a_fCheckDropZone)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync{
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync AutoInitSpan autoInitSpan(this);
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync AssertReturn(autoInitSpan.isOk(), E_FAIL);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync /*
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync * Figure some stuff out before creating the instance data.
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync */
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync char szBaseDir[RTPATH_MAX];
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync int rc = RTPathAppPrivateArch(szBaseDir, sizeof(szBaseDir));
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync AssertLogRelRCReturn(rc, E_FAIL);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync rc = RTPathAppend(szBaseDir, sizeof(szBaseDir), VBOX_EXTPACK_INSTALL_DIR);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync AssertLogRelRCReturn(rc, E_FAIL);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync char szCertificatDir[RTPATH_MAX];
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync rc = RTPathAppPrivateNoArch(szCertificatDir, sizeof(szCertificatDir));
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync AssertLogRelRCReturn(rc, E_FAIL);
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync rc = RTPathAppend(szCertificatDir, sizeof(szCertificatDir), VBOX_EXTPACK_CERT_DIR);
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync AssertLogRelRCReturn(rc, E_FAIL);
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync /*
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * Allocate and initialize the instance data.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync */
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync m = new Data;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync m->strBaseDir = szBaseDir;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync m->strCertificatDirPath = szCertificatDir;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync m->strDropZoneDir = a_pszDropZoneDir;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync /*
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync * Go looking for extensions. The RTDirOpen may fail if nothing has been
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * installed yet, or if root is paranoid and has revoked our access to them.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync *
129986ce8b48d5e5973ad84edae4465788db89aavboxsync * We ASSUME that there are no files, directories or stuff in the directory
129986ce8b48d5e5973ad84edae4465788db89aavboxsync * that exceed the max name length in RTDIRENTRYEX.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync */
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync HRESULT hrc = S_OK;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync PRTDIR pDir;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync int vrc = RTDirOpen(&pDir, szBaseDir);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync if (RT_SUCCESS(vrc))
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync for (;;)
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync RTDIRENTRYEX Entry;
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync vrc = RTDirReadEx(pDir, &Entry, NULL /*pcbDirEntry*/, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync if (RT_FAILURE(vrc))
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync {
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync AssertLogRelMsg(vrc == VERR_NO_MORE_FILES, ("%Rrc\n", vrc));
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync break;
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync }
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync if ( RTFS_IS_DIRECTORY(Entry.Info.Attr.fMode)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync && strcmp(Entry.szName, ".") != 0
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync && strcmp(Entry.szName, "..") != 0
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync && VBoxExtPackIsValidName(Entry.szName) )
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync /*
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync * All directories are extensions, the shall be nothing but
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * extensions in this subdirectory.
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync */
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync ComObjPtr<ExtPack> NewExtPack;
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync HRESULT hrc2 = NewExtPack.createObject();
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync if (SUCCEEDED(hrc2))
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync hrc2 = NewExtPack->init(Entry.szName, szBaseDir);
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync if (SUCCEEDED(hrc2))
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync m->llInstalledExtPacks.push_back(NewExtPack);
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync else if (SUCCEEDED(rc))
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync hrc = hrc2;
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync }
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync }
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync RTDirClose(pDir);
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync }
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync /* else: ignore, the directory probably does not exist or something. */
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync /*
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync * Look for things in the drop zone.
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync */
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync if (SUCCEEDED(hrc) && a_fCheckDropZone)
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync processDropZone();
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync if (SUCCEEDED(hrc))
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync autoInitSpan.setSucceeded();
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync return hrc;
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync}
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync/**
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync * COM cruft.
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync */
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsyncvoid ExtPackManager::FinalRelease()
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync{
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync uninit();
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync}
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync/**
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync * Do the actual cleanup.
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync */
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsyncvoid ExtPackManager::uninit()
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync{
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync /* Enclose the state transition Ready->InUninit->NotReady */
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync AutoUninitSpan autoUninitSpan(this);
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync if (!autoUninitSpan.uninitDone() && m != NULL)
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync {
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync delete m;
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync m = NULL;
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync }
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync}
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsyncSTDMETHODIMP ExtPackManager::COMGETTER(InstalledExtPacks)(ComSafeArrayOut(IExtPack *, a_paExtPacks))
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync{
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync CheckComArgSafeArrayNotNull(a_paExtPacks);
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync AutoCaller autoCaller(this);
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync HRESULT hrc = autoCaller.rc();
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync if (SUCCEEDED(hrc))
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync {
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync AutoReadLock autoLock(this COMMA_LOCKVAL_SRC_POS);
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync SafeIfaceArray<IExtPack> SaExtPacks(m->llInstalledExtPacks);
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync SaExtPacks.detachTo(ComSafeArrayOutArg(a_paExtPacks));
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync }
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync return hrc;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync}
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsyncSTDMETHODIMP ExtPackManager::Find(IN_BSTR a_bstrName, IExtPack **a_pExtPack)
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync{
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync CheckComArgNotNull(a_bstrName);
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync CheckComArgOutPointerValid(a_pExtPack);
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync Utf8Str strName(a_bstrName);
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync AutoCaller autoCaller(this);
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync HRESULT hrc = autoCaller.rc();
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync if (SUCCEEDED(hrc))
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync {
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync AutoReadLock autoLock(this COMMA_LOCKVAL_SRC_POS);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync ComPtr<ExtPack> ptrExtPack = findExtPack(strName.c_str());
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync if (!ptrExtPack.isNull())
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync ptrExtPack.queryInterfaceTo(a_pExtPack);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync else
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync hrc = VBOX_E_OBJECT_NOT_FOUND;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync return hrc;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync}
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsyncSTDMETHODIMP ExtPackManager::Install(IN_BSTR a_bstrTarball, BSTR *a_pbstrName)
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync{
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync CheckComArgNotNull(a_bstrTarball);
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync CheckComArgOutPointerValid(a_pbstrName);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync Utf8Str strTarball(a_bstrTarball);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync AutoCaller autoCaller(this);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync HRESULT hrc = autoCaller.rc();
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync if (SUCCEEDED(hrc))
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync {
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync AutoWriteLock autoLock(this COMMA_LOCKVAL_SRC_POS);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync /*
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync * Check that the file exists and that we can access it.
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync */
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync if (RTFileExists(strTarball.c_str()))
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync {
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync RTFILE hFile;
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync int vrc = RTFileOpen(&hFile, strTarball.c_str(), RTFILE_O_READ | RTFILE_O_DENY_WRITE | RTFILE_O_OPEN);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync if (RT_SUCCESS(vrc))
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync {
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync RTFSOBJINFO ObjInfo;
fabb3e1e51b589494ebe849b7c000e8bcc9ff473vboxsync vrc = RTFileQueryInfo(hFile, &ObjInfo, RTFSOBJATTRADD_NOTHING);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync if ( RT_SUCCESS(vrc)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync && RTFS_IS_FILE(ObjInfo.Attr.fMode))
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync {
fabb3e1e51b589494ebe849b7c000e8bcc9ff473vboxsync /*
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync * Derive the name of the extension pack from the file
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync * name. Certain restrictions are here placed on the
fabb3e1e51b589494ebe849b7c000e8bcc9ff473vboxsync * tarball name.
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync */
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync iprt::MiniString *pStrName = VBoxExtPackExtractNameFromTarballPath(strTarball.c_str());
fabb3e1e51b589494ebe849b7c000e8bcc9ff473vboxsync if (pStrName)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync {
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync /*
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync * Refresh the data we have on the extension pack as it
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync * may be made stale by direct meddling or some other user.
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync */
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync ExtPack *pExtPack;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync hrc = refreshExtPack(pStrName->c_str(), false /*a_fUnsuableIsError*/, &pExtPack);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (SUCCEEDED(hrc) && !pExtPack)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync /*
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync * Run the set-uid-to-root binary that performs the actual
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync * installation. Then create an object for the packet (we
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync * do this even on failure, to be on the safe side).
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync */
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync char szTarballFd[64];
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync RTStrPrintf(szTarballFd, sizeof(szTarballFd), "0x%RX64",
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync (uint64_t)RTFileToNative(hFile));
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync hrc = runSetUidToRootHelper("install",
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync "--base-dir", m->strBaseDir.c_str(),
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync "--certificate-dir", m->strCertificatDirPath.c_str(),
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync "--name", pStrName->c_str(),
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync "--tarball", strTarball.c_str(),
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync "--tarball-fd", &szTarballFd[0],
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync NULL);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync if (SUCCEEDED(hrc))
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync {
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync hrc = refreshExtPack(pStrName->c_str(), true /*a_fUnsuableIsError*/, &pExtPack);
fabb3e1e51b589494ebe849b7c000e8bcc9ff473vboxsync if (SUCCEEDED(hrc))
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync {
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync LogRel(("ExtPackManager: Successfully installed extension pack '%s'.\n", pStrName->c_str()));
fabb3e1e51b589494ebe849b7c000e8bcc9ff473vboxsync pExtPack->callInstalledHook();
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync }
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync }
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync else
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync {
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync ErrorInfoKeeper Eik;
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync refreshExtPack(pStrName->c_str(), false /*a_fUnsuableIsError*/, NULL);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync }
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync }
0721bcb57f5e05054e2b5092075617983ec2914evboxsync else if (SUCCEEDED(hrc))
0721bcb57f5e05054e2b5092075617983ec2914evboxsync hrc = setError(E_FAIL,
0721bcb57f5e05054e2b5092075617983ec2914evboxsync tr("Extension pack '%s' is already installed."
0721bcb57f5e05054e2b5092075617983ec2914evboxsync " In case of a reinstallation, please uninstall it first"),
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync pStrName->c_str());
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync delete pStrName;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync }
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync else
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync hrc = setError(E_FAIL, tr("Malformed '%s' file name"), strTarball.c_str());
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync }
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync else if (RT_SUCCESS(vrc))
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync hrc = setError(E_FAIL, tr("'%s' is not a regular file"), strTarball.c_str());
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync else
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync hrc = setError(E_FAIL, tr("Failed to query info on '%s' (%Rrc)"), strTarball.c_str(), vrc);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync RTFileClose(hFile);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync }
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync else
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync hrc = setError(E_FAIL, tr("Failed to open '%s' (%Rrc)"), strTarball.c_str(), vrc);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync else if (RTPathExists(strTarball.c_str()))
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync hrc = setError(E_FAIL, tr("'%s' is not a regular file"), strTarball.c_str());
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync else
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync hrc = setError(E_FAIL, tr("File '%s' was inaccessible or not found"), strTarball.c_str());
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync }
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync return hrc;
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync}
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsyncSTDMETHODIMP ExtPackManager::Uninstall(IN_BSTR a_bstrName, BOOL a_fForcedRemoval)
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync{
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync CheckComArgNotNull(a_bstrName);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync Utf8Str strName(a_bstrName);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync AutoCaller autoCaller(this);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync HRESULT hrc = autoCaller.rc();
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync if (SUCCEEDED(hrc))
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync AutoWriteLock autoLock(this COMMA_LOCKVAL_SRC_POS);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync /*
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync * Refresh the data we have on the extension pack as it may be made
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync * stale by direct meddling or some other user.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync */
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync ExtPack *pExtPack;
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync hrc = refreshExtPack(strName.c_str(), false /*a_fUnsuableIsError*/, &pExtPack);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (SUCCEEDED(hrc))
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync {
aa131431882ca8e44b0480d4af0b5d139f1bde21vboxsync if (!pExtPack)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync {
aa131431882ca8e44b0480d4af0b5d139f1bde21vboxsync LogRel(("ExtPackManager: Extension pack '%s' is not installed, so nothing to uninstall.\n", strName.c_str()));
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync hrc = S_OK; /* nothing to uninstall */
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync }
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync else
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync {
c9819fb7aaf7275898c2a4ad2f891245a4a13e67vboxsync /*
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync * Call the uninstall hook and unload the main dll.
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync */
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync hrc = pExtPack->callUninstallHookAndClose(a_fForcedRemoval != FALSE);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync if (SUCCEEDED(hrc))
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync /*
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync * Run the set-uid-to-root binary that performs the
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync * uninstallation. Then refresh the object.
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync *
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync * This refresh is theorically subject to races, but it's of
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * the don't-do-that variety.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync */
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync const char *pszForcedOpt = a_fForcedRemoval ? "--forced" : NULL;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync hrc = runSetUidToRootHelper("uninstall",
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync "--base-dir", m->strBaseDir.c_str(),
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync "--name", strName.c_str(),
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync pszForcedOpt, /* Last as it may be NULL. */
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync NULL);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync if (SUCCEEDED(hrc))
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync {
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync hrc = refreshExtPack(strName.c_str(), false /*a_fUnsuableIsError*/, &pExtPack);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync if (SUCCEEDED(hrc))
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync {
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync if (!pExtPack)
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync LogRel(("ExtPackManager: Successfully uninstalled extension pack '%s'.\n", strName.c_str()));
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync else
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync hrc = setError(E_UNEXPECTED,
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync tr("Uninstall extension pack '%s' failed under mysterious circumstances"),
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync strName.c_str());
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync }
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync }
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync else
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync {
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync ErrorInfoKeeper Eik;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync refreshExtPack(strName.c_str(), false /*a_fUnsuableIsError*/, NULL);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync }
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync }
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync }
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync }
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync }
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync return hrc;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync}
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsyncSTDMETHODIMP ExtPackManager::Cleanup(void)
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync{
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync AutoCaller autoCaller(this);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync HRESULT hrc = autoCaller.rc();
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync if (SUCCEEDED(hrc))
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync {
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync /*
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync * Run the set-uid-to-root binary that performs the cleanup.
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync *
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync * Take the write lock to prevent conflicts with other calls to this
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync * VBoxSVC instance.
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync */
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync AutoWriteLock autoLock(this COMMA_LOCKVAL_SRC_POS);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync hrc = runSetUidToRootHelper("cleanup",
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync "--base-dir", m->strBaseDir.c_str(),
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync NULL);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync }
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync return hrc;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync}
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsyncSTDMETHODIMP ExtPackManager::QueryAllPlugInsForFrontend(IN_BSTR a_bstrFrontend, ComSafeArrayOut(BSTR, a_pabstrPlugInModules))
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync{
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync CheckComArgNotNull(a_bstrFrontend);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync Utf8Str strName(a_bstrFrontend);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync CheckComArgOutSafeArrayPointerValid(a_pabstrPlugInModules);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync AutoCaller autoCaller(this);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync HRESULT hrc = autoCaller.rc();
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync if (SUCCEEDED(hrc))
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync {
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync com::SafeArray<BSTR> saPaths(0);
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync /** @todo implement plug-ins */
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync saPaths.detachTo(ComSafeArrayOutArg(a_pabstrPlugInModules));
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync }
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync return hrc;
0721bcb57f5e05054e2b5092075617983ec2914evboxsync}
0721bcb57f5e05054e2b5092075617983ec2914evboxsync
0721bcb57f5e05054e2b5092075617983ec2914evboxsync
0721bcb57f5e05054e2b5092075617983ec2914evboxsync/**
0721bcb57f5e05054e2b5092075617983ec2914evboxsync * Runs the helper application that does the privileged operations.
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync *
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync * @returns S_OK or a failure status with error information set.
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync * @param a_pszCommand The command to execute.
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync * @param ... The argument strings that goes along with the
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync * command. Maximum is about 16. Terminated by a
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync * NULL.
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync */
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsyncHRESULT ExtPackManager::runSetUidToRootHelper(const char *a_pszCommand, ...)
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync{
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync /*
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync * Calculate the path to the helper application.
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync */
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync char szExecName[RTPATH_MAX];
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync int vrc = RTPathAppPrivateArch(szExecName, sizeof(szExecName));
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync AssertLogRelRCReturn(vrc, E_UNEXPECTED);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync vrc = RTPathAppend(szExecName, sizeof(szExecName), VBOX_EXTPACK_HELPER_NAME);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync AssertLogRelRCReturn(vrc, E_UNEXPECTED);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync /*
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync * Convert the variable argument list to a RTProcCreate argument vector.
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync */
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync const char *apszArgs[20];
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync unsigned cArgs = 0;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync apszArgs[cArgs++] = &szExecName[0];
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync apszArgs[cArgs++] = a_pszCommand;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync va_list va;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync va_start(va, a_pszCommand);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync const char *pszLastArg;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync LogRel(("ExtPack: Executing '%s'", szExecName));
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync do
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync LogRel((" '%s'", apszArgs[cArgs - 1]));
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync AssertReturn(cArgs < RT_ELEMENTS(apszArgs) - 1, E_UNEXPECTED);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync pszLastArg = va_arg(va, const char *);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync apszArgs[cArgs++] = pszLastArg;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync } while (pszLastArg != NULL);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync LogRel(("\n"));
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync va_end(va);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync apszArgs[cArgs] = NULL;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync /*
77db08a24f69bca943d5abc40b1930ee97f593edvboxsync * Create a PIPE which we attach to stderr so that we can read the error
77db08a24f69bca943d5abc40b1930ee97f593edvboxsync * message on failure and report it back to the caller.
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync */
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync RTPIPE hPipeR;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync RTHANDLE hStdErrPipe;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync hStdErrPipe.enmType = RTHANDLETYPE_PIPE;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync vrc = RTPipeCreate(&hPipeR, &hStdErrPipe.u.hPipe, RTPIPE_C_INHERIT_WRITE);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync AssertLogRelRCReturn(vrc, E_UNEXPECTED);
d862f0eeb9eacdb46b9f5cc420de30a3d7c2c3f6vboxsync
d862f0eeb9eacdb46b9f5cc420de30a3d7c2c3f6vboxsync /*
d862f0eeb9eacdb46b9f5cc420de30a3d7c2c3f6vboxsync * Spawn the process.
d862f0eeb9eacdb46b9f5cc420de30a3d7c2c3f6vboxsync */
d862f0eeb9eacdb46b9f5cc420de30a3d7c2c3f6vboxsync HRESULT hrc;
d862f0eeb9eacdb46b9f5cc420de30a3d7c2c3f6vboxsync RTPROCESS hProcess;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync vrc = RTProcCreateEx(szExecName,
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync apszArgs,
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync RTENV_DEFAULT,
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync 0 /*fFlags*/,
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync NULL /*phStdIn*/,
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync NULL /*phStdOut*/,
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync &hStdErrPipe,
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync NULL /*pszAsUser*/,
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync NULL /*pszPassword*/,
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync &hProcess);
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync if (RT_SUCCESS(vrc))
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync {
9161d9a8318db73b2848c1feaef3880980474e64vboxsync vrc = RTPipeClose(hStdErrPipe.u.hPipe);
9161d9a8318db73b2848c1feaef3880980474e64vboxsync hStdErrPipe.u.hPipe = NIL_RTPIPE;
9161d9a8318db73b2848c1feaef3880980474e64vboxsync
9161d9a8318db73b2848c1feaef3880980474e64vboxsync /*
9161d9a8318db73b2848c1feaef3880980474e64vboxsync * Read the pipe output until the process completes.
9161d9a8318db73b2848c1feaef3880980474e64vboxsync */
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync RTPROCSTATUS ProcStatus = { -42, RTPROCEXITREASON_ABEND };
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync size_t cbStdErrBuf = 0;
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync size_t offStdErrBuf = 0;
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync char *pszStdErrBuf = NULL;
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync do
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync {
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync /*
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync * Service the pipe. Block waiting for output or the pipe breaking
9161d9a8318db73b2848c1feaef3880980474e64vboxsync * when the process terminates.
9161d9a8318db73b2848c1feaef3880980474e64vboxsync */
9161d9a8318db73b2848c1feaef3880980474e64vboxsync if (hPipeR != NIL_RTPIPE)
9161d9a8318db73b2848c1feaef3880980474e64vboxsync {
9161d9a8318db73b2848c1feaef3880980474e64vboxsync char achBuf[16]; ///@todo 1024
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync size_t cbRead;
9161d9a8318db73b2848c1feaef3880980474e64vboxsync vrc = RTPipeReadBlocking(hPipeR, achBuf, sizeof(achBuf), &cbRead);
9161d9a8318db73b2848c1feaef3880980474e64vboxsync if (RT_SUCCESS(vrc))
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync {
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync /* grow the buffer? */
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync size_t cbBufReq = offStdErrBuf + cbRead + 1;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync if ( cbBufReq > cbStdErrBuf
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync && cbBufReq < _256K)
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync {
9161d9a8318db73b2848c1feaef3880980474e64vboxsync size_t cbNew = RT_ALIGN_Z(cbBufReq, 16); // 1024
9161d9a8318db73b2848c1feaef3880980474e64vboxsync void *pvNew = RTMemRealloc(pszStdErrBuf, cbNew);
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync if (pvNew)
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync pszStdErrBuf = (char *)pvNew;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync cbStdErrBuf = cbNew;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync /* append if we've got room. */
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (cbBufReq <= cbStdErrBuf)
ad1aea7f006b1feaea275f858b5b574ae61bfe39vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync memcpy(&pszStdErrBuf[offStdErrBuf], achBuf, cbRead);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync offStdErrBuf = offStdErrBuf + cbRead;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync pszStdErrBuf[offStdErrBuf] = '\0';
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync else
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync AssertLogRelMsg(vrc == VERR_BROKEN_PIPE, ("%Rrc\n", vrc));
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync RTPipeClose(hPipeR);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync hPipeR = NIL_RTPIPE;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync /*
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * Service the process. Block if we have no pipe.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync */
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (hProcess != NIL_RTPROCESS)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync vrc = RTProcWait(hProcess,
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync hPipeR == NIL_RTPIPE ? RTPROCWAIT_FLAGS_BLOCK : RTPROCWAIT_FLAGS_NOBLOCK,
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync &ProcStatus);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (RT_SUCCESS(vrc))
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync hProcess = NIL_RTPROCESS;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync else
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync AssertLogRelMsgStmt(vrc != VERR_PROCESS_RUNNING, ("%Rrc\n", vrc), hProcess = NIL_RTPROCESS);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync } while ( hPipeR != NIL_RTPIPE
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync || hProcess != NIL_RTPROCESS);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync /*
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * Compose the status code and, on failure, error message.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync */
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync LogRel(("ExtPack: enmReason=%d iStatus=%d stderr='%s'\n",
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync ProcStatus.enmReason, ProcStatus.iStatus, offStdErrBuf ? pszStdErrBuf : ""));
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if ( ProcStatus.enmReason == RTPROCEXITREASON_NORMAL
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync && ProcStatus.iStatus == 0
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync && offStdErrBuf == 0)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync hrc = S_OK;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync else if (ProcStatus.enmReason == RTPROCEXITREASON_NORMAL)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync AssertMsg(ProcStatus.iStatus != 0, ("%s\n", pszStdErrBuf));
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync hrc = setError(E_UNEXPECTED, tr("The installer failed with exit code %d: %s"),
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync ProcStatus.iStatus, offStdErrBuf ? pszStdErrBuf : "");
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync else if (ProcStatus.enmReason == RTPROCEXITREASON_SIGNAL)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync hrc = setError(E_UNEXPECTED, tr("The installer was killed by signal #d (stderr: %s)"),
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync ProcStatus.iStatus, offStdErrBuf ? pszStdErrBuf : "");
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync else if (ProcStatus.enmReason == RTPROCEXITREASON_ABEND)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync hrc = setError(E_UNEXPECTED, tr("The installer aborted abnormally (stderr: %s)"),
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync offStdErrBuf ? pszStdErrBuf : "");
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync else
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync hrc = setError(E_UNEXPECTED, tr("internal error: enmReason=%d iStatus=%d stderr='%s'"),
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync ProcStatus.enmReason, ProcStatus.iStatus, offStdErrBuf ? pszStdErrBuf : "");
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync RTMemFree(pszStdErrBuf);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync }
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync else
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync hrc = setError(VBOX_E_IPRT_ERROR, tr("Failed to launch the helper application '%s' (%Rrc)"), szExecName, vrc);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync RTPipeClose(hPipeR);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync RTPipeClose(hStdErrPipe.u.hPipe);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync return hrc;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync}
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync/**
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync * Finds an installed extension pack.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync *
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * @returns Pointer to the extension pack if found, NULL if not. (No reference
aaa6e7826ca134b41d12c1f570bd7874ae1d8135vboxsync * counting problem here since the caller must be holding the lock.)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * @param a_pszName The name of the extension pack.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync */
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsyncExtPack *ExtPackManager::findExtPack(const char *a_pszName)
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync{
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync size_t cchName = strlen(a_pszName);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync for (ExtPackList::iterator it = m->llInstalledExtPacks.begin();
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync it != m->llInstalledExtPacks.end();
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync it++)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync ExtPack::Data *pExtPackData = (*it)->m;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if ( pExtPackData
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync && pExtPackData->Desc.strName.length() == cchName
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync && pExtPackData->Desc.strName.compare(a_pszName, iprt::MiniString::CaseInsensitive) == 0)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync return (*it);
c4bfe32373c55416bf49dc29ebf45dfa560b4692vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync return NULL;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync}
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
730f8be51b729e8a3c1e32c756cd0f4ec088dd4dvboxsync/**
730f8be51b729e8a3c1e32c756cd0f4ec088dd4dvboxsync * Removes an installed extension pack from the internal list.
730f8be51b729e8a3c1e32c756cd0f4ec088dd4dvboxsync *
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * The package is expected to exist!
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync *
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * @param a_pszName The name of the extension pack.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync */
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsyncvoid ExtPackManager::removeExtPack(const char *a_pszName)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync{
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync size_t cchName = strlen(a_pszName);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync for (ExtPackList::iterator it = m->llInstalledExtPacks.begin();
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync it != m->llInstalledExtPacks.end();
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync it++)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync ExtPack::Data *pExtPackData = (*it)->m;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if ( pExtPackData
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync && pExtPackData->Desc.strName.length() == cchName
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync && pExtPackData->Desc.strName.compare(a_pszName, iprt::MiniString::CaseInsensitive) == 0)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync m->llInstalledExtPacks.erase(it);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync return;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync AssertMsgFailed(("%s\n", a_pszName));
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync}
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync/**
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * Refreshes the specified extension pack.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync *
c4bfe32373c55416bf49dc29ebf45dfa560b4692vboxsync * This may remove the extension pack from the list, so any non-smart pointers
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync * to the extension pack object may become invalid.
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync *
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync * @returns S_OK and *ppExtPack on success, COM status code and error message
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync * on failure.
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync * @param a_pszName The extension to update..
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync * @param a_fUnsuableIsError If @c true, report an unusable extension pack
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync * as an error.
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync * @param a_ppExtPack Where to store the pointer to the extension
3faac25bf74aedb359249d6acd6d8e4988acd332vboxsync * pack of it is still around after the refresh.
3faac25bf74aedb359249d6acd6d8e4988acd332vboxsync * This is optional.
3faac25bf74aedb359249d6acd6d8e4988acd332vboxsync * @remarks Caller holds the extension manager lock.
3faac25bf74aedb359249d6acd6d8e4988acd332vboxsync */
3faac25bf74aedb359249d6acd6d8e4988acd332vboxsyncHRESULT ExtPackManager::refreshExtPack(const char *a_pszName, bool a_fUnsuableIsError, ExtPack **a_ppExtPack)
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync{
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync HRESULT hrc;
3faac25bf74aedb359249d6acd6d8e4988acd332vboxsync ExtPack *pExtPack = findExtPack(a_pszName);
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync if (pExtPack)
3faac25bf74aedb359249d6acd6d8e4988acd332vboxsync {
3faac25bf74aedb359249d6acd6d8e4988acd332vboxsync /*
3faac25bf74aedb359249d6acd6d8e4988acd332vboxsync * Refresh existing object.
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync */
3faac25bf74aedb359249d6acd6d8e4988acd332vboxsync bool fCanDelete;
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync hrc = pExtPack->refresh(&fCanDelete);
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync if (SUCCEEDED(hrc))
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync {
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync if (fCanDelete)
2dd7b4388106de88d20f33a8aa6c85c8babf507bvboxsync {
c4bfe32373c55416bf49dc29ebf45dfa560b4692vboxsync removeExtPack(a_pszName);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync pExtPack = NULL;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync }
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync else
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync /*
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * Does the dir exist? Make some special effort to deal with case
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync * sensitivie file systems (a_pszName is case insensitive).
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync */
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync char szDir[RTPATH_MAX];
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync int vrc = RTPathJoin(szDir, sizeof(szDir), m->strBaseDir.c_str(), a_pszName);
3c9ed6defa3feca7e21adef4b5d1ba3002fc94c9vboxsync AssertLogRelRCReturn(vrc, E_FAIL);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync RTDIRENTRYEX Entry;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync RTFSOBJINFO ObjInfo;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync vrc = RTPathQueryInfoEx(szDir, &ObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync bool fExists = RT_SUCCESS(vrc) && RTFS_IS_DIRECTORY(ObjInfo.Attr.fMode);
3c9ed6defa3feca7e21adef4b5d1ba3002fc94c9vboxsync if (!fExists)
3c9ed6defa3feca7e21adef4b5d1ba3002fc94c9vboxsync {
3c9ed6defa3feca7e21adef4b5d1ba3002fc94c9vboxsync PRTDIR pDir;
3c9ed6defa3feca7e21adef4b5d1ba3002fc94c9vboxsync vrc = RTDirOpen(&pDir, m->strBaseDir.c_str());
8842b172df03540da1eba3c422804d54f29c9fb6vboxsync if (RT_SUCCESS(vrc))
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync {
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync for (;;)
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync {
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync vrc = RTDirReadEx(pDir, &Entry, NULL /*pcbDirEntry*/, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK);
3c9ed6defa3feca7e21adef4b5d1ba3002fc94c9vboxsync if (RT_FAILURE(vrc))
3c9ed6defa3feca7e21adef4b5d1ba3002fc94c9vboxsync {
3c9ed6defa3feca7e21adef4b5d1ba3002fc94c9vboxsync AssertLogRelMsg(vrc == VERR_NO_MORE_FILES, ("%Rrc\n", vrc));
3c9ed6defa3feca7e21adef4b5d1ba3002fc94c9vboxsync break;
3c9ed6defa3feca7e21adef4b5d1ba3002fc94c9vboxsync }
3c9ed6defa3feca7e21adef4b5d1ba3002fc94c9vboxsync if ( RTFS_IS_DIRECTORY(Entry.Info.Attr.fMode)
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync && !RTStrICmp(Entry.szName, a_pszName))
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync {
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync /*
416817daa142e9bb7eaf14a1b10577978a5e691bvboxsync * The installed extension pack has a uses different case.
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync * Update the name and directory variables.
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync */
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync vrc = RTPathJoin(szDir, sizeof(szDir), m->strBaseDir.c_str(), Entry.szName); /* not really necessary */
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync AssertLogRelRCReturnStmt(vrc, E_UNEXPECTED, RTDirClose(pDir));
8842b172df03540da1eba3c422804d54f29c9fb6vboxsync a_pszName = Entry.szName;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync fExists = true;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync break;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync RTDirClose(pDir);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
c4bfe32373c55416bf49dc29ebf45dfa560b4692vboxsync if (fExists)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync /*
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * We've got something, create a new extension pack object for it.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync */
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync ComObjPtr<ExtPack> NewExtPack;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync hrc = NewExtPack.createObject();
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (SUCCEEDED(hrc))
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync hrc = NewExtPack->init(a_pszName, m->strBaseDir.c_str());
c4bfe32373c55416bf49dc29ebf45dfa560b4692vboxsync if (SUCCEEDED(hrc))
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync m->llInstalledExtPacks.push_back(NewExtPack);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (NewExtPack->m->fUsable)
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync LogRel(("ExtPackManager: Found extension pack '%s'.\n", a_pszName));
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync else
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync LogRel(("ExtPackManager: Found bad extension pack '%s': %s\n",
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync a_pszName, NewExtPack->m->strWhyUnusable.c_str() ));
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync pExtPack = NewExtPack;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
c4bfe32373c55416bf49dc29ebf45dfa560b4692vboxsync else
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync hrc = S_OK;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync }
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync /*
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * Report error if not usable, if that is desired.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync */
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if ( SUCCEEDED(hrc)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync && pExtPack
c4bfe32373c55416bf49dc29ebf45dfa560b4692vboxsync && a_fUnsuableIsError
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync && !pExtPack->m->fUsable)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync hrc = setError(E_FAIL, "%s", pExtPack->m->strWhyUnusable.c_str());
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (a_ppExtPack)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync *a_ppExtPack = pExtPack;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync return hrc;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync}
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
c4bfe32373c55416bf49dc29ebf45dfa560b4692vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync/**
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * Processes anything new in the drop zone.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync */
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsyncvoid ExtPackManager::processDropZone(void)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync{
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync AutoCaller autoCaller(this);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync HRESULT hrc = autoCaller.rc();
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (FAILED(hrc))
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync return;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync AutoWriteLock autoLock(this COMMA_LOCKVAL_SRC_POS);
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync if (m->strDropZoneDir.isEmpty())
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync return;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync PRTDIR pDir;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync int vrc = RTDirOpen(&pDir, m->strDropZoneDir.c_str());
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync if (RT_FAILURE(vrc))
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync return;
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync for (;;)
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync {
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync RTDIRENTRYEX Entry;
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync vrc = RTDirReadEx(pDir, &Entry, NULL /*pcbDirEntry*/, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync if (RT_FAILURE(vrc))
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync {
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync AssertMsg(vrc == VERR_NO_MORE_FILES, ("%Rrc\n", vrc));
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync break;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync }
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync /*
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync * We're looking for files with the right extension. Symbolic links
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync * will be ignored.
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync */
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync if ( RTFS_IS_FILE(Entry.Info.Attr.fMode)
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync && RTStrICmp(RTPathExt(Entry.szName), VBOX_EXTPACK_SUFFIX) == 0)
7cfcbe810de5334cdc2e8b92e77db705da143adavboxsync {
8be5264d31d6a6ec949ff2285764c9af57298b52vboxsync /* We create (and check for) a blocker file to prevent this
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync extension pack from being installed more than once. */
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync char szPath[RTPATH_MAX];
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync vrc = RTPathJoin(szPath, sizeof(szPath), m->strDropZoneDir.c_str(), Entry.szName);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync if (RT_SUCCESS(vrc))
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync vrc = RTPathAppend(szPath, sizeof(szPath), "-done");
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync AssertRC(vrc);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync if (RT_SUCCESS(vrc))
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync {
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync RTFILE hFile;
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync vrc = RTFileOpen(&hFile, szPath, RTFILE_O_WRITE | RTFILE_O_DENY_WRITE | RTFILE_O_CREATE);
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync if (RT_SUCCESS(vrc))
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync {
/* Construct the full path to the extension pack and invoke
the Install method to install it. Write errors to the
done file. */
vrc = RTPathJoin(szPath, sizeof(szPath), m->strDropZoneDir.c_str(), Entry.szName); AssertRC(vrc);
Bstr strName;
hrc = Install(Bstr(szPath).raw(), strName.asOutParam());
if (SUCCEEDED(hrc))
RTFileWrite(hFile, "succeeded\n", sizeof("succeeded\n"), NULL);
else
{
Utf8Str strErr;
com::ErrorInfo Info;
if (Info.isFullAvailable())
strErr.printf("failed\n"
"%ls\n"
"Details: code %Rhrc (%#RX32), component %ls, interface %ls, callee %ls\n"
,
Info.getText().raw(),
Info.getResultCode(),
Info.getResultCode(),
Info.getComponent().raw(),
Info.getInterfaceName().raw(),
Info.getCalleeName().raw());
else
strErr.printf("failed\n"
"hrc=%Rhrc (%#RX32)\n", hrc, hrc);
RTFileWrite(hFile, strErr.c_str(), strErr.length(), NULL);
}
RTFileClose(hFile);
}
}
}
} /* foreach dir entry */
RTDirClose(pDir);
}
/**
* 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;
AutoReadLock autoLock(this COMMA_LOCKVAL_SRC_POS);
for (ExtPackList::iterator it = m->llInstalledExtPacks.begin();
it != m->llInstalledExtPacks.end();
it++)
(*it)->callVmCreatedHook(a_pMachine);
}
/**
* 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);
AutoReadLock autoLock(this COMMA_LOCKVAL_SRC_POS);
for (ExtPackList::iterator it = m->llInstalledExtPacks.begin();
it != m->llInstalledExtPacks.end();
it++)
{
int vrc = (*it)->callVmConfigureVmmHook(a_pConsole, a_pVM);
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);
AutoReadLock autoLock(this COMMA_LOCKVAL_SRC_POS);
for (ExtPackList::iterator it = m->llInstalledExtPacks.begin();
it != m->llInstalledExtPacks.end();
it++)
{
int vrc = (*it)->callVmPowerOnHook(a_pConsole, a_pVM);
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;
AutoReadLock autoLock(this COMMA_LOCKVAL_SRC_POS);
for (ExtPackList::iterator it = m->llInstalledExtPacks.begin();
it != m->llInstalledExtPacks.end();
it++)
(*it)->callVmPowerOnHook(a_pConsole, a_pVM);
}
/* vi: set tabstop=4 shiftwidth=4 expandtab: */