ovfreader.cpp revision 78154219d9cb1688acdcbfbfa80c30f69ee26205
6c6531128b39093daeac902a8705c0bdf15b31ccvboxsync * OVF reader declarations.
6c6531128b39093daeac902a8705c0bdf15b31ccvboxsync * Depends only on IPRT, including the RTCString and IPRT XML classes.
c58f1213e628a545081c70e26c6b67a841cff880vboxsync * Copyright (C) 2008-2012 Oracle Corporation
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * available from http://www.virtualbox.org. This file is free software;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * you can redistribute it and/or modify it under the terms of the GNU
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * General Public License (GPL) as published by the Free Software
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsyncusing namespace std;
d5bf937d132098565e18a0d1fc408fb777c5e5b6vboxsyncusing namespace ovf;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync////////////////////////////////////////////////////////////////////////////////
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync// OVF reader implementation
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync////////////////////////////////////////////////////////////////////////////////
9986f9bfdcb0055fdb79bbd158f4912ccc3a5751vboxsync * Constructor. This parses the given XML file out of the memory. Throws lots of exceptions
9986f9bfdcb0055fdb79bbd158f4912ccc3a5751vboxsync * on XML or OVF invalidity.
9986f9bfdcb0055fdb79bbd158f4912ccc3a5751vboxsync * @param pvBuf the memory buffer to parse
9986f9bfdcb0055fdb79bbd158f4912ccc3a5751vboxsync * @param cbSize the size of the memory buffer
9986f9bfdcb0055fdb79bbd158f4912ccc3a5751vboxsync * @param path path to a filename for error messages.
6c6531128b39093daeac902a8705c0bdf15b31ccvboxsyncOVFReader::OVFReader(const void *pvBuf, size_t cbSize, const RTCString &path)
9986f9bfdcb0055fdb79bbd158f4912ccc3a5751vboxsync /* Start the parsing */
f7c0f913c4c22ee18059ff97055442566d0f14a1vboxsync * Constructor. This opens the given XML file and parses it. Throws lots of exceptions
f7c0f913c4c22ee18059ff97055442566d0f14a1vboxsync * on XML or OVF invalidity.
f7c0f913c4c22ee18059ff97055442566d0f14a1vboxsync * @param path
9986f9bfdcb0055fdb79bbd158f4912ccc3a5751vboxsync /* Start the parsing */
f7c0f913c4c22ee18059ff97055442566d0f14a1vboxsync const xml::ElementNode *pRootElem = m_doc.getRootElement();
da0cd3ee12f6b9c0e86f2aea3213cba6869b6647vboxsync if (!pRootElem || strcmp(pRootElem->getName(), "Envelope"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync throw OVFLogicError(N_("Root element in OVF file must be \"Envelope\"."));
da0cd3ee12f6b9c0e86f2aea3213cba6869b6647vboxsync throw OVFLogicError(N_("Error reading namespace URI in 'Envelope' element, line %d"), pRootElem->getLineNumber());
da0cd3ee12f6b9c0e86f2aea3213cba6869b6647vboxsync if (strncmp(ovf::OVF20_URI_string, pcszNamespaceURI.c_str(), pcszNamespaceURI.length()) == 0)
da0cd3ee12f6b9c0e86f2aea3213cba6869b6647vboxsync else if (strncmp(OVF10_URI_string, pcszNamespaceURI.c_str(), pcszNamespaceURI.length()) == 0)
62c8fef246519d59ee7ad41dd71de75b96b3552bvboxsync if ((pTypeAttr = pRootElem->findAttribute("xml:lang")))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // OVF has the following rough layout:
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync -- <References> .... files referenced from other parts of the file, such as VMDK images
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync -- Metadata, comprised of several section commands
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync -- virtual machines, either a single <VirtualSystem>, or a <VirtualSystemCollection>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync -- optionally <Strings> for localization
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // get all "File" child elements of "References" section so we can look up files easily;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // first find the "References" sections so we can look up files
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync xml::ElementNodesList listFileElements; // receives all /Envelope/References/File nodes
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if ((pReferencesElem = pRootElem->findChildElement("References")))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync pReferencesElem->getChildElements(listFileElements, "File");
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // now go though the sections
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * Private helper method that goes thru the elements of the given "current" element in the OVF XML
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * and handles the contained child elements (which can be "Section" or "Content" elements).
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * @param pcszPath Path spec of the XML file, for error messages.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * @param pReferencesElement "References" element from OVF, for looking up file specifications; can be NULL if no such element is present.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * @param pCurElem Element whose children are to be analyzed here.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsyncvoid OVFReader::LoopThruSections(const xml::ElementNode *pReferencesElem,
32c16cab49ef1ab1aea3b3340fbc133b99ee8b20vboxsync if ( ((pTypeAttr = pElem->findAttribute("xsi:type")))
32c16cab49ef1ab1aea3b3340fbc133b99ee8b20vboxsync else if ( (!strcmp(pcszElemName, "NetworkSection"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync && (!strcmp(pcszTypeAttr, "ovf:NetworkSection_Type"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if ( (!strcmp(pcszElemName, "DeploymentOptionSection")))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // child of VirtualSystemCollection -- TODO
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if ( (!strcmp(pcszElemName, "ResourceAllocationSection")))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // child of VirtualSystemCollection -- TODO
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if ( (!strcmp(pcszElemName, "StartupSection")))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // child of VirtualSystemCollection -- TODO
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync && (!strcmp(pcszTypeAttr, "ovf:VirtualSystem_Type"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if ( (!strcmp(pcszElemName, "VirtualSystemCollection"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync && (!strcmp(pcszTypeAttr, "ovf:VirtualSystemCollection_Type"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // TODO ResourceAllocationSection
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // recurse for this, since it has VirtualSystem elements as children
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * Private helper method that handles disk sections in the OVF XML.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * Gets called indirectly from IAppliance::read().
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * @param pcszPath Path spec of the XML file, for error messages.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * @param pReferencesElement "References" element from OVF, for looking up file specifications; can be NULL if no such element is present.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * @param pSectionElem Section element for which this helper is getting called.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsyncvoid OVFReader::HandleDiskSection(const xml::ElementNode *pReferencesElem,
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // contains "Disk" child elements
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if (!(pelmDisk->getAttributeValue("diskId", pcszDiskId)))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if (!(pelmDisk->getAttributeValue("format", pcszFormat)))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if (!(pelmDisk->getAttributeValue("capacity", d.iCapacity)))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if (!(pelmDisk->getAttributeValue("populatedSize", d.iPopulatedSize)))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // optional
2c1d8cd8efdd4c486ff681135035d24111b03af8vboxsync // optional vbox:uuid attribute (if OVF was exported by VirtualBox != 3.2)
2c1d8cd8efdd4c486ff681135035d24111b03af8vboxsync pelmDisk->getAttributeValue("vbox:uuid", d.uuidVbox);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if (pelmDisk->getAttributeValue("fileRef", pcszFileRef)) // optional
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // look up corresponding /References/File nodes (list built above)
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync && ((pFileElem = pReferencesElem->findChildElementFromId(pcszFileRef)))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // copy remaining values from file node then
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync const char *pcszHref;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if (!(pFileElem->getAttributeValue("href", pcszHref)))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if (!(pFileElem->getAttributeValue("size", d.iSize)))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // if (!(pFileElem->getAttributeValue("size", d.iChunkSize))) TODO
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if (pFileElem->getAttributeValue("compression", pcszCompression))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync throw OVFLogicError(N_("Error reading \"%s\": missing or invalid attribute '%s' in 'File' element, line %d"),
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync throw OVFLogicError(N_("Error reading \"%s\": cannot find References/File element for ID '%s' referenced by 'Disk' element, line %d"),
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync throw OVFLogicError(N_("Error reading \"%s\": missing or invalid attribute '%s' in 'DiskSection' element, line %d"),
2c1d8cd8efdd4c486ff681135035d24111b03af8vboxsync // suggest a size in megabytes to help callers with progress reports
2c1d8cd8efdd4c486ff681135035d24111b03af8vboxsync d.ulSuggestedSizeMB = 10000; // assume 10 GB, this is for the progress bar only anyway
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * Private helper method that handles network sections in the OVF XML.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * Gets called indirectly from IAppliance::read().
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * @param pcszPath Path spec of the XML file, for error messages.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * @param pSectionElem Section element for which this helper is getting called.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsyncvoid OVFReader::HandleNetworkSection(const xml::ElementNode * /* pSectionElem */)
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // we ignore network sections for now
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync// xml::NodesLoop loopNetworks(*pSectionElem, "Network");
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync// const xml::Node *pelmNetwork;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync// while ((pelmNetwork = loopNetworks.forAllNodes()))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync// Network n;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync// if (!(pelmNetwork->getAttributeValue("name", n.strNetworkName)))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync// return setError(VBOX_E_FILE_ERROR,
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync// tr("Error reading \"%s\": missing 'name' attribute in 'Network', line %d"),
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync// pcszPath,
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync// pelmNetwork->getLineNumber());
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync// m->mapNetworks[n.strNetworkName] = n;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * Private helper method that handles a "VirtualSystem" element in the OVF XML.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * Gets called indirectly from IAppliance::read().
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * @param pcszPath
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * @param pContentElem
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsyncvoid OVFReader::HandleVirtualSystemContent(const xml::ElementNode *pelmVirtualSystem)
f7c0f913c4c22ee18059ff97055442566d0f14a1vboxsync // peek under the <VirtualSystem> node whether we have a <vbox:Machine> node;
f7c0f913c4c22ee18059ff97055442566d0f14a1vboxsync // that case case, the caller can completely ignore the OVF but only load the VBox machine XML
f7c0f913c4c22ee18059ff97055442566d0f14a1vboxsync vsys.pelmVboxMachine = pelmVirtualSystem->findChildElement("vbox", "Machine");
f7c0f913c4c22ee18059ff97055442566d0f14a1vboxsync // now look for real OVF
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync const xml::AttributeNode *pIdAttr = pelmVirtualSystem->findAttribute("id");
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync xml::NodesLoop loop(*pelmVirtualSystem); // all child elements
885b661364d7f51d087003dccaccb6d24610f654vboxsync if (!strcmp(pcszElemName, "Section")) // OVF 0.9 used "Section" element always with a varying "type" attribute
885b661364d7f51d087003dccaccb6d24610f654vboxsync if ( ((pTypeAttr = pelmThis->findAttribute("type")))
885b661364d7f51d087003dccaccb6d24610f654vboxsync || ((pTypeAttr = pelmThis->findAttribute("xsi:type")))
885b661364d7f51d087003dccaccb6d24610f654vboxsync throw OVFLogicError(N_("Error reading \"%s\": element \"Section\" has no \"type\" attribute, line %d"),
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* <EulaSection>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <Info ovf:msgid="6">License agreement for the Virtual System.</Info>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <License ovf:msgid="1">License terms can go in here.</License>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync </EulaSection> */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if ((pelmLicense = pelmThis->findChildElement("License")))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync || (!strcmp(pcszTypeAttr, "ovf:ProductSection_Type"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* <Section ovf:required="false" xsi:type="ovf:ProductSection_Type">
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <Info>Meta-information about the installed software</Info>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <Product>VAtest</Product>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <Vendor>SUN Microsystems</Vendor>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <Version>10.0</Version>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <ProductUrl>http://blogs.sun.com/VirtualGuru</ProductUrl>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <VendorUrl>http://www.sun.com</VendorUrl>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync </Section> */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if ((pelmProduct = pelmThis->findChildElement("Product")))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if ((pelmVendor = pelmThis->findChildElement("Vendor")))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if ((pelmVersion = pelmThis->findChildElement("Version")))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if ((pelmProductUrl = pelmThis->findChildElement("ProductUrl")))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if ((pelmVendorUrl = pelmThis->findChildElement("VendorUrl")))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if ( (!strcmp(pcszElemName, "VirtualHardwareSection"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync || (!strcmp(pcszTypeAttr, "ovf:VirtualHardwareSection_Type"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync const xml::ElementNode *pelmSystem, *pelmVirtualSystemType;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if ((pelmSystem = pelmThis->findChildElement("System")))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* <System>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <vssd:Description>Description of the virtual hardware section.</vssd:Description>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <vssd:ElementName>vmware</vssd:ElementName>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <vssd:InstanceID>1</vssd:InstanceID>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <vssd:VirtualSystemIdentifier>MyLampService</vssd:VirtualSystemIdentifier>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <vssd:VirtualSystemType>vmx-4</vssd:VirtualSystemType>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync </System>*/
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if ((pelmVirtualSystemType = pelmSystem->findChildElement("VirtualSystemType")))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync vsys.strVirtualSystemType = pelmVirtualSystemType->getValue();
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync xml::NodesLoop loopVirtualHardwareItems(*pelmThis, "Item"); // all "Item" child elements
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync while ((pelmItem = loopVirtualHardwareItems.forAllNodes()))
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync throw OVFLogicError(N_("Error reading \"%s\": \"%s\""),
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync xml::NodesLoop loopVirtualHardwareItems(*pelmThis, "StorageItem");// all "StorageItem" child elements
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync while ((pelmItem = loopVirtualHardwareItems.forAllNodes()))
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync throw OVFLogicError(N_("Error reading \"%s\": \"%s\""),
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync xml::NodesLoop loopVirtualHardwareItems(*pelmThis, "EthernetPortItem");// all "EthernetPortItem" child elements
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync while ((pelmItem = loopVirtualHardwareItems.forAllNodes()))
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync throw OVFLogicError(N_("Error reading \"%s\": \"%s\""),
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync HardDiskController *pPrimaryIDEController = NULL;// will be set once found
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // now go thru all hardware items and handle them according to their type;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // in this first loop we handle all items _except_ hard disk images,
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // which we'll handle in a second loop below
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // do some analysis
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* <rasd:Caption>1 virtual CPU</rasd:Caption>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:Description>Number of virtual CPUs</rasd:Description>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:ElementName>virtual CPU</rasd:ElementName>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:InstanceID>1</rasd:InstanceID>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:ResourceType>3</rasd:ResourceType>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:VirtualQuantity>1</rasd:VirtualQuantity>*/
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync throw OVFLogicError(N_("Error reading \"%s\": CPU count %RI64 is larger than %d, line %d"),
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if ( (i.strAllocationUnits == "MegaBytes") // found in OVF created by OVF toolkit
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync || (i.strAllocationUnits == "MB") // found in MS docs
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync || (i.strAllocationUnits == "byte * 2^20") // suggested by OVF spec DSP0243 page 21
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync vsys.ullMemorySize = i.ullVirtualQuantity * 1024 * 1024;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync throw OVFLogicError(N_("Error reading \"%s\": Invalid allocation unit \"%s\" specified with memory size item, line %d"),
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:Caption>ideController0</rasd:Caption>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:Description>IDE Controller</rasd:Description>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:InstanceId>5</rasd:InstanceId>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:ResourceType>5</rasd:ResourceType>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:Address>0</rasd:Address>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:BusNumber>0</rasd:BusNumber>
15760030457c4d8548d42a9d543646b27eae7040vboxsync // this is the first IDE controller found: then mark it as "primary"
15760030457c4d8548d42a9d543646b27eae7040vboxsync // this is the second IDE controller found: If VMware exports two
15760030457c4d8548d42a9d543646b27eae7040vboxsync // IDE controllers, it seems that they are given an "Address" of 0
15760030457c4d8548d42a9d543646b27eae7040vboxsync // an 1, respectively, so assume address=0 means primary controller
15760030457c4d8548d42a9d543646b27eae7040vboxsync // then we really can't tell, just hope for the best
15760030457c4d8548d42a9d543646b27eae7040vboxsync pPrimaryIDEController = &vsys.mapControllers[i.ulInstanceID];
d5bf937d132098565e18a0d1fc408fb777c5e5b6vboxsync case ResourceType_ParallelSCSIHBA: // 6 SCSI controller
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:Caption>SCSI Controller 0 - LSI Logic</rasd:Caption>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:Description>SCI Controller</rasd:Description>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:ElementName>SCSI controller</rasd:ElementName>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:InstanceID>4</rasd:InstanceID>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:ResourceSubType>LsiLogic</rasd:ResourceSubType>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:ResourceType>6</rasd:ResourceType>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:Caption>Ethernet adapter on 'Bridged'</rasd:Caption>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:Connection>Bridged</rasd:Connection>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:InstanceID>6</rasd:InstanceID>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:ResourceType>10</rasd:ResourceType>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:ResourceSubType>E1000</rasd:ResourceSubType>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync OVF spec DSP 0243 page 21:
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync "For an Ethernet adapter, this specifies the abstract network connection name
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync for the virtual machine. All Ethernet adapters that specify the same abstract
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync network connection name within an OVF package shall be deployed on the same
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync network. The abstract network connection name shall be listed in the NetworkSection
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync at the outermost envelope level." */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // only store the name
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync vsys.fHasFloppyDrive = true; // we have no additional information
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* <Item ovf:required="false">
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:Caption>cdrom1</rasd:Caption>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:InstanceId>7</rasd:InstanceId>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:ResourceType>15</rasd:ResourceType>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:Parent>5</rasd:Parent>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:AddressOnParent>0</rasd:AddressOnParent>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // I tried to see what happens if I set an ISO for the CD-ROM in VMware Workstation,
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // but then the ovftool dies with "Device backing not supported". So I guess if
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // VMware can't export ISOs, then we don't need to be able to import them right now.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync vsys.fHasCdromDrive = true; // we have no additional information
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // handled separately in second loop below
d5bf937d132098565e18a0d1fc408fb777c5e5b6vboxsync case ResourceType_OtherStorageDevice: // 20 SATA controller
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:Description>SATA Controller</rasd:Description>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:Caption>sataController0</rasd:Caption>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:InstanceID>4</rasd:InstanceID>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:ResourceType>20</rasd:ResourceType>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:ResourceSubType>AHCI</rasd:ResourceSubType>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:Address>0</rasd:Address>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:BusNumber>0</rasd:BusNumber>
6c6531128b39093daeac902a8705c0bdf15b31ccvboxsync if ( i.strCaption.startsWith("sataController", RTCString::CaseInsensitive)
6c6531128b39093daeac902a8705c0bdf15b31ccvboxsync && !i.strResourceSubType.compare("AHCI", RTCString::CaseInsensitive)
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync throw OVFLogicError(N_("Error reading \"%s\": Host resource of type \"Other Storage Device (%d)\" is supported with SATA AHCI controllers only, line %d"),
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* <Item ovf:required="false">
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:Caption>usb</rasd:Caption>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:Description>USB Controller</rasd:Description>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:InstanceId>3</rasd:InstanceId>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:ResourceType>23</rasd:ResourceType>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:Address>0</rasd:Address>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:BusNumber>0</rasd:BusNumber>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync vsys.fHasUsbController = true; // we have no additional information
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* <Item ovf:required="false">
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:Caption>sound</rasd:Caption>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:Description>Sound Card</rasd:Description>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:InstanceId>10</rasd:InstanceId>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:ResourceType>35</rasd:ResourceType>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:ResourceSubType>ensoniq1371</rasd:ResourceSubType>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:AddressOnParent>3</rasd:AddressOnParent>
385c5fb9bdc175ef2d5dc340f1016b231acfe23cvboxsync /* If this unknown resource type isn't required, we simply skip it. */
385c5fb9bdc175ef2d5dc340f1016b231acfe23cvboxsync throw OVFLogicError(N_("Error reading \"%s\": Unknown resource type %d in hardware item, line %d"),
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync } // end switch
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // now run through the items for a second time, but handle only
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // hard disk images; otherwise the code would fail if a hard
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // disk image appears in the OVF before its hard disk controller
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // do some analysis
5a90348de5b2dd39c2258d19dabd69369a0f9999vboxsync /* <Item ovf:required="false">
5a90348de5b2dd39c2258d19dabd69369a0f9999vboxsync <rasd:Caption>cdrom1</rasd:Caption>
5a90348de5b2dd39c2258d19dabd69369a0f9999vboxsync <rasd:InstanceId>7</rasd:InstanceId>
5a90348de5b2dd39c2258d19dabd69369a0f9999vboxsync <rasd:ResourceType>15</rasd:ResourceType>
5a90348de5b2dd39c2258d19dabd69369a0f9999vboxsync <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>
5a90348de5b2dd39c2258d19dabd69369a0f9999vboxsync <rasd:Parent>5</rasd:Parent>
5a90348de5b2dd39c2258d19dabd69369a0f9999vboxsync <rasd:AddressOnParent>0</rasd:AddressOnParent>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:Caption>Harddisk 1</rasd:Caption>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:Description>HD</rasd:Description>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:ElementName>Hard Disk</rasd:ElementName>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:HostResource>ovf://disk/lamp</rasd:HostResource>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:InstanceID>5</rasd:InstanceID>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:Parent>4</rasd:Parent>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync <rasd:ResourceType>17</rasd:ResourceType>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // look up the hard disk controller element whose InstanceID equals our Parent;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // this is how the connection is specified in OVF
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync ControllersMap::const_iterator it = vsys.mapControllers.find(i.ulParent);
1b7486b51fc3d0e625fab9db6d46ee0113911adevboxsync throw OVFLogicError(N_("Error reading \"%s\": Disk item with instance ID %d specifies invalid parent %d, line %d"),
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // 123456789012345
0a6257a55820e2433e68420ff1a1ad89c398ce28vboxsync else if (i.strHostResource.startsWith("ovf:/disk/"))
5a90348de5b2dd39c2258d19dabd69369a0f9999vboxsync //the error may be missed for CD, because CD can be empty
5a90348de5b2dd39c2258d19dabd69369a0f9999vboxsync if ((vd.strDiskId.isEmpty() || (m_mapDisks.find(vd.strDiskId) == m_mapDisks.end()))
1b7486b51fc3d0e625fab9db6d46ee0113911adevboxsync throw OVFLogicError(N_("Error reading \"%s\": Disk item with instance ID %d specifies invalid host resource \"%s\", line %d"),
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if ( (!strcmp(pcszElemName, "OperatingSystemSection"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync || (!strcmp(pcszTypeAttr, "ovf:OperatingSystemSection_Type"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync throw OVFLogicError(N_("Error reading \"%s\": missing or invalid 'ovf:id' attribute in operating system section element, line %d"),
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if ((pelmCIMOSDescription = pelmThis->findChildElement("Description")))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync vsys.strCimosDesc = pelmCIMOSDescription->getValue();
cafbe3edf3ba3d13bad27f9570b0b57c18f3c57fvboxsync if ((pelmVBoxOSType = pelmThis->findChildElement("vbox", // namespace
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if ( (!strcmp(pcszElemName, "AnnotationSection"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync || (!strcmp(pcszTypeAttr, "ovf:AnnotationSection_Type"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if ((pelmAnnotation = pelmThis->findChildElement("Annotation")))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // now create the virtual system
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsyncvoid VirtualHardwareItem::fillItem(const xml::ElementNode *item)
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync xml::NodesLoop loopItemChildren(*item);// all child elements
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync while ((pelmItemChild = loopItemChildren.forAllNodes()))
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync const char *pcszItemChildName = pelmItemChild->getName();
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync else if (!strcmp(pcszItemChildName, "ElementName"))
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync else if ((!strcmp(pcszItemChildName, "InstanceID"))
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync else if (!strcmp(pcszItemChildName, "HostResource"))
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync else if (!strcmp(pcszItemChildName, "ResourceType"))
78154219d9cb1688acdcbfbfa80c30f69ee26205vboxsync if (item->getAttributeValue("required", pcszAttValue))
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync else if (!strcmp(pcszItemChildName, "OtherResourceType"))
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync else if (!strcmp(pcszItemChildName, "ResourceSubType"))
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync else if (!strcmp(pcszItemChildName, "AutomaticAllocation"))
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync fAutomaticAllocation = (!strcmp(pelmItemChild->getValue(), "true")) ? true : false;
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync else if (!strcmp(pcszItemChildName, "AutomaticDeallocation"))
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync fAutomaticDeallocation = (!strcmp(pelmItemChild->getValue(), "true")) ? true : false;
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync else if (!strcmp(pcszItemChildName, "AddressOnParent"))
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync else if (!strcmp(pcszItemChildName, "AllocationUnits"))
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync else if (!strcmp(pcszItemChildName, "VirtualQuantity"))
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync else if (!strcmp(pcszItemChildName, "Reservation"))
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync else if (!strcmp(pcszItemChildName, "ConsumerVisibility"))
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync else if (!strcmp(pcszItemChildName, "MappingBehavior"))
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync// else if (pelmItemChild->getPrefix() == NULL
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync// || strcmp(pelmItemChild->getPrefix(), "vmw"))
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync// throw OVFLogicError(N_("Unknown element \"%s\" under Item element, line %d"),
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync// pcszItemChildName,
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync// ulLineNumber);
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsyncvoid VirtualHardwareItem::_checkConsistencyAndCompliance() throw (OVFLogicError)
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync throw OVFLogicError(N_("Element InstanceID is absent under %s element, line %d. "
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync "see DMTF Schema Documentation %s"),
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync throw OVFLogicError(N_("Empty element ResourceType under %s element, line %d. "
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync "see DMTF Schema Documentation %s"),
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsyncvoid StorageItem::fillItem(const xml::ElementNode *item)
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync xml::NodesLoop loopItemChildren(*item);// all child elements
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync while ((pelmItemChild = loopItemChildren.forAllNodes()))
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync const char *pcszItemChildName = pelmItemChild->getName();
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync else if (!strcmp(pcszItemChildName, "OtherHostExtentNameFormat"))
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync strOtherHostExtentNameFormat = pelmItemChild->getValue();
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync else if (!strcmp(pcszItemChildName, "OtherHostExtentNameNamespace"))
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync strOtherHostExtentNameNamespace = pelmItemChild->getValue();
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync else if (!strcmp(pcszItemChildName, "VirtualQuantityUnits"))
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync strVirtualQuantityUnits = pelmItemChild->getValue();
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync else if (!strcmp(pcszItemChildName, "HostExtentNameFormat"))
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync else if (!strcmp(pcszItemChildName, "HostExtentNameNamespace"))
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync else if (!strcmp(pcszItemChildName, "HostExtentStartingAddress"))
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync else if (!strcmp(pcszItemChildName, "HostResourceBlockSize"))
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync else if (!strcmp(pcszItemChildName, "Reservation"))
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync else if (!strcmp(pcszItemChildName, "VirtualQuantity"))
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync else if (!strcmp(pcszItemChildName, "VirtualResourceBlockSize"))
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsyncvoid StorageItem::_checkConsistencyAndCompliance() throw (OVFLogicError)
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync VirtualHardwareItem::_checkConsistencyAndCompliance();
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync //throw OVFLogicError(N_("Access type is unknown under %s element, line %d"),
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync // name.c_str(), ulLineNumber);
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync throw OVFLogicError(N_("Element HostResourceBlockSize is absent under %s element, line %d. "
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync "see DMTF Schema Documentation %s"),
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync if (virtualResourceBlockSize <= 0 && virtualQuantity > 0)
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync throw OVFLogicError(N_("Element VirtualResourceBlockSize is absent under %s element, line %d. "
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync "see DMTF Schema Documentation %s"),
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync if (virtualQuantity > 0 && strVirtualQuantityUnits.isEmpty())
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync throw OVFLogicError(N_("Element VirtualQuantityUnits is absent under %s element, line %d. "
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync "see DMTF Schema Documentation %s"),
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync strVirtualQuantityUnits.compare(RTCString("count"), RTCString::CaseInsensitive) == 0
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync throw OVFLogicError(N_("Element VirtualQuantityUnits is set to \"count\" "
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync "while VirtualResourceBlockSize is set to 1. "
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync "under %s element, line %d. "
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync "It's needed to change on \"byte\". "
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync "see DMTF Schema Documentation %s"),
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsyncvoid EthernetPortItem::fillItem(const xml::ElementNode *item)
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync xml::NodesLoop loopItemChildren(*item);// all child elements
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync while ((pelmItemChild = loopItemChildren.forAllNodes()))
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsyncvoid EthernetPortItem::_checkConsistencyAndCompliance() throw (OVFLogicError)
37e4655312fa6433c756cfa05a4db6b72e0c4344vboxsync VirtualHardwareItem::_checkConsistencyAndCompliance();
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync////////////////////////////////////////////////////////////////////////////////
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync////////////////////////////////////////////////////////////////////////////////
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsyncOVFLogicError::OVFLogicError(const char *aFormat, ...)