Index: trunk/include/VBox/VBoxHDD-new.h
===================================================================
--- trunk/include/VBox/VBoxHDD-new.h	(revision 14851)
+++ trunk/include/VBox/VBoxHDD-new.h	(revision 14852)
@@ -1049,5 +1049,5 @@
 {
     /** Name of the backend. */
-    char *pszBackend;
+    const char *pszBackend;
     /** Capabilities of the backend (a combination of the VD_CAP_* flags). */
     uint64_t uBackendCaps;
@@ -1072,4 +1072,17 @@
 typedef VBOXHDD *PVBOXHDD;
 
+/**
+ * Initializes HDD backends.
+ *
+ * @returns VBox status code.
+ */
+VBOXDDU_DECL(int) VDInit();
+
+/**
+ * Destroys loaded HDD backends.
+ *
+ * @returns VBox status code.
+ */
+VBOXDDU_DECL(int) VDShutdown();
 
 /**
Index: trunk/src/VBox/Devices/Storage/RawHDDCore.cpp
===================================================================
--- trunk/src/VBox/Devices/Storage/RawHDDCore.cpp	(revision 14851)
+++ trunk/src/VBox/Devices/Storage/RawHDDCore.cpp	(revision 14852)
@@ -1090,4 +1090,6 @@
     /* paConfigInfo */
     NULL,
+    /* hPlugin */
+    NIL_RTLDRMOD,
     /* pfnCheckIfValid */
     rawCheckIfValid,
Index: trunk/src/VBox/Devices/Storage/VBoxHDD-new.cpp
===================================================================
--- trunk/src/VBox/Devices/Storage/VBoxHDD-new.cpp	(revision 14851)
+++ trunk/src/VBox/Devices/Storage/VBoxHDD-new.cpp	(revision 14852)
@@ -67,6 +67,4 @@
     unsigned        uOpenFlags;
 
-    /** Handle for the shared object / DLL. */
-    RTLDRMOD            hPlugin;
     /** Function pointers for the various backend methods. */
     PCVBOXHDDBACKEND    Backend;
@@ -129,16 +127,39 @@
 #endif
 
-static PCVBOXHDDBACKEND aBackends[] =
+static unsigned g_cBackends = 0;
+static PVBOXHDDBACKEND *g_apBackends = NULL;
+static PVBOXHDDBACKEND aStaticBackends[] =
 {
     &g_RawBackend,
     &g_VmdkBackend,
     &g_VDIBackend,
-    &g_VhdBackend,
+    &g_VhdBackend
 #ifdef VBOX_WITH_ISCSI
-    &g_ISCSIBackend,
+    ,&g_ISCSIBackend
 #endif
-    NULL
 };
 
+/**
+ * internal: add several backends.
+ */
+static int vdAddBackends(PVBOXHDDBACKEND *ppBackends, unsigned cBackends)
+{
+    PVBOXHDDBACKEND *pTmp = (PVBOXHDDBACKEND*)RTMemRealloc(g_apBackends,
+           (g_cBackends + cBackends) * sizeof(PVBOXHDDBACKEND));
+    if (RT_UNLIKELY(!pTmp))
+        return VERR_NO_MEMORY;
+    g_apBackends = pTmp;
+    memcpy(&g_apBackends[g_cBackends], ppBackends, cBackends * sizeof(PVBOXHDDBACKEND));
+    g_cBackends += cBackends;
+    return VINF_SUCCESS;
+}
+
+/**
+ * internal: add single backend.
+ */
+DECLINLINE(int) vdAddBackend(PVBOXHDDBACKEND pBackend)
+{
+    return vdAddBackends(&pBackend, 1);
+}
 
 /**
@@ -159,90 +180,21 @@
  * internal: find image format backend.
  */
-static int vdFindBackend(const char *pszBackend, PCVBOXHDDBACKEND *ppBackend,
-                         RTLDRMOD *phPlugin)
+static int vdFindBackend(const char *pszBackend, PCVBOXHDDBACKEND *ppBackend)
 {
     int rc = VINF_SUCCESS;
     PCVBOXHDDBACKEND pBackend = NULL;
-    RTLDRMOD hPlugin = NIL_RTLDRMOD;
-
-    for (unsigned i = 0; aBackends[i] != NULL; i++)
-    {
-        if (!strcmp(pszBackend, aBackends[i]->pszBackendName))
-        {
-            pBackend = aBackends[i];
+
+    if (!g_apBackends)
+        VDInit();
+
+    for (unsigned i = 0; i < g_cBackends; i++)
+    {
+        if (!strcmp(pszBackend, g_apBackends[i]->pszBackendName))
+        {
+            pBackend = g_apBackends[i];
             break;
         }
     }
-
-    /* If no static backend is found try loading a shared module with
-     * pszBackend as filename. */
-    if (!pBackend)
-    {
-        char szSharedLibPath[RTPATH_MAX];
-        char *pszPluginName;
-
-        rc = RTPathAppPrivateArch(szSharedLibPath, sizeof(szSharedLibPath));
-        if (RT_FAILURE(rc))
-            return rc;
-
-        /* HDD Format Plugins have VBoxHDD as prefix, prepend it. */
-        RTStrAPrintf(&pszPluginName, "%s/%s%s",
-                     szSharedLibPath, VBOX_HDDFORMAT_PLUGIN_PREFIX, pszBackend);
-        if (!pszPluginName)
-        {
-            rc = VERR_NO_MEMORY;
-            goto out;
-        }
-
-        /* Try to load the plugin (RTLdrLoad takes care of the suffix). */
-        rc = SUPR3HardenedLdrLoad(pszPluginName, &hPlugin);
-        if (RT_SUCCESS(rc))
-        {
-            PFNVBOXHDDFORMATLOAD pfnHDDFormatLoad;
-
-            rc = RTLdrGetSymbol(hPlugin, VBOX_HDDFORMAT_LOAD_NAME,
-                                (void**)&pfnHDDFormatLoad);
-            if (RT_FAILURE(rc) || !pfnHDDFormatLoad)
-            {
-                LogFunc(("error resolving the entry point %s in plugin %s, rc=%Rrc, pfnHDDFormat=%#p\n", VBOX_HDDFORMAT_LOAD_NAME, pszPluginName, rc, pfnHDDFormatLoad));
-                if (RT_SUCCESS(rc))
-                    rc = VERR_SYMBOL_NOT_FOUND;
-                goto out;
-            }
-
-            /* Get the function table. */
-            PVBOXHDDBACKEND pBE;
-            rc = pfnHDDFormatLoad(&pBE);
-            if (RT_FAILURE(rc))
-                goto out;
-            /* Check if the sizes match. If not this plugin is too old. */
-            if (pBE->cbSize != sizeof(VBOXHDDBACKEND))
-            {
-                rc = VERR_VDI_UNSUPPORTED_VERSION;
-                goto out;
-            }
-            pBackend = pBE;
-        }
-        else
-        {
-            /* If the backend plugin doesn't exist, don't treat this as an
-             * error. Just return the NULL pointers. */
-            rc = VINF_SUCCESS;
-        }
-
-        RTStrFree(pszPluginName);
-    }
-
-out:
-    if (RT_FAILURE(rc))
-    {
-        if (hPlugin != NIL_RTLDRMOD)
-            RTLdrClose(hPlugin);
-        hPlugin = NIL_RTLDRMOD;
-        pBackend = NULL;
-    }
-
     *ppBackend = pBackend;
-    *phPlugin = hPlugin;
     return rc;
 }
@@ -614,4 +566,159 @@
 
 /**
+ * internal: scans plugin directory and loads the backends have been found.
+ */
+static int vdLoadDynamicBackends()
+{
+    int rc = VINF_SUCCESS;
+    PRTDIR pPluginDir = NULL;
+
+    /* Enumerate plugin backends. */
+    char szPath[RTPATH_MAX];
+    rc = RTPathAppPrivateArch(szPath, sizeof(szPath));
+    if (RT_FAILURE(rc))
+        return rc;
+
+    /* To get all entries with VBoxHDD as prefix. */
+    char *pszPluginFilter;
+    rc = RTStrAPrintf(&pszPluginFilter, "%s/%s*", szPath,
+            VBOX_HDDFORMAT_PLUGIN_PREFIX);
+    if (RT_FAILURE(rc))
+    {
+        rc = VERR_NO_MEMORY;
+        return rc;
+    }
+
+    PRTDIRENTRYEX pPluginDirEntry = NULL;
+    size_t cbPluginDirEntry = sizeof(RTDIRENTRYEX);
+    /* The plugins are in the same directory as the other shared libs. */
+    rc = RTDirOpenFiltered(&pPluginDir, pszPluginFilter, RTDIRFILTER_WINNT);
+    if (RT_FAILURE(rc))
+    {
+        /* On Windows the above immediately signals that there are no
+         * files matching, while on other platforms enumerating the
+         * files below fails. Either way: no plugins. */
+        goto out;
+    }
+
+    pPluginDirEntry = (PRTDIRENTRYEX)RTMemAllocZ(sizeof(RTDIRENTRYEX));
+    if (!pPluginDirEntry)
+    {
+        rc = VERR_NO_MEMORY;
+        goto out;
+    }
+
+    while ((rc = RTDirReadEx(pPluginDir, pPluginDirEntry, &cbPluginDirEntry, RTFSOBJATTRADD_NOTHING)) != VERR_NO_MORE_FILES)
+    {
+        RTLDRMOD hPlugin = NIL_RTLDRMOD;
+        PFNVBOXHDDFORMATLOAD pfnHDDFormatLoad = NULL;
+        PVBOXHDDBACKEND pBackend = NULL;
+        char *pszPluginPath = NULL;
+
+        if (rc == VERR_BUFFER_OVERFLOW)
+        {
+            /* allocate new buffer. */
+            RTMemFree(pPluginDirEntry);
+            pPluginDirEntry = (PRTDIRENTRYEX)RTMemAllocZ(cbPluginDirEntry);
+            /* Retry. */
+            rc = RTDirReadEx(pPluginDir, pPluginDirEntry, &cbPluginDirEntry, RTFSOBJATTRADD_NOTHING);
+            if (RT_FAILURE(rc))
+                break;
+        }
+        else if (RT_FAILURE(rc))
+            break;
+
+        /* We got the new entry. */
+        if (!RTFS_IS_FILE(pPluginDirEntry->Info.Attr.fMode))
+            continue;
+
+        /* Prepend the path to the libraries. */
+        rc = RTStrAPrintf(&pszPluginPath, "%s/%s", szPath, pPluginDirEntry->szName);
+        if (RT_FAILURE(rc))
+        {
+            rc = VERR_NO_MEMORY;
+            break;
+        }
+
+        rc = SUPR3HardenedLdrLoad(pszPluginPath, &hPlugin);
+        if (RT_SUCCESS(rc))
+        {
+            rc = RTLdrGetSymbol(hPlugin, VBOX_HDDFORMAT_LOAD_NAME, (void**)&pfnHDDFormatLoad);
+            if (RT_FAILURE(rc) || !pfnHDDFormatLoad)
+            {
+                LogFunc(("error resolving the entry point %s in plugin %s, rc=%Rrc, pfnHDDFormat=%#p\n", VBOX_HDDFORMAT_LOAD_NAME, pPluginDirEntry->szName, rc, pfnHDDFormatLoad));
+                if (RT_SUCCESS(rc))
+                    rc = VERR_SYMBOL_NOT_FOUND;
+            }
+
+            if (RT_SUCCESS(rc))
+            {
+                /* Get the function table. */
+                rc = pfnHDDFormatLoad(&pBackend);
+                if (RT_SUCCESS(rc) && pBackend->cbSize == sizeof(VBOXHDDBACKEND))
+                {
+                    pBackend->hPlugin = hPlugin;
+                    vdAddBackend(pBackend);
+                }
+                else
+                    LogFunc(("ignored plugin '%s': pBackend->cbSize=%d rc=%Rrc\n", pszPluginPath, pBackend->cbSize, rc));
+            }
+            else
+                LogFunc(("ignored plugin '%s': rc=%Rrc\n", pszPluginPath, rc));
+
+            if (RT_FAILURE(rc))
+                RTLdrClose(hPlugin);
+        }
+        RTStrFree(pszPluginPath);
+    }
+out:
+    if (rc == VERR_NO_MORE_FILES)
+        rc = VINF_SUCCESS;
+    RTStrFree(pszPluginFilter);
+    if (pPluginDirEntry)
+        RTMemFree(pPluginDirEntry);
+    if (pPluginDir)
+        RTDirClose(pPluginDir);
+    return rc;
+}
+
+/**
+ * Initializes HDD backends.
+ *
+ * @returns VBox status code.
+ */
+VBOXDDU_DECL(int) VDInit()
+{
+    int rc = vdAddBackends(aStaticBackends, RT_ELEMENTS(aStaticBackends));
+    if (RT_SUCCESS(rc))
+        rc = vdLoadDynamicBackends();
+    LogRel(("VDInit finished\n"));
+    return rc;
+}
+
+/**
+ * Destroys loaded HDD backends.
+ *
+ * @returns VBox status code.
+ */
+VBOXDDU_DECL(int) VDShutdown()
+{
+    PVBOXHDDBACKEND *pBackends = g_apBackends;
+    unsigned cBackends = g_cBackends;
+
+    if (!pBackends)
+        return VERR_INTERNAL_ERROR;
+
+    g_cBackends = 0;
+    g_apBackends = NULL;
+
+    for (unsigned i = 0; i < cBackends; i++)
+        if (pBackends[i]->hPlugin != NIL_RTLDRMOD)
+            RTLdrClose(pBackends[i]->hPlugin);
+    return VINF_SUCCESS;
+}
+
+
+
+/**
  * Lists all HDD backends and their capabilities in a caller-provided buffer.
  *
@@ -633,191 +740,33 @@
 
     LogFlowFunc(("cEntriesAlloc=%u pEntries=%#p pcEntriesUsed=%#p\n", cEntriesAlloc, pEntries, pcEntriesUsed));
-    do
-    {
-        /* Check arguments. */
-        AssertMsgBreakStmt(cEntriesAlloc,
-                           ("cEntriesAlloc=%u\n", cEntriesAlloc),
-                           rc = VERR_INVALID_PARAMETER);
-        AssertMsgBreakStmt(VALID_PTR(pEntries),
-                           ("pEntries=%#p\n", pEntries),
-                           rc = VERR_INVALID_PARAMETER);
-        AssertMsgBreakStmt(VALID_PTR(pcEntriesUsed),
-                           ("pcEntriesUsed=%#p\n", pcEntriesUsed),
-                           rc = VERR_INVALID_PARAMETER);
-
-        /* First enumerate static backends. */
-        for (unsigned i = 0; aBackends[i] != NULL; i++)
-        {
-            char *pszName = RTStrDup(aBackends[i]->pszBackendName);
-            if (!pszName)
-            {
-                rc = VERR_NO_MEMORY;
-                break;
-            }
-            pEntries[cEntries].pszBackend = pszName;
-            pEntries[cEntries].uBackendCaps = aBackends[i]->uBackendCaps;
-            pEntries[cEntries].papszFileExtensions = aBackends[i]->papszFileExtensions;
-            pEntries[cEntries].paConfigInfo = aBackends[i]->paConfigInfo;
-            cEntries++;
-            if (cEntries >= cEntriesAlloc)
-            {
-                rc = VERR_BUFFER_OVERFLOW;
-                break;
-            }
-        }
-        if (RT_FAILURE(rc))
-            break;
-
-        /* Then enumerate plugin backends. */
-        char szPath[RTPATH_MAX];
-        rc = RTPathAppPrivateArch(szPath, sizeof(szPath));
-        if (RT_FAILURE(rc))
-            break;
-
-        /* To get all entries with VBoxHDD as prefix. */
-        char *pszPluginFilter;
-        rc = RTStrAPrintf(&pszPluginFilter, "%s/%s*", szPath,
-                          VBOX_HDDFORMAT_PLUGIN_PREFIX);
-        if (RT_FAILURE(rc))
-        {
-            rc = VERR_NO_MEMORY;
-            break;
-        }
-
-        /* The plugins are in the same directory as the other shared libs. */
-        rc = RTDirOpenFiltered(&pPluginDir, pszPluginFilter, RTDIRFILTER_WINNT);
-        if (RT_FAILURE(rc))
-        {
-            /* On Windows the above immediately signals that there are no
-             * files matching, while on other platforms enumerating the
-             * files below fails. Either way: no plugins. */
-            break;
-        }
-
-        PRTDIRENTRYEX pPluginDirEntry = NULL;
-        size_t cbPluginDirEntry = sizeof(RTDIRENTRY);
-        pPluginDirEntry = (PRTDIRENTRYEX)RTMemAllocZ(sizeof(RTDIRENTRY));
-        if (!pPluginDirEntry)
-        {
-            rc = VERR_NO_MEMORY;
-            break;
-        }
-
-        while ((rc = RTDirReadEx(pPluginDir, pPluginDirEntry, &cbPluginDirEntry, RTFSOBJATTRADD_NOTHING)) != VERR_NO_MORE_FILES)
-        {
-            RTLDRMOD hPlugin = NIL_RTLDRMOD;
-            PFNVBOXHDDFORMATLOAD pfnHDDFormatLoad = NULL;
-            PVBOXHDDBACKEND pBackend = NULL;
-            char *pszPluginPath = NULL;
-
-            if (rc == VERR_BUFFER_OVERFLOW)
-            {
-                /* allocate new buffer. */
-                RTMemFree(pPluginDirEntry);
-                pPluginDirEntry = (PRTDIRENTRYEX)RTMemAllocZ(cbPluginDirEntry);
-                /* Retry. */
-                rc = RTDirReadEx(pPluginDir, pPluginDirEntry, &cbPluginDirEntry, RTFSOBJATTRADD_NOTHING);
-                if (RT_FAILURE(rc))
-                    break;
-            }
-            else if (RT_FAILURE(rc))
-                break;
-
-            /* We got the new entry. */
-            if (!RTFS_IS_FILE(pPluginDirEntry->Info.Attr.fMode))
-                continue;
-
-            /* Prepend the path to the libraries. */
-            rc = RTStrAPrintf(&pszPluginPath, "%s/%s", szPath, pPluginDirEntry->szName);
-            if (RT_FAILURE(rc))
-            {
-                rc = VERR_NO_MEMORY;
-                break;
-            }
-
-            rc = SUPR3HardenedLdrLoad(pszPluginPath, &hPlugin);
-            if (RT_SUCCESS(rc))
-            {
-                rc = RTLdrGetSymbol(hPlugin, VBOX_HDDFORMAT_LOAD_NAME, (void**)&pfnHDDFormatLoad);
-                if (RT_FAILURE(rc) || !pfnHDDFormatLoad)
-                {
-                    LogFunc(("error resolving the entry point %s in plugin %s, rc=%Rrc, pfnHDDFormat=%#p\n", VBOX_HDDFORMAT_LOAD_NAME, pPluginDirEntry->szName, rc, pfnHDDFormatLoad));
-                    if (RT_SUCCESS(rc))
-                        rc = VERR_SYMBOL_NOT_FOUND;
-                }
-
-                if (RT_SUCCESS(rc))
-                {
-                    /* Get the function table. */
-                    rc = pfnHDDFormatLoad(&pBackend);
-                    if (RT_SUCCESS(rc) && pBackend->cbSize == sizeof(VBOXHDDBACKEND))
-                    {
-                        char *pszName = RTStrDup(pBackend->pszBackendName);
-                        if (!pszName)
-                        {
-                            rc = VERR_NO_MEMORY;
-                            break;
-                        }
-                        pEntries[cEntries].pszBackend = pszName;
-                        pEntries[cEntries].uBackendCaps = pBackend->uBackendCaps;
-                        unsigned cExts, iExt;
-                        for (cExts=0; pBackend->papszFileExtensions[cExts]; cExts++)
-                            ;
-                        const char **paExts = (const char **)RTMemAlloc((cExts+1) * sizeof(paExts[0])); /** @todo rainy day: fix leak on error. */
-                        if (!paExts)
-                        {
-                            rc = VERR_NO_MEMORY;
-                            break;
-                        }
-                        for (iExt=0; iExt < cExts; iExt++)
-                        {
-                            paExts[iExt] = (const char*)RTStrDup(pBackend->papszFileExtensions[iExt]);
-                            if (!paExts[iExt])
-                            {
-                                rc = VERR_NO_MEMORY;
-                                break;
-                            }
-                        }
-                        paExts[iExt] = NULL;
-                        pEntries[cEntries].papszFileExtensions = paExts;
-                        if (pBackend->paConfigInfo != NULL)
-                        {
-                            /* copy the whole config field! */
-                            rc = VERR_NOT_IMPLEMENTED;
-                            break;
-                        }
-                        pEntries[cEntries].paConfigInfo = NULL;
-                        cEntries++;
-                        if (cEntries >= cEntriesAlloc)
-                        {
-                            rc = VERR_BUFFER_OVERFLOW;
-                            break;
-                        }
-                    }
-                    else
-                        LogFunc(("ignored plugin '%s': pBackend->cbSize=%d rc=%Rrc\n", pszPluginPath, pBackend->cbSize, rc));
-                }
-                else
-                    LogFunc(("ignored plugin '%s': rc=%Rrc\n", pszPluginPath, rc));
-
-                RTLdrClose(hPlugin);
-            }
-            RTStrFree(pszPluginPath);
-        }
-        if (rc == VERR_NO_MORE_FILES)
-            rc = VINF_SUCCESS;
-        RTStrFree(pszPluginFilter);
-        if (pPluginDirEntry)
-            RTMemFree(pPluginDirEntry);
-        if (pPluginDir)
-            RTDirClose(pPluginDir);
-    } while (0);
-    /* Ignore any files which can't be found. Happens e.g. on Windows when
-     * absolutely no plugins are installed (see above). Totally harmless. */
-    if (rc == VERR_FILE_NOT_FOUND)
-        rc = VINF_SUCCESS;
+    /* Check arguments. */
+    AssertMsgReturn(cEntriesAlloc,
+                    ("cEntriesAlloc=%u\n", cEntriesAlloc),
+                    VERR_INVALID_PARAMETER);
+    AssertMsgReturn(VALID_PTR(pEntries),
+                    ("pEntries=%#p\n", pEntries),
+                    VERR_INVALID_PARAMETER);
+    AssertMsgReturn(VALID_PTR(pcEntriesUsed),
+                    ("pcEntriesUsed=%#p\n", pcEntriesUsed),
+                    VERR_INVALID_PARAMETER);
+    if (!g_apBackends)
+        VDInit();
+
+    if (cEntriesAlloc < g_cBackends)
+    {
+        *pcEntriesUsed = g_cBackends;
+        return VERR_BUFFER_OVERFLOW;
+    }
+
+     for (unsigned i = 0; i < g_cBackends; i++)
+     {
+         pEntries[i].pszBackend = g_apBackends[i]->pszBackendName;
+         pEntries[i].uBackendCaps = g_apBackends[i]->uBackendCaps;
+         pEntries[i].papszFileExtensions = g_apBackends[i]->papszFileExtensions;
+         pEntries[i].paConfigInfo = g_apBackends[i]->paConfigInfo;
+     }
 
     LogFlowFunc(("returns %Rrc *pcEntriesUsed=%u\n", rc, cEntries));
-    *pcEntriesUsed = cEntries;
+    *pcEntriesUsed = g_cBackends;
     return rc;
 }
@@ -833,5 +782,29 @@
 VBOXDDU_DECL(int) VDBackendInfoOne(const char *pszBackend, PVDBACKENDINFO pEntry)
 {
-    return VERR_NOT_IMPLEMENTED;
+    LogFlowFunc(("pszBackend=%#p pEntry=%#p\n", pszBackend, pEntry));
+    /* Check arguments. */
+    AssertMsgReturn(VALID_PTR(pszBackend),
+                    ("pszBackend=%#p\n", pszBackend),
+                    VERR_INVALID_PARAMETER);
+    AssertMsgReturn(VALID_PTR(pEntry),
+                    ("pEntry=%#p\n", pEntry),
+                    VERR_INVALID_PARAMETER);
+    if (!g_apBackends)
+        VDInit();
+
+    /* Go through loaded backends. */
+    for (unsigned i = 0; i < g_cBackends; i++)
+    {
+        if (!strcmp(pszBackend, g_apBackends[i]->pszBackendName))
+        {
+            pEntry->pszBackend = g_apBackends[i]->pszBackendName;
+            pEntry->uBackendCaps = g_apBackends[i]->uBackendCaps;
+            pEntry->papszFileExtensions = g_apBackends[i]->papszFileExtensions;
+            pEntry->paConfigInfo = g_apBackends[i]->paConfigInfo;
+            return VINF_SUCCESS;
+        }
+    }
+
+    return VERR_NOT_FOUND;
 }
 
@@ -924,175 +897,39 @@
 VBOXDDU_DECL(int) VDGetFormat(const char *pszFilename, char **ppszFormat)
 {
-    PRTDIR pPluginDir = NULL;
     int rc = VERR_NOT_SUPPORTED;
-    bool fPluginFound = false;
 
     LogFlowFunc(("pszFilename=\"%s\"\n", pszFilename));
-    do
-    {
-        /* Check arguments. */
-        AssertMsgBreakStmt(VALID_PTR(pszFilename) && *pszFilename,
-                           ("pszFilename=%#p \"%s\"\n", pszFilename, pszFilename),
-                           rc = VERR_INVALID_PARAMETER);
-        AssertMsgBreakStmt(VALID_PTR(ppszFormat),
-                           ("ppszFormat=%#p\n", ppszFormat),
-                           rc = VERR_INVALID_PARAMETER);
-
-        /* First check if static backends support this file format. */
-        for (unsigned i = 0; aBackends[i] != NULL; i++)
-        {
-            if (aBackends[i]->pfnCheckIfValid)
+    /* Check arguments. */
+    AssertMsgReturn(VALID_PTR(pszFilename) && *pszFilename,
+                    ("pszFilename=%#p \"%s\"\n", pszFilename, pszFilename),
+                    VERR_INVALID_PARAMETER);
+    AssertMsgReturn(VALID_PTR(ppszFormat),
+                    ("ppszFormat=%#p\n", ppszFormat),
+                    VERR_INVALID_PARAMETER);
+
+    if (!g_apBackends)
+        VDInit();
+
+    /* Find the backend supporting this file format. */
+    for (unsigned i = 0; i < g_cBackends; i++)
+    {
+        if (g_apBackends[i]->pfnCheckIfValid)
+        {
+            rc = g_apBackends[i]->pfnCheckIfValid(pszFilename);
+            if (RT_SUCCESS(rc))
             {
-                rc = aBackends[i]->pfnCheckIfValid(pszFilename);
-                if (RT_SUCCESS(rc))
+                /* Copy the name into the new string. */
+                char *pszFormat = RTStrDup(g_apBackends[i]->pszBackendName);
+                if (!pszFormat)
                 {
-                    fPluginFound = true;
-                    /* Copy the name into the new string. */
-                    char *pszFormat = RTStrDup(aBackends[i]->pszBackendName);
-                    if (!pszFormat)
-                    {
-                        rc = VERR_NO_MEMORY;
-                        break;
-                    }
-                    *ppszFormat = pszFormat;
+                    rc = VERR_NO_MEMORY;
                     break;
                 }
-            }
-        }
-        if (fPluginFound)
-            break;
-
-        /* Then check if plugin backends support this file format. */
-        char szPath[RTPATH_MAX];
-        rc = RTPathAppPrivateArch(szPath, sizeof(szPath));
-        if (RT_FAILURE(rc))
-            break;
-
-        /* To get all entries with VBoxHDD as prefix. */
-        char *pszPluginFilter;
-        rc = RTStrAPrintf(&pszPluginFilter, "%s/%s*", szPath,
-                          VBOX_HDDFORMAT_PLUGIN_PREFIX);
-        if (RT_FAILURE(rc))
-        {
-            rc = VERR_NO_MEMORY;
-            break;
-        }
-
-        /* The plugins are in the same directory as the other shared libs. */
-        rc = RTDirOpenFiltered(&pPluginDir, pszPluginFilter, RTDIRFILTER_WINNT);
-        if (RT_FAILURE(rc))
-        {
-            if (rc == VERR_FILE_NOT_FOUND)
-            {
-                /* VERR_FILE_NOT_FOUND would be interpreted as the hard
-                 * disk storage unit was not found, so replace with
-                 * VERR_NOT_SUPPORTED which is more meaningful in this case */
-                rc = VERR_NOT_SUPPORTED;
-            }
-            break;
-        }
-
-        PRTDIRENTRYEX pPluginDirEntry = NULL;
-        size_t cbPluginDirEntry = sizeof(RTDIRENTRY);
-        pPluginDirEntry = (PRTDIRENTRYEX)RTMemAllocZ(sizeof(RTDIRENTRY));
-        if (!pPluginDirEntry)
-        {
-            rc = VERR_NO_MEMORY;
-            break;
-        }
-
-        while ((rc = RTDirReadEx(pPluginDir, pPluginDirEntry, &cbPluginDirEntry, RTFSOBJATTRADD_NOTHING)) != VERR_NO_MORE_FILES)
-        {
-            RTLDRMOD hPlugin = NIL_RTLDRMOD;
-            PFNVBOXHDDFORMATLOAD pfnHDDFormatLoad = NULL;
-            PVBOXHDDBACKEND pBackend = NULL;
-            char *pszPluginPath = NULL;
-
-            if (rc == VERR_BUFFER_OVERFLOW)
-            {
-                /* allocate new buffer. */
-                RTMemFree(pPluginDirEntry);
-                pPluginDirEntry = (PRTDIRENTRYEX)RTMemAllocZ(cbPluginDirEntry);
-                /* Retry. */
-                rc = RTDirReadEx(pPluginDir, pPluginDirEntry, &cbPluginDirEntry, RTFSOBJATTRADD_NOTHING);
-                if (RT_FAILURE(rc))
-                    break;
-            }
-            else if (RT_FAILURE(rc))
-                break;
-
-            /* We got the new entry. */
-            if (!RTFS_IS_FILE(pPluginDirEntry->Info.Attr.fMode))
-                continue;
-
-            /* Prepend the path to the libraries. */
-            rc = RTStrAPrintf(&pszPluginPath, "%s/%s", szPath, pPluginDirEntry->szName);
-            if (RT_FAILURE(rc))
-            {
-                rc = VERR_NO_MEMORY;
+                *ppszFormat = pszFormat;
+                rc = VINF_SUCCESS;
                 break;
             }
-
-            rc = SUPR3HardenedLdrLoad(pszPluginPath, &hPlugin);
-            if (RT_SUCCESS(rc))
-            {
-                rc = RTLdrGetSymbol(hPlugin, VBOX_HDDFORMAT_LOAD_NAME, (void**)&pfnHDDFormatLoad);
-                if (RT_FAILURE(rc) || !pfnHDDFormatLoad)
-                {
-                    LogFunc(("error resolving the entry point %s in plugin %s, rc=%Rrc, pfnHDDFormat=%#p\n", VBOX_HDDFORMAT_LOAD_NAME, pPluginDirEntry->szName, rc, pfnHDDFormatLoad));
-                    if (RT_SUCCESS(rc))
-                        rc = VERR_SYMBOL_NOT_FOUND;
-                }
-
-                if (RT_SUCCESS(rc))
-                {
-                    /* Get the function table. */
-                    rc = pfnHDDFormatLoad(&pBackend);
-                    if (RT_SUCCESS(rc) && pBackend->cbSize == sizeof(VBOXHDDBACKEND))
-                    {
-
-                        /* Check if the plugin can handle this file. */
-                        rc = pBackend->pfnCheckIfValid(pszFilename);
-                        if (RT_SUCCESS(rc))
-                        {
-                            fPluginFound = true;
-                            rc = VINF_SUCCESS;
-
-                            /* Report the format name. */
-                            RTPathStripExt(pPluginDirEntry->szName);
-                            AssertBreakStmt(strlen(pPluginDirEntry->szName) > VBOX_HDDFORMAT_PLUGIN_PREFIX_LENGTH,
-                                            rc = VERR_INVALID_NAME);
-
-                            char *pszFormat = NULL;
-                            pszFormat = RTStrDup(pPluginDirEntry->szName + VBOX_HDDFORMAT_PLUGIN_PREFIX_LENGTH);
-                            if (!pszFormat)
-                                rc = VERR_NO_MEMORY;
-
-                            *ppszFormat = pszFormat;
-                        }
-                    }
-                }
-                else
-                    pBackend = NULL;
-
-                RTLdrClose(hPlugin);
-            }
-            RTStrFree(pszPluginPath);
-
-            /*
-             * We take the first plugin which can handle this file.
-             */
-            if (fPluginFound)
-                break;
-        }
-        if (rc == VERR_NO_MORE_FILES)
-            rc = VERR_NOT_SUPPORTED;
-
-        RTStrFree(pszPluginFilter);
-        if (pPluginDirEntry)
-            RTMemFree(pPluginDirEntry);
-        if (pPluginDir)
-            RTDirClose(pPluginDir);
-    } while (0);
+        }
+    }
 
     LogFlowFunc(("returns %Rrc *ppszFormat=\"%s\"\n", rc, *ppszFormat));
@@ -1161,5 +998,5 @@
         pImage->pVDIfsImage = pVDIfsImage;
 
-        rc = vdFindBackend(pszBackend, &pImage->Backend, &pImage->hPlugin);
+        rc = vdFindBackend(pszBackend, &pImage->Backend);
         if (RT_FAILURE(rc))
             break;
@@ -1313,7 +1150,4 @@
         if (pImage)
         {
-            if (pImage->hPlugin != NIL_RTLDRMOD)
-                RTLdrClose(pImage->hPlugin);
-
             if (pImage->pszFilename)
                 RTStrFree(pImage->pszFilename);
@@ -1439,5 +1273,5 @@
         pImage->pVDIfsImage = pVDIfsImage;
 
-        rc = vdFindBackend(pszBackend, &pImage->Backend, &pImage->hPlugin);
+        rc = vdFindBackend(pszBackend, &pImage->Backend);
         if (RT_FAILURE(rc))
             break;
@@ -1546,7 +1380,4 @@
         if (pImage)
         {
-            if (pImage->hPlugin != NIL_RTLDRMOD)
-                RTLdrClose(pImage->hPlugin);
-
             if (pImage->pszFilename)
                 RTStrFree(pImage->pszFilename);
@@ -1641,5 +1472,5 @@
         }
 
-        rc = vdFindBackend(pszBackend, &pImage->Backend, &pImage->hPlugin);
+        rc = vdFindBackend(pszBackend, &pImage->Backend);
         if (RT_FAILURE(rc))
             break;
@@ -1739,7 +1570,4 @@
     if (RT_FAILURE(rc))
     {
-        if (pImage->hPlugin != NIL_RTLDRMOD)
-            RTLdrClose(pImage->hPlugin);
-
         if (pImage)
         {
@@ -2103,7 +1931,4 @@
             pImageFrom->pvBackendData = NULL;
 
-            if (pImageFrom->hPlugin != NIL_RTLDRMOD)
-                RTLdrClose(pImageFrom->hPlugin);
-
             if (pImageFrom->pszFilename)
                 RTStrFree(pImageFrom->pszFilename);
@@ -2230,7 +2055,4 @@
 
             /* Free remaining resources. */
-            if (pImageFrom->hPlugin != NIL_RTLDRMOD)
-                RTLdrClose(pImageFrom->hPlugin);
-
             if (pImageFrom->pszFilename)
                 RTStrFree(pImageFrom->pszFilename);
@@ -2251,7 +2073,4 @@
 
         /* Free remaining resources. */
-        if (pImageTo->hPlugin != NIL_RTLDRMOD)
-            RTLdrClose(pImageTo->hPlugin);
-
         if (pImageTo->pszFilename)
             RTStrFree(pImageTo->pszFilename);
@@ -2307,9 +2126,4 @@
         rc = pImage->Backend->pfnClose(pImage->pvBackendData, fDelete);
         /* Free remaining resources related to the image. */
-        if (pImage->hPlugin != NIL_RTLDRMOD)
-        {
-            RTLdrClose(pImage->hPlugin);
-            pImage->hPlugin = NIL_RTLDRMOD;
-        }
         RTStrFree(pImage->pszFilename);
         RTMemFree(pImage);
@@ -2401,9 +2215,4 @@
                 rc = rc2;
             /* Free remaining resources related to the image. */
-            if (pImage->hPlugin != NIL_RTLDRMOD)
-            {
-                RTLdrClose(pImage->hPlugin);
-                pImage->hPlugin = NIL_RTLDRMOD;
-            }
             RTStrFree(pImage->pszFilename);
             RTMemFree(pImage);
Index: trunk/src/VBox/Devices/Storage/VBoxHDD-newInternal.h
===================================================================
--- trunk/src/VBox/Devices/Storage/VBoxHDD-newInternal.h	(revision 14851)
+++ trunk/src/VBox/Devices/Storage/VBoxHDD-newInternal.h	(revision 14852)
@@ -70,4 +70,9 @@
      */
     PCVDCONFIGINFO paConfigInfo;
+
+    /**
+     * Handle of loaded plugin library, NIL_RTLDRMOD for static backends.
+     */
+    RTLDRMOD hPlugin;
 
     /**
Index: trunk/src/VBox/Devices/Storage/VDIHDDCore.cpp
===================================================================
--- trunk/src/VBox/Devices/Storage/VDIHDDCore.cpp	(revision 14851)
+++ trunk/src/VBox/Devices/Storage/VDIHDDCore.cpp	(revision 14852)
@@ -1869,4 +1869,6 @@
     /* paConfigInfo */
     NULL,
+    /* hPlugin */
+    NIL_RTLDRMOD,
     /* pfnCheckIfValid */
     vdiCheckIfValid,
Index: trunk/src/VBox/Devices/Storage/VHDHDDCore.cpp
===================================================================
--- trunk/src/VBox/Devices/Storage/VHDHDDCore.cpp	(revision 14851)
+++ trunk/src/VBox/Devices/Storage/VHDHDDCore.cpp	(revision 14852)
@@ -1868,4 +1868,6 @@
     /* paConfigInfo */
     NULL,
+    /* hPlugin */
+    NIL_RTLDRMOD,
     /* pfnCheckIfValid */
     vhdCheckIfValid,
Index: trunk/src/VBox/Devices/Storage/VmdkHDDCore.cpp
===================================================================
--- trunk/src/VBox/Devices/Storage/VmdkHDDCore.cpp	(revision 14851)
+++ trunk/src/VBox/Devices/Storage/VmdkHDDCore.cpp	(revision 14852)
@@ -5317,4 +5317,6 @@
     /* paConfigInfo */
     NULL,
+    /* hPlugin */
+    NIL_RTLDRMOD,
     /* pfnCheckIfValid */
     vmdkCheckIfValid,
Index: trunk/src/VBox/Main/VirtualBoxImpl.cpp
===================================================================
--- trunk/src/VBox/Main/VirtualBoxImpl.cpp	(revision 14851)
+++ trunk/src/VBox/Main/VirtualBoxImpl.cpp	(revision 14852)
@@ -489,4 +489,6 @@
 # error "Port me!"
 #endif
+    /* Unload plugin backends. */
+    VDShutdown();
 
     LogFlowThisFuncLeave();
