VirtualBox

Changeset 16649 in vbox for trunk


Ignore:
Timestamp:
Feb 10, 2009 6:29:02 PM (16 years ago)
Author:
vboxsync
Message:

Main/Glue: com::Initialize() now first looks for XPCOM binaries and components in the VBOX_APP_HOME directory when this environment variable is set. Otherwise, it tries the compiled-in VirtualBox installation path as before and if it fails, checks several hard-coded paths. This is to make it possible to start 3rd-party client applications located in directories other than the VirtualBox installation directory.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/glue/initterm.cpp

    r16555 r16649  
    193193#endif /* defined (VBOX_WITH_XPCOM) */
    194194
    195 
     195/**
     196 * Initializes the COM runtime.
     197 *
     198 * This method must be called on each thread of the client application that
     199 * wants to access COM facilities. The initialization must be performed before
     200 * calling any other COM method or attempting to instantiate COM objects.
     201 *
     202 * On platforms using XPCOM, this method uses the following scheme to search for
     203 * XPCOM runtime:
     204 *
     205 * 1. If the VBOX_APP_HOME environment variable is set, the path it specifies
     206 *    is used to search XPCOM libraries and components. If this method fails to
     207 *    initialize XPCOM runtime using this path, it will immediately return a
     208 *    failure and will NOT check for other paths as described below.
     209 *
     210 * 2. If VBOX_APP_HOME is not set, this methods tries the following paths in the
     211 *    given order:
     212 *
     213 *    a) Compiled-in application data directory (as returned by
     214 *       RTPathAppPrivateArch())
     215 *    b) "/usr/lib/virtualbox" (Linux only)
     216 *    c) "/opt/VirtualBox" (Linux only)
     217 *
     218 *    The first path for which the initialization succeeds will be used.
     219 *
     220 * On MS COM platforms, the COM runtime is provided by the system and does not
     221 * need to be searched for.
     222 *
     223 * Once the COM subsystem is no longer necessary on a given thread, Shutdown()
     224 * must be called to free resources allocated for it. Note that a thread may
     225 * call Initialize() several times but for each of tese calls there must be a
     226 * corresponding Shutdown() call.
     227 *
     228 * @return S_OK on success and a COM result code in case of failure.
     229 */
    196230HRESULT Initialize()
    197231{
     
    307341    gXPCOMInitCount = 1;
    308342
    309     /* Set VBOX_XPCOM_HOME if not present */
    310     if (!RTEnvExist ("VBOX_XPCOM_HOME"))
    311     {
    312         /* get the executable path */
    313         char pathProgram [RTPATH_MAX];
    314         int vrc = RTPathProgram (pathProgram, sizeof (pathProgram));
    315         if (RT_SUCCESS (vrc))
    316         {
    317             char *pathProgramCP = NULL;
    318             vrc = RTStrUtf8ToCurrentCP (&pathProgramCP, pathProgram);
    319             if (RT_SUCCESS (vrc))
    320             {
    321                 vrc = RTEnvSet ("VBOX_XPCOM_HOME", pathProgramCP);
    322                 RTStrFree (pathProgramCP);
    323             }
    324         }
    325         AssertRC (vrc);
    326     }
     343    /* prepare paths for registry files */
     344    char userHomeDir [RTPATH_MAX];
     345    int vrc = GetVBoxUserHomeDirectory (userHomeDir, sizeof (userHomeDir));
     346    AssertRCReturn (vrc, NS_ERROR_FAILURE);
     347
     348    char compReg [RTPATH_MAX];
     349    char xptiDat [RTPATH_MAX];
     350
     351    RTStrPrintf (compReg, sizeof (compReg), "%s%c%s",
     352                 userHomeDir, RTPATH_DELIMITER, "compreg.dat");
     353    RTStrPrintf (xptiDat, sizeof (xptiDat), "%s%c%s",
     354                 userHomeDir, RTPATH_DELIMITER, "xpti.dat");
     355
     356    LogFlowFunc (("component registry  : \"%s\"\n", compReg));
     357    LogFlowFunc (("XPTI data file      : \"%s\"\n", xptiDat));
    327358
    328359#if defined (XPCOM_GLUE)
     
    330361#endif
    331362
    332     nsCOMPtr <DirectoryServiceProvider> dsProv;
    333 
    334     /* prepare paths for registry files */
    335     char homeDir [RTPATH_MAX];
    336     char privateArchDir [RTPATH_MAX];
    337     int vrc = GetVBoxUserHomeDirectory (homeDir, sizeof (homeDir));
    338     if (RT_SUCCESS (vrc))
    339         vrc = RTPathAppPrivateArch (privateArchDir, sizeof (privateArchDir));
    340     if (RT_SUCCESS (vrc))
    341     {
    342         char compReg [RTPATH_MAX];
    343         char xptiDat [RTPATH_MAX];
     363    const char *kAppPathsToProbe[] =
     364    {
     365        NULL, /* 0: will use VBOX_APP_HOME */
     366        NULL, /* 1: will try RTPathAppPrivateArch() */
     367#ifdef RT_OS_LINUX
     368        "/usr/lib/virtualbox",
     369        "/opt/VirtualBox",
     370#endif
     371    };
     372
     373    /* Find out the directory where VirtualBox binaries are located */
     374    for (size_t i = 0; i < RT_ELEMENTS (kAppPathsToProbe); ++ i)
     375    {
     376        char appHomeDir [RTPATH_MAX];
     377        appHomeDir [RTPATH_MAX - 1] = '\0';
     378
     379        if (i == 0)
     380        {
     381            /* Use VBOX_APP_HOME if present */
     382            if (!RTEnvExist ("VBOX_APP_HOME"))
     383                continue;
     384
     385            strncpy (appHomeDir, RTEnvGet ("VBOX_APP_HOME"), RTPATH_MAX - 1);
     386        }
     387        else if (i == 1)
     388        {
     389            /* Use RTPathAppPrivateArch() first */
     390            vrc = RTPathAppPrivateArch (appHomeDir, sizeof (appHomeDir));
     391            AssertRC (vrc);
     392            if (RT_FAILURE (vrc))
     393            {
     394                rc = NS_ERROR_FAILURE;
     395                continue;
     396            }
     397        }
     398        else
     399        {
     400            /* Iterate over all other paths */
     401            strncpy (appHomeDir, kAppPathsToProbe [i], RTPATH_MAX - 1);
     402        }
     403
     404        nsCOMPtr <DirectoryServiceProvider> dsProv;
     405
    344406        char compDir [RTPATH_MAX];
    345 
    346         RTStrPrintf (compReg, sizeof (compReg), "%s%c%s",
    347                      homeDir, RTPATH_DELIMITER, "compreg.dat");
    348         RTStrPrintf (xptiDat, sizeof (xptiDat), "%s%c%s",
    349                      homeDir, RTPATH_DELIMITER, "xpti.dat");
    350407        RTStrPrintf (compDir, sizeof (compDir), "%s%c%s",
    351                      privateArchDir, RTPATH_DELIMITER, "components");
    352 
    353         LogFlowFunc (("component registry  : \"%s\"\n", compReg));
    354         LogFlowFunc (("XPTI data file      : \"%s\"\n", xptiDat));
     408                     appHomeDir, RTPATH_DELIMITER, "components");
    355409        LogFlowFunc (("component directory : \"%s\"\n", compDir));
    356410
    357411        dsProv = new DirectoryServiceProvider();
    358412        if (dsProv)
    359             rc = dsProv->init (compReg, xptiDat, compDir, privateArchDir);
     413            rc = dsProv->init (compReg, xptiDat, compDir, appHomeDir);
    360414        else
    361415            rc = NS_ERROR_OUT_OF_MEMORY;
    362     }
    363     else
    364         rc = NS_ERROR_FAILURE;
    365 
    366     if (NS_SUCCEEDED (rc))
    367     {
    368         /* get the path to the executable */
     416        if (NS_FAILED (rc))
     417            break;
     418
     419        /* Setup the application path for NS_InitXPCOM2. Note that we properly
     420         * answer the NS_XPCOM_CURRENT_PROCESS_DIR query in our directory
     421         * service provider but it seems to be activated after the directory
     422         * service is used for the first time (see the source NS_InitXPCOM2). So
     423         * use the same value here to be on the safe side. */
    369424        nsCOMPtr <nsIFile> appDir;
    370425        {
    371             char path [RTPATH_MAX];
    372426            char *appDirCP = NULL;
    373 #if defined (DEBUG)
    374             const char *env = RTEnvGet ("VIRTUALBOX_APP_HOME");
    375             if (env)
    376             {
    377                 char *appDirUtf8 = NULL;
    378                 vrc = RTStrCurrentCPToUtf8 (&appDirUtf8, env);
    379                 if (RT_SUCCESS (vrc))
    380                 {
    381                     vrc = RTPathReal (appDirUtf8, path, RTPATH_MAX);
    382                     if (RT_SUCCESS (vrc))
    383                         vrc = RTStrUtf8ToCurrentCP (&appDirCP, appDirUtf8);
    384                     RTStrFree (appDirUtf8);
    385                 }
    386             }
    387             else
    388 #endif
    389             {
    390                 vrc = RTPathProgram (path, RTPATH_MAX);
    391                 if (RT_SUCCESS (vrc))
    392                     vrc = RTStrUtf8ToCurrentCP (&appDirCP, path);
    393             }
    394 
     427            vrc = RTStrUtf8ToCurrentCP (&appDirCP, appHomeDir);
    395428            if (RT_SUCCESS (vrc))
    396429            {
     
    406439                rc = NS_ERROR_FAILURE;
    407440        }
     441        if (NS_FAILED (rc))
     442            break;
     443
     444        /* Set VBOX_XPCOM_HOME to the same app path to make XPCOM sources that
     445         * still use it instead of the directory service happy */
     446        {
     447            char *pathCP = NULL;
     448            vrc = RTStrUtf8ToCurrentCP (&pathCP, appHomeDir);
     449            if (RT_SUCCESS (vrc))
     450            {
     451                vrc = RTEnvSet ("VBOX_XPCOM_HOME", pathCP);
     452                RTStrFree (pathCP);
     453            }
     454            AssertRC (vrc);
     455        }
    408456
    409457        /* Finally, initialize XPCOM */
     458        nsCOMPtr <nsIServiceManager> serviceManager;
     459        rc = NS_InitXPCOM2 (getter_AddRefs (serviceManager),
     460                            appDir, dsProv);
     461
    410462        if (NS_SUCCEEDED (rc))
    411463        {
    412             nsCOMPtr <nsIServiceManager> serviceManager;
    413             rc = NS_InitXPCOM2 (getter_AddRefs (serviceManager),
    414                                 appDir, dsProv);
    415 
     464            nsCOMPtr <nsIComponentRegistrar> registrar =
     465                do_QueryInterface (serviceManager, &rc);
    416466            if (NS_SUCCEEDED (rc))
    417467            {
    418                 nsCOMPtr <nsIComponentRegistrar> registrar =
    419                     do_QueryInterface (serviceManager, &rc);
     468                rc = registrar->AutoRegister (nsnull);
    420469                if (NS_SUCCEEDED (rc))
    421                     registrar->AutoRegister (nsnull);
     470                {
     471                    /* We succeeded, stop probing paths */
     472                    LogFlowFunc (("Succeeded.\n"));
     473                    break;
     474                }
    422475            }
     476        }
     477
     478        if (i == 0)
     479        {
     480            /* We failed with VBOX_APP_HOME, don't probe other paths */
     481            break;
    423482        }
    424483    }
Note: See TracChangeset for help on using the changeset viewer.

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