VirtualBox

Changeset 93575 in vbox for trunk/src/VBox/Main/src-server


Ignore:
Timestamp:
Feb 3, 2022 12:16:48 PM (3 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
149710
Message:

Main/Unattended: The image version is inside the WINDOWS element, not directly under IMAGE. Pick up SPBUILD and combine them all into a single version string. Be stricter with the image index parsing (via getAttributeValue override). Catch alloc exceptions. bugref:9781

File:
1 edited

Legend:

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

    r93571 r93575  
    193193Utf8Str WIMImage::getNameAndVersion() const
    194194{
    195     Utf8Str strNameAndVersion(mName);
    196     /* Append the major version number if it is not empty. */
    197     if (mVersionMajor.isEmpty())
    198         return strNameAndVersion;
    199     strNameAndVersion.appendPrintfNoThrow(" %s", mVersionMajor.c_str());
    200     /* Same for the minor version number and build number. */
    201     if (mVersionMinor.isEmpty())
    202         return strNameAndVersion;
    203     strNameAndVersion.appendPrintfNoThrow("-%s", mVersionMinor.c_str());
    204     if (mVersionBuild.isEmpty())
    205         return strNameAndVersion;
    206     strNameAndVersion.appendPrintfNoThrow("-%s", mVersionBuild.c_str());
    207     return strNameAndVersion;
    208 }
     195    if (mVersion.isEmpty())
     196        return mName;
     197    return Utf8StrFmt("%s (%s)", mName.c_str(), mVersion.c_str());
     198}
     199
    209200
    210201//////////////////////////////////////////////////////////////////////////////////////////////////////
     
    305296 *        more, replace E_NOTIMPL with E_FAIL. */
    306297
     298    /*
     299     * Reset output state before we start
     300     */
     301    mStrDetectedOSTypeId.setNull();
     302    mStrDetectedOSVersion.setNull();
     303    mStrDetectedOSFlavor.setNull();
     304    mDetectedOSLanguages.clear();
     305    mStrDetectedOSHints.setNull();
     306    mDetectedImages.clear();
    307307
    308308    /*
     
    432432 *     <MINOR>0</MINOR>
    433433 *     <BUILD>19041</BUILD>
    434  *     ......
     434 *     <SPBUILD>1</SPBUILD>
    435435 * </VERSION>
    436436 * @endverbatim
     
    440440static void parseVersionElement(const xml::ElementNode *pNode, WIMImage &image)
    441441{
    442     /* Major part. */
    443     const ElementNode *pMajorNode = pNode->findChildElement("MAJOR");
     442    /* Major part: */
     443    const xml::ElementNode *pMajorNode = pNode->findChildElement("MAJOR");
    444444    if (!pMajorNode)
    445445        pMajorNode = pNode->findChildElement("major");
     446    if (!pMajorNode)
     447        pMajorNode = pNode->findChildElement("Major");
    446448    if (pMajorNode)
    447         image.mVersionMajor = pMajorNode->getValue();
    448 
    449     /* Minor part. */
    450     const ElementNode *pMinorNode = pNode->findChildElement("MINOR");
    451     if (!pMinorNode)
    452         pMinorNode = pNode->findChildElement("minor");
    453     if (pMinorNode)
    454         image.mVersionMinor = pMinorNode->getValue();
    455 
    456     /* Build part. */
    457     const ElementNode *pBuildNode = pNode->findChildElement("BUILD");
    458     if (!pBuildNode)
    459         pBuildNode = pNode->findChildElement("build");
    460     if (pBuildNode)
    461         image.mVersionBuild = pBuildNode->getValue();
    462 }
    463 
     449    {
     450        const char * const pszMajor = pMajorNode->getValue();
     451        if (pszMajor && *pszMajor)
     452        {
     453            /* Minor part: */
     454            const ElementNode *pMinorNode = pNode->findChildElement("MINOR");
     455            if (!pMinorNode)
     456                pMinorNode = pNode->findChildElement("minor");
     457            if (!pMinorNode)
     458                pMinorNode = pNode->findChildElement("Minor");
     459            if (pMinorNode)
     460            {
     461                const char * const pszMinor = pMinorNode->getValue();
     462                if (pszMinor && *pszMinor)
     463                {
     464                    /* Build: */
     465                    const ElementNode *pBuildNode = pNode->findChildElement("BUILD");
     466                    if (!pBuildNode)
     467                        pBuildNode = pNode->findChildElement("build");
     468                    if (!pBuildNode)
     469                        pBuildNode = pNode->findChildElement("Build");
     470                    if (pBuildNode)
     471                    {
     472                        const char * const pszBuild = pBuildNode->getValue();
     473                        if (pszBuild && *pszBuild)
     474                        {
     475                            /* SPBuild: */
     476                            const ElementNode *pSpBuildNode = pNode->findChildElement("SPBUILD");
     477                            if (!pSpBuildNode)
     478                                pSpBuildNode = pNode->findChildElement("spbuild");
     479                            if (!pSpBuildNode)
     480                                pSpBuildNode = pNode->findChildElement("Spbuild");
     481                            if (!pSpBuildNode)
     482                                pSpBuildNode = pNode->findChildElement("SpBuild");
     483                            if (pSpBuildNode && pSpBuildNode->getValue() && *pSpBuildNode->getValue())
     484                                image.mVersion.printf("%s.%s.%s.%s", pszMajor, pszMinor, pszBuild, pSpBuildNode->getValue());
     485                            else
     486                                image.mVersion.printf("%s.%s.%s", pszMajor, pszMinor, pszBuild);
     487                        }
     488                    }
     489
     490                }
     491            }
     492        }
     493    }
     494}
    464495
    465496/**
     
    467498 * @verbatim
    468499 * <WIM>
    469  *     ....
     500 *     ...
    470501 *     <IMAGE INDEX="1">
    471  *     ....
    472  *     <DISPLAYNAME>Windows 10 Home</DISPLAYNAME>
    473  *     <VERSION>
    474  *         ....
    475  *     </VERSION>
     502 *         ...
     503 *         <DISPLAYNAME>Windows 10 Home</DISPLAYNAME>
     504 *         <WINDOWS>
     505 *             <VERSION>
     506 *                 ...
     507 *             </VERSION>
     508 *         </WINDOWS>
    476509 *     </IMAGE>
    477510 * </WIM>
     
    497530            continue;
    498531
    499         const char *pszIndex = pChild->findAttributeValue("INDEX");
    500         if (!pszIndex)
    501             pszIndex = pChild->findAttributeValue("index");
    502         if (!pszIndex)
    503             continue;
    504         uint32_t pu32 = 0;
    505         int vrc = RTStrToUInt32Full(pszIndex, 10 /* uBase */, &pu32);
    506 
    507         if (!RT_SUCCESS(vrc))
     532        WIMImage newImage;
     533
     534        if (   !pChild->getAttributeValue("INDEX", &newImage.mImageIndex)
     535            && !pChild->getAttributeValue("index", &newImage.mImageIndex)
     536            && !pChild->getAttributeValue("Index", &newImage.mImageIndex))
    508537            continue;
    509538
     
    513542        if (!pDisplayDescriptionNode)
    514543            continue;
    515         WIMImage newImage;
    516544        newImage.mName = pDisplayDescriptionNode->getValue();
    517545        if (newImage.mName.isEmpty())
    518546            continue;
    519547
    520         newImage.mImageIndex = pu32;
    521         const ElementNode *pVersionElement = pChild->findChildElement("VERSION");
    522         if (!pVersionElement)
    523             pVersionElement = pChild->findChildElement("version");
    524         if (pVersionElement)
    525             parseVersionElement(pVersionElement, newImage);
     548        const ElementNode *pElmWindows = pChild->findChildElement("WINDOWS");
     549        if (!pElmWindows)
     550            pElmWindows = pChild->findChildElement("windows");
     551        if (!pElmWindows)
     552            pElmWindows = pChild->findChildElement("Windows");
     553        if (pElmWindows)
     554        {
     555            const ElementNode *pVersionElement = pElmWindows->findChildElement("VERSION");
     556            if (!pVersionElement)
     557                pVersionElement = pChild->findChildElement("version");
     558            if (pVersionElement)
     559                parseVersionElement(pVersionElement, newImage);
     560        }
     561
    526562        imageList.append(newImage);
    527563    }
     
    577613            if (    (header.XmlData.bFlags & RESHDR_FLAGS_METADATA)
    578614                && !(header.XmlData.bFlags & RESHDR_FLAGS_COMPRESSED)
    579                 &&  header.XmlData.cbOrginal != 0
    580                 &&  header.XmlData.cbOrginal < _32M
    581                 &&  header.XmlData.cbOrginal == header.XmlData.cb)
     615                &&  header.XmlData.cbOriginal >= 32
     616                &&  header.XmlData.cbOriginal < _32M
     617                &&  header.XmlData.cbOriginal == header.XmlData.cb)
    582618            {
    583                 char *pXmlBuf = (char*)RTMemAlloc(header.XmlData.cbOrginal);
    584                 if (pXmlBuf)
    585                 {
    586                     vrc = RTVfsFileReadAt(hVfsFile, (RTFOFF)header.XmlData.off, pXmlBuf, (size_t)header.XmlData.cbOrginal, NULL);
     619                size_t const cbXmlData = (size_t)header.XmlData.cbOriginal;
     620                char *pachXmlBuf = (char *)RTMemTmpAlloc(cbXmlData);
     621                if (pachXmlBuf)
     622                {
     623                    vrc = RTVfsFileReadAt(hVfsFile, (RTFOFF)header.XmlData.off, pachXmlBuf, cbXmlData, NULL);
    587624                    if (RT_SUCCESS(vrc))
    588625                    {
     626                        LogRel2(("XML Data (%#zx bytes):\n%32.*Rhxd\n", cbXmlData, cbXmlData, pachXmlBuf));
     627
     628                        /* Parse the XML: */
    589629                        xml::Document doc;
    590630                        xml::XmlMemParser parser;
    591                         RTCString fileName = "dump";
    592631                        try
    593632                        {
    594                             parser.read(pXmlBuf, header.XmlData.cbOrginal, fileName, doc);
     633                            RTCString strFileName = "source/install.wim";
     634                            parser.read(pachXmlBuf, cbXmlData, strFileName, doc);
    595635                        }
    596636                        catch (xml::XmlError &rErr)
     
    598638                            LogRel(("Unattended: An error has occured during XML parsing: %s\n", rErr.what()));
    599639                            vrc = VERR_XAR_TOC_XML_PARSE_ERROR;
     640                        }
     641                        catch (std::bad_alloc &)
     642                        {
     643                            LogRel(("Unattended: std::bad_alloc\n"));
     644                            vrc = VERR_NO_MEMORY;
    600645                        }
    601646                        catch (...)
     
    606651                        if (RT_SUCCESS(vrc))
    607652                        {
     653                            /* Extract the information we need from the XML document: */
    608654                            xml::ElementNode *pElmRoot = doc.getRootElement();
    609655                            if (pElmRoot)
    610656                            {
    611                                 mDetectedImages.clear();
    612                                 parseWimXMLData(pElmRoot, mDetectedImages);
     657                                Assert(mDetectedImages.size() == 0);
     658                                try
     659                                {
     660                                    parseWimXMLData(pElmRoot, mDetectedImages);
     661                                }
     662                                catch (std::bad_alloc &)
     663                                {
     664                                    vrc = VERR_NO_MEMORY;
     665                                }
    613666                            }
    614667                            else
     
    618671                    else
    619672                        LogRel(("Unattended: Failed during reading XML Metadata out of install.wim\n"));
    620                     RTMemFree(pXmlBuf);
     673                    RTMemTmpFree(pachXmlBuf);
     674                }
     675                else
     676                {
     677                    LogRel(("Unattended: Failed to allocate %#zx bytes for XML Metadata\n", cbXmlData));
     678                    vrc = VERR_NO_TMP_MEMORY;
    621679                }
    622680            }
    623681            else
    624                 LogRel(("Unattended: XML Metadata of install.wim is either compressed, empty, or too big\n"));
     682                LogRel(("Unattended: XML Metadata of install.wim is either compressed, empty, or too big (bFlags=%#x cbOriginal=%#RX64 cb=%#RX64)\n",
     683                        header.XmlData.bFlags, header.XmlData.cbOriginal, header.XmlData.cb));
    625684        }
    626685        RTVfsFileRelease(hVfsFile);
     686
     687        /* Bail out if we ran out of memory here. */
     688        if (vrc == VERR_NO_MEMORY || vrc == VERR_NO_TMP_MEMORY)
     689            return setErrorBoth(E_OUTOFMEMORY, vrc, tr("Out of memory"));
    627690    }
    628691
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