VirtualBox

Changeset 33693 in vbox for trunk/src


Ignore:
Timestamp:
Nov 2, 2010 2:52:24 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
67319
Message:

Main: More ExtPack code.

Location:
trunk/src/VBox/Main
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/ExtPackManagerImpl.cpp

    r33671 r33693  
    4141#include <VBox/version.h>
    4242#include "AutoCaller.h"
     43#include "Global.h"
    4344
    4445
     
    6667struct ExtPack::Data
    6768{
     69public:
    6870    /** The extension pack description (loaded from the XML, mostly). */
    6971    VBOXEXTPACKDESC     Desc;
     
    9193    /** The helper callbacks for the extension pack. */
    9294    VBOXEXTPACKHLP      Hlp;
     95    /** Pointer back to the extension pack object (for Hlp methods). */
     96    ExtPack            *pThis;
    9397    /** The extension pack registration structure. */
    9498    PCVBOXEXTPACKREG    pReg;
     
    103107struct ExtPackManager::Data
    104108{
    105     /** Where the directory where the extension packs are installed. */
    106     Utf8Str     strBasePath;
     109    /** The directory where the extension packs are installed. */
     110    Utf8Str     strBaseDir;
     111    /** The directory where the extension packs can be dropped for automatic
     112     * installation. */
     113    Utf8Str     strDropZoneDir;
     114    /** The directory where the certificates this installation recognizes are
     115     * stored. */
     116    Utf8Str     strCertificatDirPath;
    107117    /** The list of installed extension packs. */
    108118    ExtPackList llInstalledExtPacks;
     
    167177    m->Hlp.pszVBoxVersion           = RTBldCfgVersion();
    168178    m->Hlp.uVBoxInternalRevision    = RTBldCfgRevision();
     179    m->pThis                        = this;
    169180    m->pReg                         = NULL;
    170181
     
    196207        if (m->hMainMod != NIL_RTLDRMOD)
    197208        {
     209            AssertPtr(m->pReg);
     210            if (m->pReg->pfnUnload != NULL)
     211                m->pReg->pfnUnload(m->pReg);
     212
    198213            RTLdrClose(m->hMainMod);
    199214            m->hMainMod = NIL_RTLDRMOD;
     215            m->pReg = NULL;
    200216        }
    201217
     
    205221}
    206222
    207 void *ExtPack::getCallbackTable()
    208 {
    209     return NULL;
     223
     224/**
     225 * Calls the installed hook.
     226 * @remarks Caller holds the extension manager lock.
     227 */
     228void    ExtPack::callInstalledHook(void)
     229{
     230    if (   m->hMainMod != NIL_RTLDRMOD
     231        && m->pReg->pfnInstalled)
     232        m->pReg->pfnInstalled(m->pReg);
     233}
     234
     235/**
     236 * Calls the uninstall hook and closes the module.
     237 *
     238 * @returns S_OK or COM error status with error information.
     239 * @param   a_fForcedRemoval    When set, we'll ignore complaints from the
     240 *                              uninstall hook.
     241 * @remarks The caller holds the manager's write lock.
     242 */
     243HRESULT ExtPack::callUninstallHookAndClose(bool a_fForcedRemoval)
     244{
     245    HRESULT hrc = S_OK;
     246
     247    if (m->hMainMod != NIL_RTLDRMOD)
     248    {
     249        if (m->pReg->pfnUninstall)
     250        {
     251            int vrc = m->pReg->pfnUninstall(m->pReg);
     252            if (RT_FAILURE(vrc))
     253            {
     254                LogRel(("ExtPack pfnUninstall returned %Rrc for %s\n", vrc, m->Desc.strName.c_str()));
     255                if (!a_fForcedRemoval)
     256                    hrc = setError(E_FAIL, tr("pfnUninstall returned %Rrc"), vrc);
     257            }
     258        }
     259        if (SUCCEEDED(hrc))
     260        {
     261            RTLdrClose(m->hMainMod);
     262            m->hMainMod = NIL_RTLDRMOD;
     263            m->pReg = NULL;
     264        }
     265    }
     266
     267    return hrc;
     268}
     269
     270/**
     271 * Calls the pfnVMCreate hook.
     272 *
     273 * @param   a_pMachine          The machine interface of the new VM.
     274 * @remarks Caller holds the extension manager lock.
     275 */
     276void ExtPack::callVmCreatedHook(IMachine *a_pMachine)
     277{
     278    if (   m->hMainMod != NIL_RTLDRMOD
     279        && m->pReg->pfnVMCreated)
     280        m->pReg->pfnVMCreated(m->pReg, a_pMachine);
     281}
     282
     283/**
     284 * Calls the pfnVMConfigureVMM hook.
     285 *
     286 * @returns VBox status code, LogRel called on failure.
     287 * @param   a_pConsole          The console interface.
     288 * @param   a_pVM               The VM handle.
     289 * @remarks Caller holds the extension manager lock.
     290 */
     291int ExtPack::callVmConfigureVmmHook(IConsole *a_pConsole, PVM a_pVM)
     292{
     293    if (   m->hMainMod != NIL_RTLDRMOD
     294        && m->pReg->pfnVMConfigureVMM)
     295    {
     296        int vrc = m->pReg->pfnVMConfigureVMM(m->pReg, a_pConsole, a_pVM);
     297        if (RT_FAILURE(vrc))
     298        {
     299            LogRel(("ExtPack pfnVMConfigureVMM returned %Rrc for %s\n", vrc, m->Desc.strName.c_str()));
     300            return vrc;
     301        }
     302    }
     303    return VINF_SUCCESS;
     304}
     305
     306/**
     307 * Calls the pfnVMPowerOn hook.
     308 *
     309 * @returns VBox status code, LogRel called on failure.
     310 * @param   a_pConsole          The console interface.
     311 * @param   a_pVM               The VM handle.
     312 * @remarks Caller holds the extension manager lock.
     313 */
     314int ExtPack::callVmPowerOnHook(IConsole *a_pConsole, PVM a_pVM)
     315{
     316    if (   m->hMainMod != NIL_RTLDRMOD
     317        && m->pReg->pfnVMPowerOn)
     318    {
     319        int vrc = m->pReg->pfnVMPowerOn(m->pReg, a_pConsole, a_pVM);
     320        if (RT_FAILURE(vrc))
     321        {
     322            LogRel(("ExtPack pfnVMPowerOn returned %Rrc for %s\n", vrc, m->Desc.strName.c_str()));
     323            return vrc;
     324        }
     325    }
     326    return VINF_SUCCESS;
     327}
     328
     329/**
     330 * Calls the pfnVMPowerOff hook.
     331 *
     332 * @param   a_pConsole          The console interface.
     333 * @param   a_pVM               The VM handle.
     334 * @remarks Caller holds the extension manager lock.
     335 */
     336void ExtPack::callVmPowerOffHook(IConsole *a_pConsole, PVM a_pVM)
     337{
     338    if (   m->hMainMod != NIL_RTLDRMOD
     339        && m->pReg->pfnVMPowerOff)
     340        m->pReg->pfnVMPowerOff(m->pReg, a_pConsole, a_pVM);
    210341}
    211342
     
    217348 * @returns S_OK or COM error status with error information.
    218349 * @param   pfCanDelete     Optional can-delete-this-object output indicator.
     350 * @remarks Caller holds the extension manager lock for writing.
    219351 */
    220352HRESULT ExtPack::refresh(bool *pfCanDelete)
     
    223355        *pfCanDelete = false;
    224356
    225     AutoWriteLock autoLock(this COMMA_LOCKVAL_SRC_POS);
     357    AutoWriteLock autoLock(this COMMA_LOCKVAL_SRC_POS); /* for the COMGETTERs */
    226358
    227359    /*
     
    395527                if (   (!m->pReg->pfnInstalled      || RT_VALID_PTR(m->pReg->pfnInstalled))
    396528                    && (!m->pReg->pfnUninstall      || RT_VALID_PTR(m->pReg->pfnUninstall))
     529                    && (!m->pReg->pfnUnload         || RT_VALID_PTR(m->pReg->pfnUnload))
    397530                    && (!m->pReg->pfnVMCreated      || RT_VALID_PTR(m->pReg->pfnVMCreated))
    398531                    && (!m->pReg->pfnVMConfigureVMM || RT_VALID_PTR(m->pReg->pfnVMConfigureVMM))
     
    445578                         Utf8Str *a_pStrFound, bool *a_pfNative, PRTFSOBJINFO a_pObjInfo) const
    446579{
     580    /*
     581     * Try the native path first.
     582     */
     583    char szPath[RTPATH_MAX];
     584    int vrc = RTPathJoin(szPath, sizeof(szPath), m->strExtPackPath.c_str(), RTBldCfgTargetDotArch());
     585    AssertLogRelRCReturn(vrc, false);
     586    vrc = RTPathAppend(szPath, sizeof(szPath), a_pszName);
     587    AssertLogRelRCReturn(vrc, false);
     588    if (!a_pszExt)
     589    {
     590        vrc = RTStrCat(szPath, sizeof(szPath), RTLdrGetSuff());
     591        AssertLogRelRCReturn(vrc, false);
     592    }
     593
     594    RTFSOBJINFO ObjInfo;
     595    if (!a_pObjInfo)
     596        a_pObjInfo = &ObjInfo;
     597    vrc = RTPathQueryInfo(szPath, a_pObjInfo, RTFSOBJATTRADD_UNIX);
     598    if (RT_SUCCESS(vrc) && RTFS_IS_FIFO(a_pObjInfo->Attr.fMode))
     599    {
     600        if (a_pfNative)
     601            *a_pfNative = true;
     602        a_pStrFound = new Utf8Str(szPath);
     603        return true;
     604    }
     605
     606    /*
     607     * Try the platform agnostic modules.
     608     */
     609    /* gcc.x86/module.rel */
     610    char szSubDir[32];
     611    RTStrPrintf(szSubDir, sizeof(szSubDir), "%s.%s", RTBldCfgCompiler(), RTBldCfgTargetArch());
     612    vrc = RTPathJoin(szPath, sizeof(szPath), m->strExtPackPath.c_str(), szSubDir);
     613    AssertLogRelRCReturn(vrc, false);
     614    vrc = RTPathAppend(szPath, sizeof(szPath), a_pszName);
     615    AssertLogRelRCReturn(vrc, false);
     616    if (!a_pszExt)
     617    {
     618        vrc = RTStrCat(szPath, sizeof(szPath), ".rel");
     619        AssertLogRelRCReturn(vrc, false);
     620    }
     621    vrc = RTPathQueryInfo(szPath, a_pObjInfo, RTFSOBJATTRADD_UNIX);
     622    if (RT_SUCCESS(vrc) && RTFS_IS_FIFO(a_pObjInfo->Attr.fMode))
     623    {
     624        if (a_pfNative)
     625            *a_pfNative = false;
     626        a_pStrFound = new Utf8Str(szPath);
     627        return true;
     628    }
     629
     630    /* x86/module.rel */
     631    vrc = RTPathJoin(szPath, sizeof(szPath), m->strExtPackPath.c_str(), RTBldCfgTargetArch());
     632    AssertLogRelRCReturn(vrc, false);
     633    vrc = RTPathAppend(szPath, sizeof(szPath), a_pszName);
     634    AssertLogRelRCReturn(vrc, false);
     635    if (!a_pszExt)
     636    {
     637        vrc = RTStrCat(szPath, sizeof(szPath), ".rel");
     638        AssertLogRelRCReturn(vrc, false);
     639    }
     640    vrc = RTPathQueryInfo(szPath, a_pObjInfo, RTFSOBJATTRADD_UNIX);
     641    if (RT_SUCCESS(vrc) && RTFS_IS_FIFO(a_pObjInfo->Attr.fMode))
     642    {
     643        if (a_pfNative)
     644            *a_pfNative = false;
     645        a_pStrFound = new Utf8Str(szPath);
     646        return true;
     647    }
     648
    447649    return false;
    448650}
     
    499701                       char *pszFound, size_t cbFound, bool *pfNative)
    500702{
     703    /*
     704     * Validate the input and get our bearings.
     705     */
     706    AssertPtrReturn(pszName, VERR_INVALID_POINTER);
     707    AssertPtrNullReturn(pszExt, VERR_INVALID_POINTER);
     708    AssertPtrReturn(pszFound, VERR_INVALID_POINTER);
     709    AssertPtrNullReturn(pfNative, VERR_INVALID_POINTER);
     710
     711    AssertPtrReturn(pHlp, VERR_INVALID_POINTER);
     712    AssertReturn(pHlp->u32Version == VBOXEXTPACKHLP_VERSION, VERR_INVALID_POINTER);
     713    ExtPack::Data *m = RT_FROM_CPP_MEMBER(pHlp, Data, Hlp);
     714    AssertPtrReturn(m, VERR_INVALID_POINTER);
     715    ExtPack *pThis = m->pThis;
     716    AssertPtrReturn(pThis, VERR_INVALID_POINTER);
     717
     718    /*
     719     * This is just a wrapper around findModule.
     720     */
     721    Utf8Str strFound;
     722    if (pThis->findModule(pszName, pszExt, &strFound, pfNative, NULL))
     723        return RTStrCopy(pszFound, cbFound, strFound.c_str());
    501724    return VERR_FILE_NOT_FOUND;
    502725}
     
    516739        Bstr str(m->Desc.strName);
    517740        str.cloneTo(a_pbstrName);
     741    }
     742    return hrc;
     743}
     744
     745STDMETHODIMP ExtPack::COMGETTER(Description)(BSTR *a_pbstrDescription)
     746{
     747    CheckComArgOutPointerValid(a_pbstrDescription);
     748
     749    AutoCaller autoCaller(this);
     750    HRESULT hrc = autoCaller.rc();
     751    if (SUCCEEDED(hrc))
     752    {
     753        Bstr str(m->Desc.strDescription);
     754        str.cloneTo(a_pbstrDescription);
    518755    }
    519756    return hrc;
     
    589826 *
    590827 * @returns COM status code.
    591  */
    592 HRESULT ExtPackManager::init()
     828 * @param   a_pszDropZoneDir        The path to the drop zone directory.
     829 * @param   a_fCheckDropZone        Whether to check the drop zone for new
     830 *                                  extensions or not.  Only VBoxSVC does this
     831 *                                  and then only when wanted.
     832 */
     833HRESULT ExtPackManager::init(const char *a_pszDropZoneDir, bool a_fCheckDropZone)
    593834{
    594835    /*
    595836     * Figure some stuff out before creating the instance data.
    596837     */
    597     char szBasePath[RTPATH_MAX];
    598     int rc = RTPathAppPrivateArch(szBasePath, sizeof(szBasePath));
     838    char szBaseDir[RTPATH_MAX];
     839    int rc = RTPathAppPrivateArch(szBaseDir, sizeof(szBaseDir));
    599840    AssertLogRelRCReturn(rc, E_FAIL);
    600     rc = RTPathAppend(szBasePath, sizeof(szBasePath), "ExtensionPacks");
     841    rc = RTPathAppend(szBaseDir, sizeof(szBaseDir), "ExtensionPacks");
    601842    AssertLogRelRCReturn(rc, E_FAIL);
    602843
     844    char szCertificatDir[RTPATH_MAX];
     845    rc = RTPathAppPrivateArch(szCertificatDir, sizeof(szCertificatDir));
     846    AssertLogRelRCReturn(rc, E_FAIL);
     847    rc = RTPathAppend(szBaseDir, sizeof(szCertificatDir), "Certificates");
     848    AssertLogRelRCReturn(rc, E_FAIL);
     849
    603850    /*
    604851     * Allocate and initialize the instance data.
    605852     */
    606853    m = new Data;
    607     m->strBasePath = szBasePath;
     854    m->strBaseDir           = szBaseDir;
     855    m->strCertificatDirPath = szCertificatDir;
     856    m->strDropZoneDir       = a_pszDropZoneDir;
    608857
    609858    /*
     
    615864     */
    616865    PRTDIR pDir;
    617     int vrc = RTDirOpen(&pDir, szBasePath);
     866    int vrc = RTDirOpen(&pDir, szBaseDir);
    618867    if (RT_FAILURE(vrc))
    619868        return S_OK;
     
    639888            HRESULT hrc2 = NewExtPack.createObject();
    640889            if (SUCCEEDED(hrc2))
    641                 hrc2 = NewExtPack->init(Entry.szName, szBasePath);
     890                hrc2 = NewExtPack->init(Entry.szName, szBaseDir);
    642891            if (SUCCEEDED(hrc2))
    643892                m->llInstalledExtPacks.push_back(NewExtPack);
     
    648897    RTDirClose(pDir);
    649898
     899    /*
     900     * Look for things in the drop zone.
     901     */
     902    if (SUCCEEDED(hrc) && a_fCheckDropZone)
     903        processDropZone();
     904
    650905    return hrc;
    651906}
     
    668923    if (!autoUninitSpan.uninitDone() && m != NULL)
    669924    {
    670         /** @todo do unload notifications */
    671 
    672925        delete m;
    673926        m = NULL;
     
    7791032
    7801033                                hrc = runSetUidToRootHelper("install",
    781                                                             "--basepath",   m->strBasePath.c_str(),
    782                                                             "--name",       pszName,
    783                                                             "--tarball",    strTarball.c_str(),
    784                                                             "--tarball-fd", &szTarballFd[0],
     1034                                                            "--base-dir",        m->strBaseDir.c_str(),
     1035                                                            "--name",            pszName,
     1036                                                            "--certificate-dir", m->strCertificatDirPath.c_str(),
     1037                                                            "--tarball",         strTarball.c_str(),
     1038                                                            "--tarball-fd",      &szTarballFd[0],
    7851039                                                            NULL);
    7861040                                if (SUCCEEDED(hrc))
     
    7881042                                    hrc = refreshExtPack(pszName, true /*a_fUnsuableIsError*/, &pExtPack);
    7891043                                    if (SUCCEEDED(hrc))
     1044                                    {
    7901045                                        LogRel(("ExtPackManager: Successfully installed extension pack '%s'.\n", pszName));
     1046                                        pExtPack->callInstalledHook();
     1047                                    }
    7911048                                }
    7921049                                else
     
    8531110            {
    8541111                /*
    855                  * Run the set-uid-to-root binary that performs the
    856                  * uninstallation.  Then refresh the object.
    857                  *
    858                  * This refresh is theorically subject to races, but it's of
    859                  * the don't-do-that variety.
     1112                 * Call the uninstall hook and unload the main dll.
    8601113                 */
    861                 const char *pszForcedOpt = a_fForcedRemoval ? "--forced" : NULL;
    862                 hrc = runSetUidToRootHelper("uninstall",
    863                                             "--basepath", m->strBasePath.c_str(),
    864                                             "--name",     strName.c_str(),
    865                                             pszForcedOpt, /* Last as it may be NULL. */
    866                                             NULL);
     1114                hrc = pExtPack->callUninstallHookAndClose(a_fForcedRemoval != FALSE);
    8671115                if (SUCCEEDED(hrc))
    8681116                {
    869                     hrc = refreshExtPack(strName.c_str(), false /*a_fUnsuableIsError*/, &pExtPack);
     1117                    /*
     1118                     * Run the set-uid-to-root binary that performs the
     1119                     * uninstallation.  Then refresh the object.
     1120                     *
     1121                     * This refresh is theorically subject to races, but it's of
     1122                     * the don't-do-that variety.
     1123                     */
     1124                    const char *pszForcedOpt = a_fForcedRemoval ? "--forced" : NULL;
     1125                    hrc = runSetUidToRootHelper("uninstall",
     1126                                                "--base-dir", m->strBaseDir.c_str(),
     1127                                                "--name",     strName.c_str(),
     1128                                                pszForcedOpt, /* Last as it may be NULL. */
     1129                                                NULL);
    8701130                    if (SUCCEEDED(hrc))
    8711131                    {
    872                         if (!pExtPack)
    873                             LogRel(("ExtPackManager: Successfully uninstalled extension pack '%s'.\n", strName.c_str()));
    874                         else
    875                             hrc = setError(E_UNEXPECTED,
    876                                            tr("Uninstall extension pack '%s' failed under mysterious circumstances"),
    877                                            strName.c_str());
     1132                        hrc = refreshExtPack(strName.c_str(), false /*a_fUnsuableIsError*/, &pExtPack);
     1133                        if (SUCCEEDED(hrc))
     1134                        {
     1135                            if (!pExtPack)
     1136                                LogRel(("ExtPackManager: Successfully uninstalled extension pack '%s'.\n", strName.c_str()));
     1137                            else
     1138                                hrc = setError(E_UNEXPECTED,
     1139                                               tr("Uninstall extension pack '%s' failed under mysterious circumstances"),
     1140                                               strName.c_str());
     1141                        }
     1142                    }
     1143                    else
     1144                    {
     1145                        ErrorInfoKeeper Eik;
     1146                        refreshExtPack(strName.c_str(), false /*a_fUnsuableIsError*/, NULL);
    8781147                    }
    8791148                }
    880                 else
    881                 {
    882                     ErrorInfoKeeper Eik;
    883                     refreshExtPack(strName.c_str(), false /*a_fUnsuableIsError*/, NULL);
    884                 }
    885 
    8861149            }
    8871150        }
     
    9811244            if (hPipeR != NIL_RTPIPE)
    9821245            {
    983                 char    achBuf[16]; //1024
     1246                char    achBuf[16]; ///@todo 1024
    9841247                size_t  cbRead;
    9851248                vrc = RTPipeReadBlocking(hPipeR, achBuf, sizeof(achBuf), &cbRead);
     
    11341397 *                              pack of it is still around after the refresh.
    11351398 *                              This is optional.
     1399 * @remarks Caller holds the extension manager lock.
    11361400 */
    11371401HRESULT ExtPackManager::refreshExtPack(const char *a_pszName, bool a_fUnsuableIsError, ExtPack **a_ppExtPack)
     
    11621426         */
    11631427        char szDir[RTPATH_MAX];
    1164         int vrc = RTPathJoin(szDir, sizeof(szDir), m->strBasePath.c_str(), a_pszName);
     1428        int vrc = RTPathJoin(szDir, sizeof(szDir), m->strBaseDir.c_str(), a_pszName);
    11651429        AssertLogRelRCReturn(vrc, E_FAIL);
    11661430
     
    11721436        {
    11731437            PRTDIR pDir;
    1174             vrc = RTDirOpen(&pDir, m->strBasePath.c_str());
     1438            vrc = RTDirOpen(&pDir, m->strBaseDir.c_str());
    11751439            if (RT_SUCCESS(vrc))
    11761440            {
     
    11901454                         * Update the name and directory variables.
    11911455                         */
    1192                         vrc = RTPathJoin(szDir, sizeof(szDir), m->strBasePath.c_str(), Entry.szName); /* not really necessary */
     1456                        vrc = RTPathJoin(szDir, sizeof(szDir), m->strBaseDir.c_str(), Entry.szName); /* not really necessary */
    11931457                        AssertLogRelRCReturnStmt(vrc, E_UNEXPECTED, RTDirClose(pDir));
    11941458                        a_pszName = Entry.szName;
     
    12081472            hrc = NewExtPack.createObject();
    12091473            if (SUCCEEDED(hrc))
    1210                 hrc = NewExtPack->init(a_pszName, m->strBasePath.c_str());
     1474                hrc = NewExtPack->init(a_pszName, m->strBaseDir.c_str());
    12111475            if (SUCCEEDED(hrc))
    12121476            {
     
    12391503
    12401504
    1241 
    1242 int ExtPackManager::callAllConfigHooks(IConsole *a_pConsole, PVM a_pVM)
    1243 {
    1244     NOREF(a_pConsole); NOREF(a_pVM);
     1505/**
     1506 * Processes anything new in the drop zone.
     1507 */
     1508void ExtPackManager::processDropZone(void)
     1509{
     1510    AutoCaller autoCaller(this);
     1511    HRESULT hrc = autoCaller.rc();
     1512    if (FAILED(hrc))
     1513        return;
     1514    AutoWriteLock autoLock(this COMMA_LOCKVAL_SRC_POS);
     1515
     1516    if (m->strDropZoneDir.isEmpty())
     1517        return;
     1518
     1519    PRTDIR pDir;
     1520    int vrc = RTDirOpen(&pDir, m->strDropZoneDir.c_str());
     1521    if (RT_FAILURE(vrc))
     1522        return;
     1523    for (;;)
     1524    {
     1525        RTDIRENTRYEX Entry;
     1526        vrc = RTDirReadEx(pDir, &Entry, NULL /*pcbDirEntry*/, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK);
     1527        if (RT_FAILURE(vrc))
     1528        {
     1529            AssertMsg(vrc == VERR_NO_MORE_FILES, ("%Rrc\n", vrc));
     1530            break;
     1531        }
     1532
     1533        /*
     1534         * We're looking for files with the right extension.  Symbolic links
     1535         * will be ignored.
     1536         */
     1537        if (   RTFS_IS_FILE(Entry.Info.Attr.fMode)
     1538            && RTStrICmp(RTPathExt(Entry.szName), VBOX_EXTPACK_SUFFIX) == 0)
     1539        {
     1540            /* We create (and check for) a blocker file to prevent this
     1541               extension pack from being installed more than once. */
     1542            char szPath[RTPATH_MAX];
     1543            vrc = RTPathJoin(szPath, sizeof(szPath), m->strDropZoneDir.c_str(), Entry.szName);
     1544            if (RT_SUCCESS(vrc))
     1545                vrc = RTPathAppend(szPath, sizeof(szPath), "-done");
     1546            AssertRC(vrc);
     1547            if (RT_SUCCESS(vrc))
     1548            {
     1549                RTFILE hFile;
     1550                vrc = RTFileOpen(&hFile, szPath,  RTFILE_O_WRITE | RTFILE_O_DENY_WRITE | RTFILE_O_CREATE);
     1551                if (RT_SUCCESS(vrc))
     1552                {
     1553                    /* Construct the full path to the extension pack and invoke
     1554                       the Install method to install it.  Write errors to the
     1555                       done file. */
     1556                    vrc = RTPathJoin(szPath, sizeof(szPath), m->strDropZoneDir.c_str(), Entry.szName); AssertRC(vrc);
     1557                    Bstr strName;
     1558                    hrc = Install(Bstr(szPath).raw(), strName.asOutParam());
     1559                    if (SUCCEEDED(hrc))
     1560                        RTFileWrite(hFile, "succeeded\n", sizeof("succeeded\n"), NULL);
     1561                    else
     1562                    {
     1563                        Utf8Str strErr;
     1564                        com::ErrorInfo Info(this, COM_IIDOF(IExtPackManager));
     1565                        if (Info.isFullAvailable())
     1566                            strErr.printf("failed\n"
     1567                                          "%ls\n"
     1568                                          "Details: code %Rhrc (%#RX32), component %ls, interface %ls, callee %ls\n"
     1569                                          ,
     1570                                          Info.getText().raw(),
     1571                                          Info.getResultCode(),
     1572                                          Info.getResultCode(),
     1573                                          Info.getComponent().raw(),
     1574                                          Info.getInterfaceName().raw(),
     1575                                          Info.getCalleeName().raw());
     1576                        else
     1577                            strErr.printf("failed\n"
     1578                                          "hrc=%Rhrc (%#RX32)\n", hrc, hrc);
     1579                        RTFileWrite(hFile, strErr.c_str(), strErr.length(), NULL);
     1580                    }
     1581                    RTFileClose(hFile);
     1582                }
     1583            }
     1584        }
     1585    } /* foreach dir entry */
     1586    RTDirClose(pDir);
     1587}
     1588
     1589
     1590/**
     1591 * Calls the pfnVMCreated hook for all working extension packs.
     1592 *
     1593 * @param   a_pMachine          The machine interface of the new VM.
     1594 */
     1595void ExtPackManager::callAllVmCreatedHooks(IMachine *a_pMachine)
     1596{
     1597    AutoCaller autoCaller(this);
     1598    HRESULT hrc = autoCaller.rc();
     1599    if (FAILED(hrc))
     1600        return;
     1601    AutoReadLock autoLock(this COMMA_LOCKVAL_SRC_POS);
     1602
     1603    for (ExtPackList::iterator it = m->llInstalledExtPacks.begin();
     1604         it != m->llInstalledExtPacks.end();
     1605         it++)
     1606        (*it)->callVmCreatedHook(a_pMachine);
     1607}
     1608
     1609/**
     1610 * Calls the pfnVMConfigureVMM hook for all working extension packs.
     1611 *
     1612 * @returns VBox status code.  Stops on the first failure, expecting the caller
     1613 *          to signal this to the caller of the CFGM constructor.
     1614 * @param   a_pConsole          The console interface for the VM.
     1615 * @param   a_pVM               The VM handle.
     1616 */
     1617int ExtPackManager::callAllVmConfigureVmmHooks(IConsole *a_pConsole, PVM a_pVM)
     1618{
     1619    AutoCaller autoCaller(this);
     1620    HRESULT hrc = autoCaller.rc();
     1621    if (FAILED(hrc))
     1622        return Global::vboxStatusCodeFromCOM(hrc);
     1623    AutoReadLock autoLock(this COMMA_LOCKVAL_SRC_POS);
     1624
     1625    for (ExtPackList::iterator it = m->llInstalledExtPacks.begin();
     1626         it != m->llInstalledExtPacks.end();
     1627         it++)
     1628    {
     1629        int vrc = (*it)->callVmConfigureVmmHook(a_pConsole, a_pVM);
     1630        if (RT_FAILURE(vrc))
     1631            return vrc;
     1632    }
     1633
    12451634    return VINF_SUCCESS;
    12461635}
    12471636
    1248 int ExtPackManager::callAllNewMachineHooks(IMachine *a_pMachine)
    1249 {
    1250     NOREF(a_pMachine);
     1637/**
     1638 * Calls the pfnVMPowerOn hook for all working extension packs.
     1639 *
     1640 * @returns VBox status code.  Stops on the first failure, expecting the caller
     1641 *          to not power on the VM.
     1642 * @param   a_pConsole          The console interface for the VM.
     1643 * @param   a_pVM               The VM handle.
     1644 */
     1645int ExtPackManager::callAllVmPowerOnHooks(IConsole *a_pConsole, PVM a_pVM)
     1646{
     1647    AutoCaller autoCaller(this);
     1648    HRESULT hrc = autoCaller.rc();
     1649    if (FAILED(hrc))
     1650        return Global::vboxStatusCodeFromCOM(hrc);
     1651    AutoReadLock autoLock(this COMMA_LOCKVAL_SRC_POS);
     1652
     1653    for (ExtPackList::iterator it = m->llInstalledExtPacks.begin();
     1654         it != m->llInstalledExtPacks.end();
     1655         it++)
     1656    {
     1657        int vrc = (*it)->callVmPowerOnHook(a_pConsole, a_pVM);
     1658        if (RT_FAILURE(vrc))
     1659            return vrc;
     1660    }
     1661
    12511662    return VINF_SUCCESS;
    12521663}
    12531664
     1665/**
     1666 * Calls the pfnVMPowerOff hook for all working extension packs.
     1667 *
     1668 * @param   a_pConsole          The console interface for the VM.
     1669 * @param   a_pVM               The VM handle. Can be NULL.
     1670 */
     1671void ExtPackManager::callAllVmPowerOffHooks(IConsole *a_pConsole, PVM a_pVM)
     1672{
     1673    AutoCaller autoCaller(this);
     1674    HRESULT hrc = autoCaller.rc();
     1675    if (FAILED(hrc))
     1676        return;
     1677    AutoReadLock autoLock(this COMMA_LOCKVAL_SRC_POS);
     1678
     1679    for (ExtPackList::iterator it = m->llInstalledExtPacks.begin();
     1680         it != m->llInstalledExtPacks.end();
     1681         it++)
     1682        (*it)->callVmPowerOnHook(a_pConsole, a_pVM);
     1683}
     1684
    12541685
    12551686/* vi: set tabstop=4 shiftwidth=4 expandtab: */
  • trunk/src/VBox/Main/Makefile.kmk

    r33687 r33693  
    192192
    193193VBOX_AUTOGEN_EVENT_CPP  = $(PATH_TARGET)/Main/VBoxEvents.cpp
    194 OTHER_CLEAN    += $(VBOX_AUTOGEN_EVENT_CPP)
    195194
    196195testschemadefs: $(VBOX_XML_SCHEMADEFS_H) $(VBOX_XML_SCHEMADEFS_CPP)
     
    323322        $(if $(VBOX_WITH_EXTPACK),ExtPackManagerImpl.cpp ExtPackUtil.cpp,)
    324323
    325 $(VBOX_AUTOGEN_EVENT_CPP): $(VBOX_PATH_MAIN_SRC)/idl/comimpl.xsl $(VBOX_XIDL_FILE) | $$(dir $$@)
    326         $(call MSG_TOOL,xsltproc,autogen events,$<,$@)
    327         $(QUIET)$(VBOX_XSLTPROC) --stringparam G_kind VBoxEvent -o $@ $< $(VBOX_XIDL_FILE)
    328 
    329324VBoxSVC_SOURCES.darwin = \
    330325        darwin/iokit.cpp \
     
    435430        $(VBOX_XSLTPROC) --stringparam Module VBoxSVC -o $@ $< $(VBOX_XIDL_FILE)
    436431
     432
    437433#
    438434# Embed XML Schema files to VBoxSVC
     
    471467
    472468
     469#
     470# Generate some event stuff for VBoxSVC and VBoxC.
     471#
     472$(VBOX_AUTOGEN_EVENT_CPP): $(VBOX_PATH_MAIN_SRC)/idl/comimpl.xsl $(VBOX_XIDL_FILE) | $$(dir $$@)
     473        $(call MSG_TOOL,xsltproc,autogen events,$<,$@)
     474        $(QUIET)$(VBOX_XSLTPROC) --stringparam G_kind VBoxEvent -o $@ $< $(VBOX_XIDL_FILE)
     475
     476OTHER_CLEAN += $(VBOX_AUTOGEN_EVENT_CPP)
     477
     478
     479#
     480# VBoxTestOGL - OpenGL support test app.
     481# Note! Doesn't link with VBOX_WITH_DEBUG_VCC_CRT defined because it uses Qt.
     482#
    473483if (   defined(VBOX_WITH_QTGUI) \
    474484    && (defined(VBOX_WITH_CROGL) || defined(VBOX_WITH_VIDEOHWACCEL)) \
    475485    && !defined(VBOX_WITH_DEBUG_VCC_CRT))
    476486 ifneq ($(KBUILD_TARGET),darwin)
    477   #
    478   # VBoxTestOGL - OpenGL support test app.
    479   # Note! Doesn't link with VBOX_WITH_DEBUG_VCC_CRT defined because it uses Qt.
    480   #
    481487  ifdef VBOX_WITH_VIDEOHWACCEL
    482488   USES += qt4
     
    538544 endif
    539545VBoxSVCM_INTERMEDIATES += $(VBOX_IDL_HEADER.XPCOM)
    540 
    541546endif # VBOX_WITH_XPCOM
     547
    542548
    543549#
  • trunk/src/VBox/Main/include/ExtPackManagerImpl.h

    r33623 r33693  
    5555     * @{ */
    5656    STDMETHOD(COMGETTER(Name))(BSTR *a_pbstrName);
     57    STDMETHOD(COMGETTER(Description))(BSTR *a_pbstrDescription);
    5758    STDMETHOD(COMGETTER(Version))(BSTR *a_pbstrVersion);
    5859    STDMETHOD(COMGETTER(Revision))(ULONG *a_puRevision);
     
    6364    /** @name Internal interfaces used by ExtPackManager.
    6465     * @{ */
    65     void *getCallbackTable();
    66     HRESULT refresh(bool *pfCanDelete);
     66    void        callInstalledHook(void);
     67    HRESULT     callUninstallHookAndClose(bool a_fForcedRemoval);
     68    void        callVmCreatedHook(IMachine *a_pMachine);
     69    int         callVmConfigureVmmHook(IConsole *a_pConsole, PVM a_pVM);
     70    int         callVmPowerOnHook(IConsole *a_pConsole, PVM a_pVM);
     71    void        callVmPowerOffHook(IConsole *a_pConsole, PVM a_pVM);
     72    HRESULT     refresh(bool *pfCanDelete);
    6773    /** @}  */
    6874
     
    112118    HRESULT     FinalConstruct();
    113119    void        FinalRelease();
    114     HRESULT     init();
     120    HRESULT     init(const char *a_pszDropZonePath, bool a_fCheckDropZone);
    115121    void        uninit();
    116122    /** @}  */
     
    126132    /** @name Internal interfaces used by other Main classes.
    127133     * @{ */
    128     int         callAllConfigHooks(IConsole *a_pConsole, PVM a_pVM);
    129     int         callAllNewMachineHooks(IMachine *a_pMachine);
     134    void        processDropZone(void);
     135    void        callAllVmCreatedHooks(IMachine *a_pMachine);
     136    int         callAllVmConfigureVmmHooks(IConsole *a_pConsole, PVM a_pVM);
     137    int         callAllVmPowerOnHooks(IConsole *a_pConsole, PVM a_pVM);
     138    void        callAllVmPowerOffHooks(IConsole *a_pConsole, PVM a_pVM);
    130139    /** @}  */
    131140
  • trunk/src/VBox/Main/include/ExtPackUtil.h

    r33656 r33693  
    2121 * The name of the description file in an extension pack.  */
    2222#define VBOX_EXTPACK_DESCRIPTION_NAME   "ExtPack.xml"
     23/** @name VBOX_EXTPACK_SUFFIX
     24 * The suffix of a extension pack tarball. */
     25#define VBOX_EXTPACK_SUFFIX             ".vbox-extpack"
    2326
    2427
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette