VirtualBox

Ignore:
Timestamp:
Jul 4, 2018 7:42:18 PM (6 years ago)
Author:
vboxsync
Message:

ApplianceImpl.cpp: Replaced the supportedStandardsURI std::map by a more C-ish construct that doesn't leak memory nor introduces any race conditions during initialization and works correctly after an init failure.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-server/ApplianceImpl.cpp

    r72899 r72900  
    4141*   Global Variables                                                                                                             *
    4242*********************************************************************************************************************************/
    43 static const char * const g_pszISOURI = "http://www.ecma-international.org/publications/standards/Ecma-119.htm";
    44 static const char * const g_pszVMDKStreamURI = "http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized";
    45 static const char * const g_pszVMDKSparseURI = "http://www.vmware.com/specifications/vmdk.html#sparse";
    46 static const char * const g_pszVMDKCompressedURI = "http://www.vmware.com/specifications/vmdk.html#compressed";
    47 static const char * const g_pszVMDKCompressedURI2 = "http://www.vmware.com/interfaces/specifications/vmdk.html#compressed";
    48 static const char * const g_pszrVHDURI = "http://go.microsoft.com/fwlink/?LinkId=137171";
     43static const char * const   g_pszISOURI             = "http://www.ecma-international.org/publications/standards/Ecma-119.htm";
     44static const char * const   g_pszVMDKStreamURI      = "http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized";
     45static const char * const   g_pszVMDKSparseURI      = "http://www.vmware.com/specifications/vmdk.html#sparse";
     46static const char * const   g_pszVMDKCompressedURI  = "http://www.vmware.com/specifications/vmdk.html#compressed";
     47static const char * const   g_pszVMDKCompressedURI2 = "http://www.vmware.com/interfaces/specifications/vmdk.html#compressed";
     48static const char * const   g_pszrVHDURI            = "http://go.microsoft.com/fwlink/?LinkId=137171";
     49static char                 g_szIsoBackend[128];
     50static char                 g_szVmdkBackend[128];
     51static char                 g_szVhdBackend[128];
     52/** Set after the g_szXxxxBackend variables has been initialized. */
     53static bool volatile        g_fInitializedBackendNames = false;
     54
     55static struct
     56{
     57    const char *pszUri, *pszBackend;
     58} const g_aUriToBackend[] =
     59{
     60    { g_pszISOURI,              g_szIsoBackend },
     61    { g_pszVMDKStreamURI,       g_szVmdkBackend },
     62    { g_pszVMDKSparseURI,       g_szVmdkBackend },
     63    { g_pszVMDKCompressedURI,   g_szVmdkBackend },
     64    { g_pszVMDKCompressedURI2,  g_szVmdkBackend },
     65    { g_pszrVHDURI,             g_szVhdBackend },
     66};
    4967
    5068static std::map<Utf8Str, Utf8Str> supportedStandardsURI;
    5169
    52 static const struct
     70static struct
    5371{
    5472    ovf::CIMOSType_T    cim;
    5573    VBOXOSTYPE          osType;
    56 } g_aOsTypes[] =
     74} const g_aOsTypes[] =
    5775{
    5876    { ovf::CIMOSType_CIMOS_Unknown,                              VBOXOSTYPE_Unknown },
     
    394412 * Appliance COM initializer.
    395413 * @param   aVirtualBox     The VirtualBox object.
    396  * @return
    397414 */
    398415HRESULT Appliance::init(VirtualBox *aVirtualBox)
     
    411428    AssertReturn(m->m_pSecretKeyStore, E_FAIL);
    412429
    413     rc = i_initSetOfSupportedStandardsURI();
     430    rc = i_initBackendNames();
    414431
    415432    /* Confirm a successful initialization */
     
    421438/**
    422439 * Appliance COM uninitializer.
    423  * @return
    424440 */
    425441void Appliance::uninit()
     
    445461/**
    446462 * Public method implementation.
    447  * @param   aPath
    448  * @return
    449463 */
    450464HRESULT Appliance::getPath(com::Utf8Str &aPath)
     
    462476/**
    463477 * Public method implementation.
    464  * @param aDisks
    465  * @return
    466478 */
    467479HRESULT Appliance::getDisks(std::vector<com::Utf8Str> &aDisks)
     
    684696////////////////////////////////////////////////////////////////////////////////
    685697
    686 HRESULT Appliance::i_initSetOfSupportedStandardsURI()
    687 {
    688     HRESULT rc = S_OK;
    689     if (!supportedStandardsURI.empty())
    690         return rc;
    691 
    692     /* Get the system properties. */
    693     SystemProperties *pSysProps = mVirtualBox->i_getSystemProperties();
    694     {
    695         ComObjPtr<MediumFormat> trgFormat = pSysProps->i_mediumFormatFromExtension("iso");
    696         if (trgFormat.isNull())
    697             return setError(E_FAIL, tr("Can't find appropriate medium format for ISO type of a virtual disk."));
    698 
    699         Bstr bstrFormatName;
    700         rc = trgFormat->COMGETTER(Name)(bstrFormatName.asOutParam());
    701         if (FAILED(rc)) return rc;
    702 
    703         Utf8Str strTrgFormat = Utf8Str(bstrFormatName);
    704 
    705         supportedStandardsURI.insert(std::make_pair(Utf8Str(g_pszISOURI), strTrgFormat));
    706     }
    707 
    708     {
    709         ComObjPtr<MediumFormat> trgFormat = pSysProps->i_mediumFormatFromExtension("vmdk");
    710         if (trgFormat.isNull())
    711             return setError(E_FAIL, tr("Can't find appropriate medium format for VMDK type of a virtual disk."));
    712 
    713         Bstr bstrFormatName;
    714         rc = trgFormat->COMGETTER(Name)(bstrFormatName.asOutParam());
    715         if (FAILED(rc)) return rc;
    716 
    717         Utf8Str strTrgFormat = Utf8Str(bstrFormatName);
    718 
    719         supportedStandardsURI.insert(std::make_pair(Utf8Str(g_pszVMDKStreamURI), strTrgFormat));
    720         supportedStandardsURI.insert(std::make_pair(Utf8Str(g_pszVMDKSparseURI), strTrgFormat));
    721         supportedStandardsURI.insert(std::make_pair(Utf8Str(g_pszVMDKCompressedURI), strTrgFormat));
    722         supportedStandardsURI.insert(std::make_pair(Utf8Str(g_pszVMDKCompressedURI2), strTrgFormat));
    723     }
    724 
    725     {
    726         ComObjPtr<MediumFormat> trgFormat = pSysProps->i_mediumFormatFromExtension("vhd");
    727         if (trgFormat.isNull())
    728             return setError(E_FAIL, tr("Can't find appropriate medium format for VHD type of a virtual disk."));
    729 
    730         Bstr bstrFormatName;
    731         rc = trgFormat->COMGETTER(Name)(bstrFormatName.asOutParam());
    732         if (FAILED(rc)) return rc;
    733 
    734         Utf8Str strTrgFormat = Utf8Str(bstrFormatName);
    735 
    736         supportedStandardsURI.insert(std::make_pair(Utf8Str(g_pszrVHDURI), strTrgFormat));
    737     }
    738 
    739     return rc;
     698HRESULT Appliance::i_initBackendNames()
     699{
     700    HRESULT hrc = S_OK;
     701    if (!g_fInitializedBackendNames)
     702    {
     703        /*
     704         * Use the system properties to translate file extensions into
     705         * storage backend names.
     706         */
     707        static struct
     708        {
     709            const char *pszExt;         /**< extension */
     710            char       *pszBackendName;
     711            size_t      cbBackendName;
     712        } const s_aFormats[] =
     713        {
     714            { "iso",   g_szIsoBackend,  sizeof(g_szIsoBackend)  },
     715            { "vmdk",  g_szVmdkBackend, sizeof(g_szVmdkBackend) },
     716            { "vhd",   g_szVhdBackend,  sizeof(g_szVhdBackend)  },
     717        };
     718        SystemProperties *pSysProps = mVirtualBox->i_getSystemProperties();
     719        for (unsigned i = 0; i < RT_ELEMENTS(s_aFormats); i++)
     720        {
     721            ComObjPtr<MediumFormat> trgFormat = pSysProps->i_mediumFormatFromExtension(s_aFormats[i].pszExt);
     722            if (trgFormat.isNotNull())
     723            {
     724                const char *pszName = trgFormat->i_getName().c_str();
     725                int vrc = RTStrCopy(s_aFormats[i].pszBackendName, s_aFormats[i].cbBackendName, pszName);
     726                AssertRCStmt(vrc, hrc = setError(E_FAIL, "Unexpected storage backend name copy error %Rrc for %s.", vrc, pszName));
     727            }
     728            else
     729                hrc = setError(E_FAIL, tr("Can't find appropriate medium format for ISO type of a virtual disk."));
     730        }
     731
     732        if (SUCCEEDED(hrc))
     733            g_fInitializedBackendNames = true;
     734    }
     735
     736    return hrc;
    740737}
    741738
    742739Utf8Str Appliance::i_typeOfVirtualDiskFormatFromURI(Utf8Str uri) const
    743740{
    744     Utf8Str type;
    745     std::map<Utf8Str, Utf8Str>::const_iterator cit = supportedStandardsURI.find(uri);
    746     if (cit != supportedStandardsURI.end())
    747     {
    748         type = cit->second;
    749     }
    750 
    751     return type;
     741    Assert(g_fInitializedBackendNames);
     742
     743    unsigned i = RT_ELEMENTS(g_aUriToBackend);
     744    while (i-- > 0)
     745        if (RTStrICmp(g_aUriToBackend[i].pszUri, uri.c_str()) == 0)
     746            return Utf8Str(g_aUriToBackend[i].pszBackend);
     747    return Utf8Str();
    752748}
    753749
    754750std::set<Utf8Str> Appliance::i_URIFromTypeOfVirtualDiskFormat(Utf8Str type)
    755751{
    756     std::set<Utf8Str> uri;
    757     std::map<Utf8Str, Utf8Str>::const_iterator cit = supportedStandardsURI.begin();
    758     while(cit != supportedStandardsURI.end())
    759     {
    760         if (cit->second.compare(type,Utf8Str::CaseInsensitive) == 0)
    761             uri.insert(cit->first);
    762         ++cit;
    763     }
    764 
    765     return uri;
     752    Assert(g_fInitializedBackendNames);
     753
     754    std::set<Utf8Str> UriSet;
     755    unsigned i = RT_ELEMENTS(g_aUriToBackend);
     756    while (i-- > 0)
     757        if (RTStrICmp(g_aUriToBackend[i].pszBackend, type.c_str()) == 0)
     758            UriSet.insert(g_aUriToBackend[i].pszUri);
     759    return UriSet;
    766760}
    767761
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