ovfreader.cpp revision 0a6257a55820e2433e68420ff1a1ad89c398ce28
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync/* $Id$ */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync/** @file
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync *
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * OVF reader declarations. Depends only on IPRT, including the iprt::MiniString
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * and IPRT XML classes.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync/*
e64031e20c39650a7bc902a3e1aba613b9415deevboxsync * Copyright (C) 2008-2009 Oracle Corporation
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync *
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.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync#include "ovfreader.h"
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsyncusing namespace std;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsyncusing namespace iprt;
d5bf937d132098565e18a0d1fc408fb777c5e5b6vboxsyncusing namespace ovf;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync////////////////////////////////////////////////////////////////////////////////
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync//
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync// OVF reader implementation
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync//
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync////////////////////////////////////////////////////////////////////////////////
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
9986f9bfdcb0055fdb79bbd158f4912ccc3a5751vboxsync/**
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.
9986f9bfdcb0055fdb79bbd158f4912ccc3a5751vboxsync */
af4bc422c52b9d0db8d26e06d842fecc340a9f12vboxsyncOVFReader::OVFReader(const void *pvBuf, size_t cbSize, const MiniString &path)
9986f9bfdcb0055fdb79bbd158f4912ccc3a5751vboxsync : m_strPath(path)
9986f9bfdcb0055fdb79bbd158f4912ccc3a5751vboxsync{
9986f9bfdcb0055fdb79bbd158f4912ccc3a5751vboxsync xml::XmlMemParser parser;
9986f9bfdcb0055fdb79bbd158f4912ccc3a5751vboxsync parser.read(pvBuf, cbSize,
9986f9bfdcb0055fdb79bbd158f4912ccc3a5751vboxsync m_strPath,
9986f9bfdcb0055fdb79bbd158f4912ccc3a5751vboxsync m_doc);
9986f9bfdcb0055fdb79bbd158f4912ccc3a5751vboxsync /* Start the parsing */
9986f9bfdcb0055fdb79bbd158f4912ccc3a5751vboxsync parse();
9986f9bfdcb0055fdb79bbd158f4912ccc3a5751vboxsync}
9986f9bfdcb0055fdb79bbd158f4912ccc3a5751vboxsync
f7c0f913c4c22ee18059ff97055442566d0f14a1vboxsync/**
f7c0f913c4c22ee18059ff97055442566d0f14a1vboxsync * Constructor. This opens the given XML file and parses it. Throws lots of exceptions
f7c0f913c4c22ee18059ff97055442566d0f14a1vboxsync * on XML or OVF invalidity.
f7c0f913c4c22ee18059ff97055442566d0f14a1vboxsync * @param path
f7c0f913c4c22ee18059ff97055442566d0f14a1vboxsync */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsyncOVFReader::OVFReader(const MiniString &path)
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync : m_strPath(path)
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync{
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync xml::XmlFileParser parser;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync parser.read(m_strPath,
f7c0f913c4c22ee18059ff97055442566d0f14a1vboxsync m_doc);
9986f9bfdcb0055fdb79bbd158f4912ccc3a5751vboxsync /* Start the parsing */
9986f9bfdcb0055fdb79bbd158f4912ccc3a5751vboxsync parse();
9986f9bfdcb0055fdb79bbd158f4912ccc3a5751vboxsync}
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
9986f9bfdcb0055fdb79bbd158f4912ccc3a5751vboxsyncvoid OVFReader::parse()
9986f9bfdcb0055fdb79bbd158f4912ccc3a5751vboxsync{
f7c0f913c4c22ee18059ff97055442566d0f14a1vboxsync const xml::ElementNode *pRootElem = m_doc.getRootElement();
f7c0f913c4c22ee18059ff97055442566d0f14a1vboxsync if ( !pRootElem
f7c0f913c4c22ee18059ff97055442566d0f14a1vboxsync || strcmp(pRootElem->getName(), "Envelope")
f7c0f913c4c22ee18059ff97055442566d0f14a1vboxsync )
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync throw OVFLogicError(N_("Root element in OVF file must be \"Envelope\"."));
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // OVF has the following rough layout:
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /*
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 */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
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 const xml::ElementNode *pReferencesElem;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if ((pReferencesElem = pRootElem->findChildElement("References")))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync pReferencesElem->getChildElements(listFileElements, "File");
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // now go though the sections
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync LoopThruSections(pReferencesElem, pRootElem);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync}
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync/**
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 *
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.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * @return
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsyncvoid OVFReader::LoopThruSections(const xml::ElementNode *pReferencesElem,
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync const xml::ElementNode *pCurElem)
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync{
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync xml::NodesLoop loopChildren(*pCurElem);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync const xml::ElementNode *pElem;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync while ((pElem = loopChildren.forAllNodes()))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync {
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync const char *pcszElemName = pElem->getName();
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync const char *pcszTypeAttr = "";
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync const xml::AttributeNode *pTypeAttr;
32c16cab49ef1ab1aea3b3340fbc133b99ee8b20vboxsync if ( ((pTypeAttr = pElem->findAttribute("xsi:type")))
32c16cab49ef1ab1aea3b3340fbc133b99ee8b20vboxsync || ((pTypeAttr = pElem->findAttribute("type")))
32c16cab49ef1ab1aea3b3340fbc133b99ee8b20vboxsync )
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync pcszTypeAttr = pTypeAttr->getValue();
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if ( (!strcmp(pcszElemName, "DiskSection"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync || ( (!strcmp(pcszElemName, "Section"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync && (!strcmp(pcszTypeAttr, "ovf:DiskSection_Type"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync )
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync )
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync {
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync HandleDiskSection(pReferencesElem, pElem);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync }
32c16cab49ef1ab1aea3b3340fbc133b99ee8b20vboxsync else if ( (!strcmp(pcszElemName, "NetworkSection"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync || ( (!strcmp(pcszElemName, "Section"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync && (!strcmp(pcszTypeAttr, "ovf:NetworkSection_Type"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync )
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync )
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync {
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync HandleNetworkSection(pElem);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if ( (!strcmp(pcszElemName, "DeploymentOptionSection")))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync {
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // TODO
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if ( (!strcmp(pcszElemName, "Info")))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync {
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // child of VirtualSystemCollection -- TODO
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if ( (!strcmp(pcszElemName, "ResourceAllocationSection")))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync {
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // child of VirtualSystemCollection -- TODO
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if ( (!strcmp(pcszElemName, "StartupSection")))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync {
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // child of VirtualSystemCollection -- TODO
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if ( (!strcmp(pcszElemName, "VirtualSystem"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync || ( (!strcmp(pcszElemName, "Content"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync && (!strcmp(pcszTypeAttr, "ovf:VirtualSystem_Type"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync )
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync )
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync {
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync HandleVirtualSystemContent(pElem);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if ( (!strcmp(pcszElemName, "VirtualSystemCollection"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync || ( (!strcmp(pcszElemName, "Content"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync && (!strcmp(pcszTypeAttr, "ovf:VirtualSystemCollection_Type"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync )
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync )
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync {
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // TODO ResourceAllocationSection
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // recurse for this, since it has VirtualSystem elements as children
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync LoopThruSections(pReferencesElem, pElem);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync}
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync/**
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * Private helper method that handles disk sections in the OVF XML.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * Gets called indirectly from IAppliance::read().
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync *
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.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * @return
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsyncvoid OVFReader::HandleDiskSection(const xml::ElementNode *pReferencesElem,
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync const xml::ElementNode *pSectionElem)
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync{
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // contains "Disk" child elements
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync xml::NodesLoop loopDisks(*pSectionElem, "Disk");
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync const xml::ElementNode *pelmDisk;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync while ((pelmDisk = loopDisks.forAllNodes()))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync {
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync DiskImage d;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync const char *pcszBad = NULL;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync const char *pcszDiskId;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync const char *pcszFormat;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if (!(pelmDisk->getAttributeValue("diskId", pcszDiskId)))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync pcszBad = "diskId";
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if (!(pelmDisk->getAttributeValue("format", pcszFormat)))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync pcszBad = "format";
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if (!(pelmDisk->getAttributeValue("capacity", d.iCapacity)))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync pcszBad = "capacity";
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync {
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync d.strDiskId = pcszDiskId;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync d.strFormat = pcszFormat;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if (!(pelmDisk->getAttributeValue("populatedSize", d.iPopulatedSize)))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // optional
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync d.iPopulatedSize = -1;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
2c1d8cd8efdd4c486ff681135035d24111b03af8vboxsync // optional vbox:uuid attribute (if OVF was exported by VirtualBox != 3.2)
2c1d8cd8efdd4c486ff681135035d24111b03af8vboxsync pelmDisk->getAttributeValue("vbox:uuid", d.uuidVbox);
2c1d8cd8efdd4c486ff681135035d24111b03af8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync const char *pcszFileRef;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if (pelmDisk->getAttributeValue("fileRef", pcszFileRef)) // optional
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync {
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // look up corresponding /References/File nodes (list built above)
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync const xml::ElementNode *pFileElem;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if ( pReferencesElem
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync && ((pFileElem = pReferencesElem->findChildElementFromId(pcszFileRef)))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync )
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync {
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // copy remaining values from file node then
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync const char *pcszBadInFile = NULL;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync const char *pcszHref;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if (!(pFileElem->getAttributeValue("href", pcszHref)))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync pcszBadInFile = "href";
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if (!(pFileElem->getAttributeValue("size", d.iSize)))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync d.iSize = -1; // optional
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync d.strHref = pcszHref;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // if (!(pFileElem->getAttributeValue("size", d.iChunkSize))) TODO
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync d.iChunkSize = -1; // optional
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync const char *pcszCompression;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if (pFileElem->getAttributeValue("compression", pcszCompression))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync d.strCompression = pcszCompression;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if (pcszBadInFile)
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync throw OVFLogicError(N_("Error reading \"%s\": missing or invalid attribute '%s' in 'File' element, line %d"),
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync m_strPath.c_str(),
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync pcszBadInFile,
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync pFileElem->getLineNumber());
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync throw OVFLogicError(N_("Error reading \"%s\": cannot find References/File element for ID '%s' referenced by 'Disk' element, line %d"),
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync m_strPath.c_str(),
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync pcszFileRef,
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync pelmDisk->getLineNumber());
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if (pcszBad)
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync throw OVFLogicError(N_("Error reading \"%s\": missing or invalid attribute '%s' in 'DiskSection' element, line %d"),
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync m_strPath.c_str(),
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync pcszBad,
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync pelmDisk->getLineNumber());
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
2c1d8cd8efdd4c486ff681135035d24111b03af8vboxsync // suggest a size in megabytes to help callers with progress reports
2c1d8cd8efdd4c486ff681135035d24111b03af8vboxsync d.ulSuggestedSizeMB = 0;
2c1d8cd8efdd4c486ff681135035d24111b03af8vboxsync if (d.iCapacity != -1)
2c1d8cd8efdd4c486ff681135035d24111b03af8vboxsync d.ulSuggestedSizeMB = d.iCapacity / _1M;
2c1d8cd8efdd4c486ff681135035d24111b03af8vboxsync else if (d.iPopulatedSize != -1)
2c1d8cd8efdd4c486ff681135035d24111b03af8vboxsync d.ulSuggestedSizeMB = d.iPopulatedSize / _1M;
2c1d8cd8efdd4c486ff681135035d24111b03af8vboxsync else if (d.iSize != -1)
2c1d8cd8efdd4c486ff681135035d24111b03af8vboxsync d.ulSuggestedSizeMB = d.iSize / _1M;
2c1d8cd8efdd4c486ff681135035d24111b03af8vboxsync if (d.ulSuggestedSizeMB == 0)
2c1d8cd8efdd4c486ff681135035d24111b03af8vboxsync d.ulSuggestedSizeMB = 10000; // assume 10 GB, this is for the progress bar only anyway
2c1d8cd8efdd4c486ff681135035d24111b03af8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync m_mapDisks[d.strDiskId] = d;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync}
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync/**
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * Private helper method that handles network sections in the OVF XML.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * Gets called indirectly from IAppliance::read().
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync *
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * @param pcszPath Path spec of the XML file, for error messages.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * @param pSectionElem Section element for which this helper is getting called.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * @return
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsyncvoid OVFReader::HandleNetworkSection(const xml::ElementNode * /* pSectionElem */)
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync{
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // we ignore network sections for now
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync// xml::NodesLoop loopNetworks(*pSectionElem, "Network");
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync// const xml::Node *pelmNetwork;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync// while ((pelmNetwork = loopNetworks.forAllNodes()))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync// {
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//
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync// m->mapNetworks[n.strNetworkName] = n;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync// }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync}
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync/**
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * Private helper method that handles a "VirtualSystem" element in the OVF XML.
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * Gets called indirectly from IAppliance::read().
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync *
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * @param pcszPath
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * @param pContentElem
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync * @return
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsyncvoid OVFReader::HandleVirtualSystemContent(const xml::ElementNode *pelmVirtualSystem)
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync{
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VirtualSystem vsys;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
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
f7c0f913c4c22ee18059ff97055442566d0f14a1vboxsync // now look for real OVF
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync const xml::AttributeNode *pIdAttr = pelmVirtualSystem->findAttribute("id");
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if (pIdAttr)
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync vsys.strName = pIdAttr->getValue();
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync xml::NodesLoop loop(*pelmVirtualSystem); // all child elements
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync const xml::ElementNode *pelmThis;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync while ((pelmThis = loop.forAllNodes()))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync {
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync const char *pcszElemName = pelmThis->getName();
885b661364d7f51d087003dccaccb6d24610f654vboxsync const char *pcszTypeAttr = "";
885b661364d7f51d087003dccaccb6d24610f654vboxsync if (!strcmp(pcszElemName, "Section")) // OVF 0.9 used "Section" element always with a varying "type" attribute
885b661364d7f51d087003dccaccb6d24610f654vboxsync {
885b661364d7f51d087003dccaccb6d24610f654vboxsync const xml::AttributeNode *pTypeAttr;
885b661364d7f51d087003dccaccb6d24610f654vboxsync if ( ((pTypeAttr = pelmThis->findAttribute("type")))
885b661364d7f51d087003dccaccb6d24610f654vboxsync || ((pTypeAttr = pelmThis->findAttribute("xsi:type")))
885b661364d7f51d087003dccaccb6d24610f654vboxsync )
885b661364d7f51d087003dccaccb6d24610f654vboxsync pcszTypeAttr = pTypeAttr->getValue();
885b661364d7f51d087003dccaccb6d24610f654vboxsync else
885b661364d7f51d087003dccaccb6d24610f654vboxsync throw OVFLogicError(N_("Error reading \"%s\": element \"Section\" has no \"type\" attribute, line %d"),
885b661364d7f51d087003dccaccb6d24610f654vboxsync m_strPath.c_str(),
885b661364d7f51d087003dccaccb6d24610f654vboxsync pelmThis->getLineNumber());
885b661364d7f51d087003dccaccb6d24610f654vboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if ( (!strcmp(pcszElemName, "EulaSection"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync || (!strcmp(pcszTypeAttr, "ovf:EulaSection_Type"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync )
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync {
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
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync const xml::ElementNode *pelmLicense;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if ((pelmLicense = pelmThis->findChildElement("License")))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync vsys.strLicenseText = pelmLicense->getValue();
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if ( (!strcmp(pcszElemName, "ProductSection"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync || (!strcmp(pcszTypeAttr, "ovf:ProductSection_Type"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync )
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync {
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 const xml::ElementNode *pelmProduct;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if ((pelmProduct = pelmThis->findChildElement("Product")))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync vsys.strProduct = pelmProduct->getValue();
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync const xml::ElementNode *pelmVendor;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if ((pelmVendor = pelmThis->findChildElement("Vendor")))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync vsys.strVendor = pelmVendor->getValue();
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync const xml::ElementNode *pelmVersion;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if ((pelmVersion = pelmThis->findChildElement("Version")))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync vsys.strVersion = pelmVersion->getValue();
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync const xml::ElementNode *pelmProductUrl;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if ((pelmProductUrl = pelmThis->findChildElement("ProductUrl")))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync vsys.strProductUrl = pelmProductUrl->getValue();
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync const xml::ElementNode *pelmVendorUrl;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if ((pelmVendorUrl = pelmThis->findChildElement("VendorUrl")))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync vsys.strVendorUrl = pelmVendorUrl->getValue();
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if ( (!strcmp(pcszElemName, "VirtualHardwareSection"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync || (!strcmp(pcszTypeAttr, "ovf:VirtualHardwareSection_Type"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync )
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync {
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync const xml::ElementNode *pelmSystem, *pelmVirtualSystemType;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if ((pelmSystem = pelmThis->findChildElement("System")))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync {
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();
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync xml::NodesLoop loopVirtualHardwareItems(*pelmThis, "Item"); // all "Item" child elements
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync const xml::ElementNode *pelmItem;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync while ((pelmItem = loopVirtualHardwareItems.forAllNodes()))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync {
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VirtualHardwareItem i;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync i.ulLineNumber = pelmItem->getLineNumber();
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync xml::NodesLoop loopItemChildren(*pelmItem); // all child elements
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync const xml::ElementNode *pelmItemChild;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync while ((pelmItemChild = loopItemChildren.forAllNodes()))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync {
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync const char *pcszItemChildName = pelmItemChild->getName();
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if (!strcmp(pcszItemChildName, "Description"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync i.strDescription = pelmItemChild->getValue();
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if (!strcmp(pcszItemChildName, "Caption"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync i.strCaption = pelmItemChild->getValue();
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if (!strcmp(pcszItemChildName, "ElementName"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync i.strElementName = pelmItemChild->getValue();
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if ( (!strcmp(pcszItemChildName, "InstanceID"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync || (!strcmp(pcszItemChildName, "InstanceId"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync )
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync pelmItemChild->copyValue(i.ulInstanceID);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if (!strcmp(pcszItemChildName, "HostResource"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync i.strHostResource = pelmItemChild->getValue();
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if (!strcmp(pcszItemChildName, "ResourceType"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync {
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync uint32_t ulType;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync pelmItemChild->copyValue(ulType);
d5bf937d132098565e18a0d1fc408fb777c5e5b6vboxsync i.resourceType = (ResourceType_T)ulType;
385c5fb9bdc175ef2d5dc340f1016b231acfe23cvboxsync i.fResourceRequired = true;
385c5fb9bdc175ef2d5dc340f1016b231acfe23cvboxsync const char *pcszAttValue;
385c5fb9bdc175ef2d5dc340f1016b231acfe23cvboxsync if (pelmItem->getAttributeValue("required", pcszAttValue))
385c5fb9bdc175ef2d5dc340f1016b231acfe23cvboxsync {
385c5fb9bdc175ef2d5dc340f1016b231acfe23cvboxsync if (!strcmp(pcszAttValue, "false"))
385c5fb9bdc175ef2d5dc340f1016b231acfe23cvboxsync i.fResourceRequired = false;
385c5fb9bdc175ef2d5dc340f1016b231acfe23cvboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if (!strcmp(pcszItemChildName, "OtherResourceType"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync i.strOtherResourceType = pelmItemChild->getValue();
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if (!strcmp(pcszItemChildName, "ResourceSubType"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync i.strResourceSubType = pelmItemChild->getValue();
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if (!strcmp(pcszItemChildName, "AutomaticAllocation"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync i.fAutomaticAllocation = (!strcmp(pelmItemChild->getValue(), "true")) ? true : false;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if (!strcmp(pcszItemChildName, "AutomaticDeallocation"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync i.fAutomaticDeallocation = (!strcmp(pelmItemChild->getValue(), "true")) ? true : false;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if (!strcmp(pcszItemChildName, "Parent"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync pelmItemChild->copyValue(i.ulParent);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if (!strcmp(pcszItemChildName, "Connection"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync i.strConnection = pelmItemChild->getValue();
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if (!strcmp(pcszItemChildName, "Address"))
15760030457c4d8548d42a9d543646b27eae7040vboxsync {
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync i.strAddress = pelmItemChild->getValue();
15760030457c4d8548d42a9d543646b27eae7040vboxsync pelmItemChild->copyValue(i.lAddress);
15760030457c4d8548d42a9d543646b27eae7040vboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if (!strcmp(pcszItemChildName, "AddressOnParent"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync i.strAddressOnParent = pelmItemChild->getValue();
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if (!strcmp(pcszItemChildName, "AllocationUnits"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync i.strAllocationUnits = pelmItemChild->getValue();
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if (!strcmp(pcszItemChildName, "VirtualQuantity"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync pelmItemChild->copyValue(i.ullVirtualQuantity);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if (!strcmp(pcszItemChildName, "Reservation"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync pelmItemChild->copyValue(i.ullReservation);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if (!strcmp(pcszItemChildName, "Limit"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync pelmItemChild->copyValue(i.ullLimit);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if (!strcmp(pcszItemChildName, "Weight"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync pelmItemChild->copyValue(i.ullWeight);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if (!strcmp(pcszItemChildName, "ConsumerVisibility"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync i.strConsumerVisibility = pelmItemChild->getValue();
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if (!strcmp(pcszItemChildName, "MappingBehavior"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync i.strMappingBehavior = pelmItemChild->getValue();
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if (!strcmp(pcszItemChildName, "PoolID"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync i.strPoolID = pelmItemChild->getValue();
ad0efafe1c9e639fa7c26b9a956f20119031ca10vboxsync else if (!strcmp(pcszItemChildName, "BusNumber")) // seen in some old OVF, but it's not listed in the OVF specs
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync pelmItemChild->copyValue(i.ulBusNumber);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync throw OVFLogicError(N_("Error reading \"%s\": unknown element \"%s\" under Item element, line %d"),
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync m_strPath.c_str(),
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync pcszItemChildName,
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync i.ulLineNumber);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // store!
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync vsys.mapHardwareItems[i.ulInstanceID] = i;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
15760030457c4d8548d42a9d543646b27eae7040vboxsync HardDiskController *pPrimaryIDEController = NULL; // will be set once found
15760030457c4d8548d42a9d543646b27eae7040vboxsync
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 HardwareItemsMap::const_iterator itH;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync for (itH = vsys.mapHardwareItems.begin();
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync itH != vsys.mapHardwareItems.end();
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync ++itH)
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync {
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync const VirtualHardwareItem &i = itH->second;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // do some analysis
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync switch (i.resourceType)
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync {
d5bf937d132098565e18a0d1fc408fb777c5e5b6vboxsync case ResourceType_Processor: // 3
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 if (i.ullVirtualQuantity < UINT16_MAX)
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync vsys.cCPUs = (uint16_t)i.ullVirtualQuantity;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync throw OVFLogicError(N_("Error reading \"%s\": CPU count %RI64 is larger than %d, line %d"),
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync m_strPath.c_str(),
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync i.ullVirtualQuantity,
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync UINT16_MAX,
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync i.ulLineNumber);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync break;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d5bf937d132098565e18a0d1fc408fb777c5e5b6vboxsync case ResourceType_Memory: // 4
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 )
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync vsys.ullMemorySize = i.ullVirtualQuantity * 1024 * 1024;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync throw OVFLogicError(N_("Error reading \"%s\": Invalid allocation unit \"%s\" specified with memory size item, line %d"),
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync m_strPath.c_str(),
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync i.strAllocationUnits.c_str(),
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync i.ulLineNumber);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync break;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d5bf937d132098565e18a0d1fc408fb777c5e5b6vboxsync case ResourceType_IDEController: // 5
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync {
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* <Item>
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>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync </Item> */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync HardDiskController hdc;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync hdc.system = HardDiskController::IDE;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync hdc.idController = i.ulInstanceID;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync hdc.strControllerType = i.strResourceSubType;
ad0efafe1c9e639fa7c26b9a956f20119031ca10vboxsync
15760030457c4d8548d42a9d543646b27eae7040vboxsync hdc.lAddress = i.lAddress;
15760030457c4d8548d42a9d543646b27eae7040vboxsync
15760030457c4d8548d42a9d543646b27eae7040vboxsync if (!pPrimaryIDEController)
15760030457c4d8548d42a9d543646b27eae7040vboxsync // this is the first IDE controller found: then mark it as "primary"
15760030457c4d8548d42a9d543646b27eae7040vboxsync hdc.fPrimary = true;
ad0efafe1c9e639fa7c26b9a956f20119031ca10vboxsync else
15760030457c4d8548d42a9d543646b27eae7040vboxsync {
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 if ( pPrimaryIDEController->lAddress == 0
15760030457c4d8548d42a9d543646b27eae7040vboxsync && hdc.lAddress == 1
15760030457c4d8548d42a9d543646b27eae7040vboxsync )
15760030457c4d8548d42a9d543646b27eae7040vboxsync {
15760030457c4d8548d42a9d543646b27eae7040vboxsync pPrimaryIDEController->fPrimary = true;
15760030457c4d8548d42a9d543646b27eae7040vboxsync hdc.fPrimary = false;
15760030457c4d8548d42a9d543646b27eae7040vboxsync }
15760030457c4d8548d42a9d543646b27eae7040vboxsync else if ( pPrimaryIDEController->lAddress == 1
15760030457c4d8548d42a9d543646b27eae7040vboxsync && hdc.lAddress == 0
15760030457c4d8548d42a9d543646b27eae7040vboxsync )
15760030457c4d8548d42a9d543646b27eae7040vboxsync {
15760030457c4d8548d42a9d543646b27eae7040vboxsync pPrimaryIDEController->fPrimary = false;
15760030457c4d8548d42a9d543646b27eae7040vboxsync hdc.fPrimary = false;
15760030457c4d8548d42a9d543646b27eae7040vboxsync }
15760030457c4d8548d42a9d543646b27eae7040vboxsync else
15760030457c4d8548d42a9d543646b27eae7040vboxsync // then we really can't tell, just hope for the best
15760030457c4d8548d42a9d543646b27eae7040vboxsync hdc.fPrimary = false;
15760030457c4d8548d42a9d543646b27eae7040vboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync vsys.mapControllers[i.ulInstanceID] = hdc;
15760030457c4d8548d42a9d543646b27eae7040vboxsync if (!pPrimaryIDEController)
15760030457c4d8548d42a9d543646b27eae7040vboxsync pPrimaryIDEController = &vsys.mapControllers[i.ulInstanceID];
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync break;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d5bf937d132098565e18a0d1fc408fb777c5e5b6vboxsync case ResourceType_ParallelSCSIHBA: // 6 SCSI controller
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync {
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* <Item>
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 </Item> */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync HardDiskController hdc;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync hdc.system = HardDiskController::SCSI;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync hdc.idController = i.ulInstanceID;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync hdc.strControllerType = i.strResourceSubType;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync vsys.mapControllers[i.ulInstanceID] = hdc;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync break;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d5bf937d132098565e18a0d1fc408fb777c5e5b6vboxsync case ResourceType_EthernetAdapter: // 10
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync {
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* <Item>
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 </Item>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
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
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // only store the name
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync EthernetAdapter ea;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync ea.strAdapterType = i.strResourceSubType;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync ea.strNetworkName = i.strConnection;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync vsys.llEthernetAdapters.push_back(ea);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync break;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d5bf937d132098565e18a0d1fc408fb777c5e5b6vboxsync case ResourceType_FloppyDrive: // 14
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync vsys.fHasFloppyDrive = true; // we have no additional information
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync break;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d5bf937d132098565e18a0d1fc408fb777c5e5b6vboxsync case ResourceType_CDDrive: // 15
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 </Item> */
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 break;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d5bf937d132098565e18a0d1fc408fb777c5e5b6vboxsync case ResourceType_HardDisk: // 17
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // handled separately in second loop below
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync break;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d5bf937d132098565e18a0d1fc408fb777c5e5b6vboxsync case ResourceType_OtherStorageDevice: // 20 SATA controller
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync {
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* <Item>
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>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync </Item> */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if ( i.strCaption.startsWith("sataController", MiniString::CaseInsensitive)
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync && !i.strResourceSubType.compare("AHCI", MiniString::CaseInsensitive)
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync )
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync {
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync HardDiskController hdc;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync hdc.system = HardDiskController::SATA;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync hdc.idController = i.ulInstanceID;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync hdc.strControllerType = i.strResourceSubType;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync vsys.mapControllers[i.ulInstanceID] = hdc;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else
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 m_strPath.c_str(),
d5bf937d132098565e18a0d1fc408fb777c5e5b6vboxsync ResourceType_OtherStorageDevice,
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync i.ulLineNumber);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync break;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d5bf937d132098565e18a0d1fc408fb777c5e5b6vboxsync case ResourceType_USBController: // 23
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 </Item> */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync vsys.fHasUsbController = true; // we have no additional information
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync break;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d5bf937d132098565e18a0d1fc408fb777c5e5b6vboxsync case ResourceType_SoundCard: // 35
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>
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync </Item> */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync vsys.strSoundCardType = i.strResourceSubType;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync break;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync default:
385c5fb9bdc175ef2d5dc340f1016b231acfe23cvboxsync {
385c5fb9bdc175ef2d5dc340f1016b231acfe23cvboxsync /* If this unknown resource type isn't required, we simply skip it. */
385c5fb9bdc175ef2d5dc340f1016b231acfe23cvboxsync if (i.fResourceRequired)
385c5fb9bdc175ef2d5dc340f1016b231acfe23cvboxsync {
385c5fb9bdc175ef2d5dc340f1016b231acfe23cvboxsync throw OVFLogicError(N_("Error reading \"%s\": Unknown resource type %d in hardware item, line %d"),
385c5fb9bdc175ef2d5dc340f1016b231acfe23cvboxsync m_strPath.c_str(),
385c5fb9bdc175ef2d5dc340f1016b231acfe23cvboxsync i.resourceType,
385c5fb9bdc175ef2d5dc340f1016b231acfe23cvboxsync i.ulLineNumber);
385c5fb9bdc175ef2d5dc340f1016b231acfe23cvboxsync }
385c5fb9bdc175ef2d5dc340f1016b231acfe23cvboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync } // end switch
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
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 for (itH = vsys.mapHardwareItems.begin();
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync itH != vsys.mapHardwareItems.end();
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync ++itH)
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync {
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync const VirtualHardwareItem &i = itH->second;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // do some analysis
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync switch (i.resourceType)
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync {
d5bf937d132098565e18a0d1fc408fb777c5e5b6vboxsync case ResourceType_HardDisk: // 17
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync {
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync /* <Item>
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 </Item> */
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
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);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if (it == vsys.mapControllers.end())
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync throw OVFLogicError(N_("Error reading \"%s\": Hard disk item with instance ID %d specifies invalid parent %d, line %d"),
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync m_strPath.c_str(),
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync i.ulInstanceID,
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync i.ulParent,
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync i.ulLineNumber);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync //const HardDiskController &hdc = it->second;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync VirtualDisk vd;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync vd.idController = i.ulParent;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync i.strAddressOnParent.toInt(vd.ulAddressOnParent);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // ovf://disk/lamp
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // 123456789012345
0a6257a55820e2433e68420ff1a1ad89c398ce28vboxsync if (i.strHostResource.startsWith("ovf://disk/"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync vd.strDiskId = i.strHostResource.substr(11);
0a6257a55820e2433e68420ff1a1ad89c398ce28vboxsync else if (i.strHostResource.startsWith("ovf:/disk/"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync vd.strDiskId = i.strHostResource.substr(10);
0a6257a55820e2433e68420ff1a1ad89c398ce28vboxsync else if (i.strHostResource.startsWith("/disk/"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync vd.strDiskId = i.strHostResource.substr(6);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if ( !(vd.strDiskId.length())
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync || (m_mapDisks.find(vd.strDiskId) == m_mapDisks.end())
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync )
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync throw OVFLogicError(N_("Error reading \"%s\": Hard disk item with instance ID %d specifies invalid host resource \"%s\", line %d"),
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync m_strPath.c_str(),
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync i.ulInstanceID,
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync i.strHostResource.c_str(),
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync i.ulLineNumber);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync vsys.mapVirtualDisks[vd.strDiskId] = vd;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync break;
7622c238774f7797c2a216582f4efb84c4c082afvboxsync default: break;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if ( (!strcmp(pcszElemName, "OperatingSystemSection"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync || (!strcmp(pcszTypeAttr, "ovf:OperatingSystemSection_Type"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync )
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync {
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync uint64_t cimos64;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if (!(pelmThis->getAttributeValue("id", cimos64)))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync throw OVFLogicError(N_("Error reading \"%s\": missing or invalid 'ovf:id' attribute in operating system section element, line %d"),
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync m_strPath.c_str(),
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync pelmThis->getLineNumber());
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync vsys.cimos = (CIMOSType_T)cimos64;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync const xml::ElementNode *pelmCIMOSDescription;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if ((pelmCIMOSDescription = pelmThis->findChildElement("Description")))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync vsys.strCimosDesc = pelmCIMOSDescription->getValue();
cafbe3edf3ba3d13bad27f9570b0b57c18f3c57fvboxsync
cafbe3edf3ba3d13bad27f9570b0b57c18f3c57fvboxsync const xml::ElementNode *pelmVBoxOSType;
cafbe3edf3ba3d13bad27f9570b0b57c18f3c57fvboxsync if ((pelmVBoxOSType = pelmThis->findChildElement("vbox", // namespace
cafbe3edf3ba3d13bad27f9570b0b57c18f3c57fvboxsync "OSType"))) // element name
cafbe3edf3ba3d13bad27f9570b0b57c18f3c57fvboxsync vsys.strTypeVbox = pelmVBoxOSType->getValue();
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync else if ( (!strcmp(pcszElemName, "AnnotationSection"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync || (!strcmp(pcszTypeAttr, "ovf:AnnotationSection_Type"))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync )
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync {
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync const xml::ElementNode *pelmAnnotation;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync if ((pelmAnnotation = pelmThis->findChildElement("Annotation")))
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync vsys.strDescription = pelmAnnotation->getValue();
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync }
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync // now create the virtual system
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync m_llVirtualSystems.push_back(vsys);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync}
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync////////////////////////////////////////////////////////////////////////////////
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync//
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync// Errors
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync//
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync////////////////////////////////////////////////////////////////////////////////
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsyncOVFLogicError::OVFLogicError(const char *aFormat, ...)
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync{
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync char *pszNewMsg;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync va_list args;
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync va_start(args, aFormat);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync RTStrAPrintfV(&pszNewMsg, aFormat, args);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync setWhat(pszNewMsg);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync RTStrFree(pszNewMsg);
d84b6107a8e797f41ac2d55bed97b02c91c742e8vboxsync va_end(args);
7622c238774f7797c2a216582f4efb84c4c082afvboxsync}