VirtualBox

Changeset 51751 in vbox for trunk/src/VBox/Storage


Ignore:
Timestamp:
Jun 27, 2014 8:46:25 PM (11 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
94563
Message:

Storage/VD: Add methods to load a plugin from a given path/file. Preparation for support of VD plugins in extension packs

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Storage/VD.cpp

    r51750 r51751  
    35313531 *
    35323532 * @returns VBox status code.
    3533  * @param   hPlugin    PLugin handle to add.
     3533 * @param   hPlugin    Plugin handle to add.
    35343534 */
    35353535static int vdAddPlugin(RTLDRMOD hPlugin)
     
    35513551
    35523552/**
    3553  * internal: scans plugin directory and loads found plugins.
    3554  */
    3555 static int vdLoadDynamicBackends()
     3553 * Worker for VDPluginLoadFromFilename() and vdPluginLoadFromPath().
     3554 *
     3555 * @returns VBox status code.
     3556 * @param   pszFilename    The plugin filename to load.
     3557 */
     3558static int vdPluginLoadFromFilename(const char *pszFilename)
    35563559{
    35573560#ifndef VBOX_HDD_NO_DYNAMIC_BACKENDS
    3558     int rc = VINF_SUCCESS;
    3559     PRTDIR pPluginDir = NULL;
    3560 
    3561     /* Enumerate plugin backends. */
    3562     char szPath[RTPATH_MAX];
    3563     rc = RTPathAppPrivateArch(szPath, sizeof(szPath));
    3564     if (RT_FAILURE(rc))
    3565         return rc;
    3566 
     3561    RTLDRMOD hPlugin = NIL_RTLDRMOD;
     3562    int rc = SUPR3HardenedLdrLoadPlugIn(pszFilename, &hPlugin, NULL);
     3563    if (RT_SUCCESS(rc))
     3564    {
     3565        VDBACKENDREGISTER BackendRegister;
     3566        PFNVDPLUGINLOAD pfnVDPluginLoad = NULL;
     3567
     3568        BackendRegister.pfnRegisterImage  = vdPluginRegisterImage;
     3569        BackendRegister.pfnRegisterCache  = vdPluginRegisterCache;
     3570        BackendRegister.pfnRegisterFilter = vdPluginRegisterFilter;
     3571
     3572        rc = RTLdrGetSymbol(hPlugin, VD_PLUGIN_LOAD_NAME, (void**)&pfnVDPluginLoad);
     3573        if (RT_FAILURE(rc) || !pfnVDPluginLoad)
     3574        {
     3575            LogFunc(("error resolving the entry point %s in plugin %s, rc=%Rrc, pfnVDPluginLoad=%#p\n",
     3576                     VD_PLUGIN_LOAD_NAME, pszFilename, rc, pfnVDPluginLoad));
     3577            if (RT_SUCCESS(rc))
     3578                rc = VERR_SYMBOL_NOT_FOUND;
     3579        }
     3580
     3581        if (RT_SUCCESS(rc))
     3582        {
     3583            /* Get the function table. */
     3584            rc = pfnVDPluginLoad(NULL, &BackendRegister);
     3585        }
     3586        else
     3587            LogFunc(("ignored plugin '%s': rc=%Rrc\n", pszFilename, rc));
     3588
     3589        /* Create a plugin entry on success. */
     3590        if (RT_SUCCESS(rc))
     3591            vdAddPlugin(hPlugin);
     3592        else
     3593            RTLdrClose(hPlugin);
     3594    }
     3595
     3596    return rc;
     3597#else
     3598    return VERR_NOT_IMPLEMENTED;
     3599#endif
     3600}
     3601
     3602/**
     3603 * Worker for VDPluginLoadFromPath() and vdLoadDynamicBackends().
     3604 *
     3605 * @returns VBox status code.
     3606 * @param   pszPath        The path to load plugins from.
     3607 */
     3608static int vdPluginLoadFromPath(const char *pszPath)
     3609{
     3610#ifndef VBOX_HDD_NO_DYNAMIC_BACKENDS
    35673611    /* To get all entries with VBoxHDD as prefix. */
    3568     char *pszPluginFilter = RTPathJoinA(szPath, VD_PLUGIN_PREFIX "*");
     3612    char *pszPluginFilter = RTPathJoinA(pszPath, VD_PLUGIN_PREFIX "*");
    35693613    if (!pszPluginFilter)
    35703614        return VERR_NO_STR_MEMORY;
    35713615
    35723616    PRTDIRENTRYEX pPluginDirEntry = NULL;
     3617    PRTDIR pPluginDir = NULL;
    35733618    size_t cbPluginDirEntry = sizeof(RTDIRENTRYEX);
    3574     /* The plugins are in the same directory as the other shared libs. */
    3575     rc = RTDirOpenFiltered(&pPluginDir, pszPluginFilter, RTDIRFILTER_WINNT, 0);
     3619    int rc = RTDirOpenFiltered(&pPluginDir, pszPluginFilter, RTDIRFILTER_WINNT, 0);
    35763620    if (RT_FAILURE(rc))
    35773621    {
     
    35913635    while ((rc = RTDirReadEx(pPluginDir, pPluginDirEntry, &cbPluginDirEntry, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK)) != VERR_NO_MORE_FILES)
    35923636    {
    3593         RTLDRMOD hPlugin = NIL_RTLDRMOD;
    35943637        char *pszPluginPath = NULL;
    35953638
     
    36173660
    36183661        /* Prepend the path to the libraries. */
    3619         pszPluginPath = RTPathJoinA(szPath, pPluginDirEntry->szName);
     3662        pszPluginPath = RTPathJoinA(pszPath, pPluginDirEntry->szName);
    36203663        if (!pszPluginPath)
    36213664        {
     
    36243667        }
    36253668
    3626         rc = SUPR3HardenedLdrLoadPlugIn(pszPluginPath, &hPlugin, NULL);
    3627         if (RT_SUCCESS(rc))
    3628         {
    3629             VDBACKENDREGISTER BackendRegister;
    3630             PFNVDPLUGINLOAD pfnVDPluginLoad = NULL;
    3631 
    3632             BackendRegister.pfnRegisterImage  = vdPluginRegisterImage;
    3633             BackendRegister.pfnRegisterCache  = vdPluginRegisterCache;
    3634             BackendRegister.pfnRegisterFilter = vdPluginRegisterFilter;
    3635 
    3636             rc = RTLdrGetSymbol(hPlugin, VD_PLUGIN_LOAD_NAME, (void**)&pfnVDPluginLoad);
    3637             if (RT_FAILURE(rc) || !pfnVDPluginLoad)
    3638             {
    3639                 LogFunc(("error resolving the entry point %s in plugin %s, rc=%Rrc, pfnVDPluginLoad=%#p\n",
    3640                          VD_PLUGIN_LOAD_NAME, pPluginDirEntry->szName, rc, pfnVDPluginLoad));
    3641                 if (RT_SUCCESS(rc))
    3642                     rc = VERR_SYMBOL_NOT_FOUND;
    3643             }
    3644 
    3645             if (RT_SUCCESS(rc))
    3646             {
    3647                 /* Get the function table. */
    3648                 rc = pfnVDPluginLoad(NULL, &BackendRegister);
    3649             }
    3650             else
    3651                 LogFunc(("ignored plugin '%s': rc=%Rrc\n", pszPluginPath, rc));
    3652 
    3653             /* Create a plugin entry on success. */
    3654             if (RT_SUCCESS(rc))
    3655                 vdAddPlugin(hPlugin);
    3656             else
    3657                 RTLdrClose(hPlugin);
    3658         }
     3669        rc = vdPluginLoadFromFilename(pszPluginPath);
    36593670        RTStrFree(pszPluginPath);
    36603671    }
     
    36683679        RTDirClose(pPluginDir);
    36693680    return rc;
     3681#else
     3682    return VERR_NOT_IMPLEMENTED;
     3683#endif
     3684}
     3685
     3686/**
     3687 * internal: scans plugin directory and loads found plugins.
     3688 */
     3689static int vdLoadDynamicBackends()
     3690{
     3691#ifndef VBOX_HDD_NO_DYNAMIC_BACKENDS
     3692    /*
     3693     * Enumerate plugin backends from the application directory where the other
     3694     * shared libraries are.
     3695     */
     3696    char szPath[RTPATH_MAX];
     3697    int rc = RTPathAppPrivateArch(szPath, sizeof(szPath));
     3698    if (RT_FAILURE(rc))
     3699        return rc;
     3700
     3701    return vdPluginLoadFromPath(szPath);
    36703702#else
    36713703    return VINF_SUCCESS;
     
    53565388}
    53575389
     5390/**
     5391 * Loads a single plugin given by filename.
     5392 *
     5393 * @returns VBox status code.
     5394 * @param   pszFilename     The plugin filename to load.
     5395 */
     5396VBOXDDU_DECL(int) VDPluginLoadFromFilename(const char *pszFilename)
     5397{
     5398    if (!g_apBackends)
     5399    {
     5400        int rc = VDInit();
     5401        if (RT_FAILURE(rc))
     5402            return rc;
     5403    }
     5404
     5405    return vdPluginLoadFromFilename(pszFilename);
     5406}
     5407
     5408/**
     5409 * Load all plugins from a given path.
     5410 *
     5411 * @returns VBox statuse code.
     5412 * @param   pszPath         The path to load plugins from.
     5413 */
     5414VBOXDDU_DECL(int) VDPluginLoadFromPath(const char *pszPath)
     5415{
     5416    if (!g_apBackends)
     5417    {
     5418        int rc = VDInit();
     5419        if (RT_FAILURE(rc))
     5420            return rc;
     5421    }
     5422
     5423    return vdPluginLoadFromPath(pszPath);
     5424}
    53585425
    53595426/**
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