diff options
Diffstat (limited to 'src/VBox/Main/include/ovfreader.h')
-rw-r--r-- | src/VBox/Main/include/ovfreader.h | 732 |
1 files changed, 732 insertions, 0 deletions
diff --git a/src/VBox/Main/include/ovfreader.h b/src/VBox/Main/include/ovfreader.h new file mode 100644 index 00000000..848434b6 --- /dev/null +++ b/src/VBox/Main/include/ovfreader.h @@ -0,0 +1,732 @@ +/* $Id: ovfreader.h $ */ +/** @file + * VirtualBox Main - OVF reader declarations. + * + * Depends only on IPRT, including the RTCString and IPRT XML classes. + */ + +/* + * Copyright (C) 2008-2022 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#ifndef MAIN_INCLUDED_ovfreader_h +#define MAIN_INCLUDED_ovfreader_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include "iprt/cpp/xml.h" +#include <map> +#include <vector> + +namespace ovf +{ + +//////////////////////////////////////////////////////////////////////////////// +// +// Errors +// +//////////////////////////////////////////////////////////////////////////////// + +/** + * Thrown by OVFReader for any kind of error that is not an XML error but + * still makes the OVF impossible to parse. Based on xml::LogicError so + * that one catch() for all xml::LogicError can handle all possible errors. + */ +class OVFLogicError : public xml::LogicError +{ +public: + OVFLogicError(const char *aFormat, ...); +}; + + +//////////////////////////////////////////////////////////////////////////////// +// +// Enumerations +// +//////////////////////////////////////////////////////////////////////////////// + +/** + * CIM OS values. + * + * The OVF 1.10 spec refers to some CIM_OperatingSystem.mof doc. Could this be it: + * http://cvs.opengroup.org/cgi-bin/cvsweb.cgi/pegasus/Schemas/CIM231/DMTF/System/CIM_OperatingSystem.mof + * + * @todo r=bird: Why are the values are repeating 'CIMOS'. CIMOSType_T is also + * repeating it self, 'Type' and '_T'. Why not call it kCIOMOpSys, + * easier to read as well. + * Then also apply: s/CIMOSType_CIMOS_/kCIMOpSys_/g + */ +enum CIMOSType_T +{ + CIMOSType_CIMOS_Unknown = 0, + CIMOSType_CIMOS_Other = 1, + CIMOSType_CIMOS_MACOS = 2, + CIMOSType_CIMOS_ATTUNIX = 3, + CIMOSType_CIMOS_DGUX = 4, + CIMOSType_CIMOS_DECNT = 5, + CIMOSType_CIMOS_Tru64UNIX = 6, + CIMOSType_CIMOS_OpenVMS = 7, + CIMOSType_CIMOS_HPUX = 8, + CIMOSType_CIMOS_AIX = 9, + CIMOSType_CIMOS_MVS = 10, + CIMOSType_CIMOS_OS400 = 11, + CIMOSType_CIMOS_OS2 = 12, + CIMOSType_CIMOS_JavaVM = 13, + CIMOSType_CIMOS_MSDOS = 14, + CIMOSType_CIMOS_WIN3x = 15, + CIMOSType_CIMOS_WIN95 = 16, + CIMOSType_CIMOS_WIN98 = 17, + CIMOSType_CIMOS_WINNT = 18, + CIMOSType_CIMOS_WINCE = 19, + CIMOSType_CIMOS_NCR3000 = 20, + CIMOSType_CIMOS_NetWare = 21, + CIMOSType_CIMOS_OSF = 22, + CIMOSType_CIMOS_DCOS = 23, + CIMOSType_CIMOS_ReliantUNIX = 24, + CIMOSType_CIMOS_SCOUnixWare = 25, + CIMOSType_CIMOS_SCOOpenServer = 26, + CIMOSType_CIMOS_Sequent = 27, + CIMOSType_CIMOS_IRIX = 28, + CIMOSType_CIMOS_Solaris = 29, + CIMOSType_CIMOS_SunOS = 30, + CIMOSType_CIMOS_U6000 = 31, + CIMOSType_CIMOS_ASERIES = 32, + CIMOSType_CIMOS_HPNonStopOS = 33, + CIMOSType_CIMOS_HPNonStopOSS = 34, + CIMOSType_CIMOS_BS2000 = 35, + CIMOSType_CIMOS_LINUX = 36, + CIMOSType_CIMOS_Lynx = 37, + CIMOSType_CIMOS_XENIX = 38, + CIMOSType_CIMOS_VM = 39, + CIMOSType_CIMOS_InteractiveUNIX = 40, + CIMOSType_CIMOS_BSDUNIX = 41, + CIMOSType_CIMOS_FreeBSD = 42, + CIMOSType_CIMOS_NetBSD = 43, + CIMOSType_CIMOS_GNUHurd = 44, + CIMOSType_CIMOS_OS9 = 45, + CIMOSType_CIMOS_MACHKernel = 46, + CIMOSType_CIMOS_Inferno = 47, + CIMOSType_CIMOS_QNX = 48, + CIMOSType_CIMOS_EPOC = 49, + CIMOSType_CIMOS_IxWorks = 50, + CIMOSType_CIMOS_VxWorks = 51, + CIMOSType_CIMOS_MiNT = 52, + CIMOSType_CIMOS_BeOS = 53, + CIMOSType_CIMOS_HPMPE = 54, + CIMOSType_CIMOS_NextStep = 55, + CIMOSType_CIMOS_PalmPilot = 56, + CIMOSType_CIMOS_Rhapsody = 57, + CIMOSType_CIMOS_Windows2000 = 58, + CIMOSType_CIMOS_Dedicated = 59, + CIMOSType_CIMOS_OS390 = 60, + CIMOSType_CIMOS_VSE = 61, + CIMOSType_CIMOS_TPF = 62, + CIMOSType_CIMOS_WindowsMe = 63, + CIMOSType_CIMOS_CalderaOpenUNIX = 64, + CIMOSType_CIMOS_OpenBSD = 65, + CIMOSType_CIMOS_NotApplicable = 66, + CIMOSType_CIMOS_WindowsXP = 67, + CIMOSType_CIMOS_zOS = 68, + CIMOSType_CIMOS_MicrosoftWindowsServer2003 = 69, + CIMOSType_CIMOS_MicrosoftWindowsServer2003_64 = 70, + CIMOSType_CIMOS_WindowsXP_64 = 71, + CIMOSType_CIMOS_WindowsXPEmbedded = 72, + CIMOSType_CIMOS_WindowsVista = 73, + CIMOSType_CIMOS_WindowsVista_64 = 74, + CIMOSType_CIMOS_WindowsEmbeddedforPointofService = 75, + CIMOSType_CIMOS_MicrosoftWindowsServer2008 = 76, + CIMOSType_CIMOS_MicrosoftWindowsServer2008_64 = 77, + CIMOSType_CIMOS_FreeBSD_64 = 78, + CIMOSType_CIMOS_RedHatEnterpriseLinux = 79, + CIMOSType_CIMOS_RedHatEnterpriseLinux_64 = 80, + CIMOSType_CIMOS_Solaris_64 = 81, + CIMOSType_CIMOS_SUSE = 82, + CIMOSType_CIMOS_SUSE_64 = 83, + CIMOSType_CIMOS_SLES = 84, + CIMOSType_CIMOS_SLES_64 = 85, + CIMOSType_CIMOS_NovellOES = 86, + CIMOSType_CIMOS_NovellLinuxDesktop = 87, + CIMOSType_CIMOS_SunJavaDesktopSystem = 88, + CIMOSType_CIMOS_Mandriva = 89, + CIMOSType_CIMOS_Mandriva_64 = 90, + CIMOSType_CIMOS_TurboLinux = 91, + CIMOSType_CIMOS_TurboLinux_64 = 92, + CIMOSType_CIMOS_Ubuntu = 93, + CIMOSType_CIMOS_Ubuntu_64 = 94, + CIMOSType_CIMOS_Debian = 95, + CIMOSType_CIMOS_Debian_64 = 96, + CIMOSType_CIMOS_Linux_2_4_x = 97, + CIMOSType_CIMOS_Linux_2_4_x_64 = 98, + CIMOSType_CIMOS_Linux_2_6_x = 99, + CIMOSType_CIMOS_Linux_2_6_x_64 = 100, + CIMOSType_CIMOS_Linux_64 = 101, + CIMOSType_CIMOS_Other_64 = 102, + // types added with CIM 2.25.0 follow: + CIMOSType_CIMOS_WindowsServer2008R2 = 103, + CIMOSType_CIMOS_VMwareESXi = 104, + CIMOSType_CIMOS_Windows7 = 105, + CIMOSType_CIMOS_CentOS = 106, + CIMOSType_CIMOS_CentOS_64 = 107, + CIMOSType_CIMOS_OracleLinux = 108, + CIMOSType_CIMOS_OracleLinux_64 = 109, + CIMOSType_CIMOS_eComStation = 110, + // no new types added with CIM 2.26.0 + CIMOSType_CIMOS_WindowsServer2011 = 111, + CIMOSType_CIMOS_WindowsServer2012 = 112, + CIMOSType_CIMOS_Windows8 = 113, + CIMOSType_CIMOS_Windows8_64 = 114, + CIMOSType_CIMOS_WindowsServer2012R2 = 115, + CIMOSType_CIMOS_Windows8_1 = 116, + CIMOSType_CIMOS_Windows8_1_64 = 117, + CIMOSType_CIMOS_WindowsServer2016 = 118, + CIMOSType_CIMOS_Windows10 = 119, + CIMOSType_CIMOS_Windows10_64 = 120, + // the above covers up to CIM 2.52.0, without checking when it was added +}; + +enum OVFVersion_T +{ + OVFVersion_unknown, + OVFVersion_0_9, + OVFVersion_1_0, + OVFVersion_2_0 +}; + +const char* const OVF09_URI_string = "http://www.vmware.com/schema/ovf/1/envelope"; +const char* const OVF10_URI_string = "http://schemas.dmtf.org/ovf/envelope/1"; +const char* const OVF20_URI_string = "http://schemas.dmtf.org/ovf/envelope/2"; + +const char* const DTMF_SPECS_URI = "http://schemas.dmtf.org/wbem/cim-html/2/"; + +//////////////////////////////////////////////////////////////////////////////// +// +// Envelope data +// +//////////////////////////////////////////////////////////////////////////////// +struct EnvelopeData +{ + OVFVersion_T version;//OVF standard version, it is used internally only by VirtualBox + RTCString lang;//language + + OVFVersion_T getOVFVersion() const + { + return version; + } + + + RTCString getStringOVFVersion() const + { + if (version == OVFVersion_0_9) + return "0.9"; + else if (version == OVFVersion_1_0) + return "1.0"; + else if (version == OVFVersion_2_0) + return "2.0"; + else + return ""; + } + + void setOVFVersion(OVFVersion_T v) + { + version = v; + } +}; + + +struct FileReference +{ + RTCString strHref; // value from /References/File/@href (filename) + RTCString strDiskId; // value from /References/File/@id () +}; + +typedef std::map<uint32_t, FileReference> FileReferenceMap; + +//////////////////////////////////////////////////////////////////////////////// +// +// Hardware definition structs +// +//////////////////////////////////////////////////////////////////////////////// + +struct DiskImage +{ + // fields from /DiskSection/Disk + RTCString strDiskId; // value from DiskSection/Disk/@diskId + int64_t iCapacity; // value from DiskSection/Disk/@capacity; + // (maximum size for dynamic images, I guess; we always translate this to bytes) + int64_t iPopulatedSize; // optional value from DiskSection/Disk/@populatedSize + // (actual used size of disk, always in bytes; can be an estimate of used disk + // space, but cannot be larger than iCapacity; -1 if not set) + RTCString strFormat; // value from DiskSection/Disk/@format + // typically http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized + RTCString uuidVBox; // optional; if the file was exported by VirtualBox >= 3.2, + // then this has the UUID with which the disk was registered + + // fields from /References/File; the spec says the file reference from disk can be empty, + // so in that case, strFilename will be empty, then a new disk should be created + RTCString strHref; // value from /References/File/@href (filename); if empty, then the remaining fields are ignored + int64_t iSize; // value from /References/File/@size (optional according to spec; then we set -1 here) + int64_t iChunkSize; // value from /References/File/@chunkSize (optional, unsupported) + RTCString strCompression; // value from /References/File/@compression (optional, can be "gzip" according to spec) + + // additional field which has a descriptive size in megabytes derived from the above; this can be used for progress reports + uint32_t ulSuggestedSizeMB; +}; + +enum ResourceType_T +{ + ResourceType_Other = 1, + ResourceType_ComputerSystem = 2, + ResourceType_Processor = 3, + ResourceType_Memory = 4, + ResourceType_IDEController = 5, + ResourceType_ParallelSCSIHBA = 6, + ResourceType_FCHBA = 7, + ResourceType_iSCSIHBA = 8, + ResourceType_IBHCA = 9, + ResourceType_EthernetAdapter = 10, + ResourceType_OtherNetworkAdapter = 11, + ResourceType_IOSlot = 12, + ResourceType_IODevice = 13, + ResourceType_FloppyDrive = 14, + ResourceType_CDDrive = 15, + ResourceType_DVDDrive = 16, + ResourceType_HardDisk = 17, + ResourceType_TapeDrive = 18, + ResourceType_StorageExtent = 19, + ResourceType_OtherStorageDevice = 20, + ResourceType_SerialPort = 21, + ResourceType_ParallelPort = 22, + ResourceType_USBController = 23, + ResourceType_GraphicsController = 24, + ResourceType_IEEE1394Controller = 25, + ResourceType_PartitionableUnit = 26, + ResourceType_BasePartitionableUnit = 27, + ResourceType_Power = 28, + ResourceType_CoolingCapacity = 29, + ResourceType_EthernetSwitchPort = 30, + ResourceType_LogicalDisk = 31, + ResourceType_StorageVolume = 32, + ResourceType_EthernetConnection = 33, + ResourceType_SoundCard = 35 /**< @todo r=klaus: Not part of OVF/CIM spec, should use "Other" or some value from 0x8000..0xffff. */ +}; + + +enum StorageAccessType_T +{ StorageAccessType_Unknown = 0, + StorageAccessType_Readable = 1, + StorageAccessType_Writeable = 2, + StorageAccessType_ReadWrite = 3 +}; + +enum ComplianceType_T +{ ComplianceType_No = 0, + ComplianceType_Soft = 1, + ComplianceType_Medium = 2, + ComplianceType_Strong = 3 +}; + +class VirtualHardwareItem +{ +public: + RTCString strDescription; + RTCString strCaption; + RTCString strElementName; + + RTCString strInstanceID; + RTCString strParent; + + ResourceType_T resourceType; + RTCString strOtherResourceType; + RTCString strResourceSubType; + bool fResourceRequired; + + RTCString strHostResource; ///< "Abstractly specifies how a device shall connect to a resource on the deployment platform. + /// Not all devices need a backing." Used with disk items, for which this + /// references a virtual disk from the Disks section. + bool fAutomaticAllocation; + bool fAutomaticDeallocation; + RTCString strConnection; ///< "All Ethernet adapters that specify the same abstract network connection name within an OVF + /// package shall be deployed on the same network. The abstract network connection name shall be + /// listed in the NetworkSection at the outermost envelope level." We ignore this and only set up + /// a network adapter depending on the network name. + RTCString strAddress; ///< "Device-specific. For an Ethernet adapter, this specifies the MAC address." + int32_t lAddress; ///< strAddress as an integer, if applicable. + RTCString strAddressOnParent;///< "For a device, this specifies its location on the controller." + RTCString strAllocationUnits;///< "Specifies the units of allocation used. For example, “byte * 2^20”." + uint64_t ullVirtualQuantity; ///< "Specifies the quantity of resources presented. For example, “256”." + uint64_t ullReservation; ///< "Specifies the minimum quantity of resources guaranteed to be available." + uint64_t ullLimit; ///< "Specifies the maximum quantity of resources that will be granted." + uint64_t ullWeight; ///< "Specifies a relative priority for this allocation in relation to other allocations." + + RTCString strConsumerVisibility; + RTCString strMappingBehavior; + RTCString strPoolID; + uint32_t ulBusNumber; ///< seen with IDE controllers, but not listed in OVF spec + + int m_iLineNumber; ///< line number of \<Item\> element in XML source; cached for error messages + + VirtualHardwareItem() + : fResourceRequired(false) + , fAutomaticAllocation(false) + , fAutomaticDeallocation(false) + , ullVirtualQuantity(0) + , ullReservation(0) + , ullLimit(0) + , ullWeight(0) + , ulBusNumber(0) + , m_iLineNumber(0) + , fDefault(false) + { + itemName = "Item"; + } + + virtual ~VirtualHardwareItem() { /* Makes MSC happy. */ } + + void fillItem(const xml::ElementNode *item); + + void setDefaultFlag() + { + fDefault = true; + } + + bool isThereDefaultValues() const + { + return fDefault; + } + + void checkConsistencyAndCompliance() RT_THROW(OVFLogicError) + { + _checkConsistencyAndCompliance(); + } + +protected: + virtual void _checkConsistencyAndCompliance() RT_THROW(OVFLogicError); + virtual const RTCString& getItemName() + { + return _getItemName(); + } + +private: + RTCString itemName; + bool fDefault;//true means that some fields were absent in the XML and some default values were assigned to. + + virtual const RTCString& _getItemName() + { + return itemName; + } +}; + +class StorageItem: public VirtualHardwareItem +{ + //see DMTF Schema Documentation http://schemas.dmtf.org/wbem/cim-html/2/ + StorageAccessType_T accessType; + RTCString strHostExtentName; +#if 0 /* unused */ + int16_t hostExtentNameFormat; + int16_t hostExtentNameNamespace; + int64_t hostExtentStartingAddress; +#endif + int64_t hostResourceBlockSize; + int64_t limit; + RTCString strOtherHostExtentNameFormat; + RTCString strOtherHostExtentNameNamespace; + int64_t reservation; + int64_t virtualQuantity; + RTCString strVirtualQuantityUnits; + int64_t virtualResourceBlockSize; + +public: + StorageItem() + : VirtualHardwareItem() + , accessType(StorageAccessType_Unknown) +#if 0 /* unused */ + , hostExtentNameFormat(-1) + , hostExtentNameNamespace(-1) + , hostExtentStartingAddress(-1) +#endif + , hostResourceBlockSize(-1) + , limit(-1) + , reservation(-1) + , virtualQuantity(-1) + , virtualResourceBlockSize(-1) + { + itemName = "StorageItem"; + }; + + void fillItem(const xml::ElementNode *item); + +protected: + virtual void _checkConsistencyAndCompliance() RT_THROW(OVFLogicError); +private: + RTCString itemName; + + virtual const RTCString& _getItemName() + { + return itemName; + } +}; + + +class EthernetPortItem: public VirtualHardwareItem +{ + //see DMTF Schema Documentation http://schemas.dmtf.org/wbem/cim-html/2/ +#if 0 /* unused */ + uint16_t DefaultPortVID; + uint16_t DefaultPriority; + uint16_t DesiredVLANEndpointMode; + uint32_t GroupID; + uint32_t ManagerID; + uint16_t NetworkPortProfileIDType; +#endif + RTCString strNetworkPortProfileID; + RTCString strOtherEndpointMode; + RTCString strOtherNetworkPortProfileIDTypeInfo; + RTCString strPortCorrelationID; +#if 0 /* unused */ + uint16_t PortVID; + bool Promiscuous; + uint64_t ReceiveBandwidthLimit; + uint16_t ReceiveBandwidthReservation; + bool SourceMACFilteringEnabled; + uint32_t VSITypeID; + uint8_t VSITypeIDVersion; + uint16_t AllowedPriorities[256]; + uint16_t AllowedToReceiveVLANs[256]; + uint16_t AllowedToTransmitVLANs[256]; +#endif + RTCString strAllowedToReceiveMACAddresses; + RTCString strAllowedToTransmitMACAddresses; + +public: + EthernetPortItem() : VirtualHardwareItem() + { + itemName = "EthernetPortItem"; + }; + + void fillItem(const xml::ElementNode *item); + +protected: + virtual void _checkConsistencyAndCompliance() RT_THROW(OVFLogicError); +private: + RTCString itemName; + + virtual const RTCString& _getItemName() + { + return itemName; + } +}; + +typedef std::map<RTCString, DiskImage> DiskImagesMap; + +struct VirtualSystem; + + +/** + * VirtualHardwareItem pointer vector with safe cleanup. + * + * We need to use object pointers because we also want EthernetPortItem and + * StorageItems to go into the container. + */ +class HardwareItemVector : public std::vector<VirtualHardwareItem *> +{ +public: + HardwareItemVector() : std::vector<VirtualHardwareItem *>() { } + ~HardwareItemVector() + { + for (iterator it = begin(); it != end(); ++it) + delete(*it); + clear(); + } + + /* There is no copying of this vector. We'd need something like shared_ptr for that. */ +private: + HardwareItemVector(const VirtualSystem &); + +}; + +struct HardDiskController +{ + RTCString strIdController; // instance ID (Item/InstanceId); this gets referenced from VirtualDisk + + enum ControllerSystemType { IDE, SATA, SCSI, VIRTIOSCSI }; + ControllerSystemType system; // one of IDE, SATA, SCSI, VIRTIOSCSI + + RTCString strControllerType; + // controller subtype (Item/ResourceSubType); e.g. "LsiLogic"; can be empty (esp. for IDE) + // note that we treat LsiLogicSAS as a SCSI controller (system == SCSI) even though VirtualBox + // treats it as a fourth class besides IDE, SATA, SCSI + + int32_t lAddress; // value from OVF "Address" element + bool fPrimary; // controller index; this is determined heuristically by the OVF reader and will + // be true for the first controller of this type (e.g. IDE primary ctler) or + // false for the next (e.g. IDE secondary ctler) + + HardDiskController() + : lAddress(0), + fPrimary(true) + { } +}; + +typedef std::map<RTCString, HardDiskController> ControllersMap; + +struct VirtualDisk +{ + RTCString strIdController; // SCSI (or IDE) controller this disk is connected to; + // this must match HardDiskController.strIdController and + // points into VirtualSystem.mapControllers + uint32_t ulAddressOnParent; // parsed strAddressOnParent of hardware item; will be 0 or 1 for IDE + // and possibly higher for disks attached to SCSI controllers (untested) + RTCString strDiskId; // if the hard disk has an ovf:/disk/<id> reference, + // this receives the <id> component; points to one of the + // references in Appliance::Data.mapDisks + bool fEmpty; //true - empty disk, e.g. the component <rasd:HostResource>...</rasd:HostResource> is absent. +}; + +typedef std::map<RTCString, VirtualDisk> VirtualDisksMap; + +/** + * A list of EthernetAdapters is contained in VirtualSystem, representing the + * ethernet adapters in the virtual system. + */ +struct EthernetAdapter +{ + RTCString strAdapterType; // "PCNet32" or "E1000" or whatever; from <rasd:ResourceSubType> + RTCString strNetworkName; // from <rasd:Connection> +}; + +typedef std::list<EthernetAdapter> EthernetAdaptersList; + +/** + * A list of VirtualSystem structs is created by OVFReader::read(). Each refers to + * a \<VirtualSystem\> block in the OVF file. + */ +struct VirtualSystem +{ + RTCString strName; // copy of VirtualSystem/@id + + RTCString strDescription; // copy of VirtualSystem/AnnotationSection content, if any + + CIMOSType_T cimos; + RTCString strCimosDesc; // readable description of the cimos type in the case of cimos = 0/1/102 + RTCString strTypeVBox; // optional type from @vbox:ostype attribute (VirtualBox 4.0 or higher) + + RTCString strVirtualSystemType; // generic hardware description; OVF says this can be something like "vmx-4" or "xen"; + // VMware Workstation 6.5 is "vmx-07" + + HardwareItemVector vecHardwareItems; //< vector containing all virtual hardware items in parsing order. + + uint64_t ullMemorySize; // always in bytes, copied from llHardwareItems; default = 0 (unspecified) + uint16_t cCPUs; // no. of CPUs, copied from llHardwareItems; default = 1 + + EthernetAdaptersList llEthernetAdapters; // (one for each VirtualSystem/Item[@ResourceType=10]element) + + ControllersMap mapControllers; + // list of hard disk controllers + // (one for each VirtualSystem/Item[@ResourceType=6] element with accumulated data from children) + + VirtualDisksMap mapVirtualDisks; + // (one for each VirtualSystem/Item[@ResourceType=17] element with accumulated data from children) + + bool fHasFloppyDrive; // true if there's a floppy item in mapHardwareItems + bool fHasCdromDrive; // true if there's a CD-ROM item in mapHardwareItems; ISO images are not yet supported by OVFtool + bool fHasUsbController; // true if there's a USB controller item in mapHardwareItems + + RTCString strSoundCardType; // if not empty, then the system wants a soundcard; this then specifies the hardware; + // VMware Workstation 6.5 uses "ensoniq1371" for example + + RTCString strLicenseText; // license info if any; receives contents of VirtualSystem/EulaSection/License + + RTCString strProduct; // product info if any; receives contents of VirtualSystem/ProductSection/Product + RTCString strVendor; // product info if any; receives contents of VirtualSystem/ProductSection/Vendor + RTCString strVersion; // product info if any; receives contents of VirtualSystem/ProductSection/Version + RTCString strProductUrl; // product info if any; receives contents of VirtualSystem/ProductSection/ProductUrl + RTCString strVendorUrl; // product info if any; receives contents of VirtualSystem/ProductSection/VendorUrl + + const xml::ElementNode *pelmVBoxMachine; // pointer to <vbox:Machine> element under <VirtualSystem> element or NULL if not present + + VirtualSystem() + : cimos(CIMOSType_CIMOS_Unknown), + ullMemorySize(0), + cCPUs(1), + fHasFloppyDrive(false), + fHasCdromDrive(false), + fHasUsbController(false), + pelmVBoxMachine(NULL) + { + } +}; + +//////////////////////////////////////////////////////////////////////////////// +// +// Class OVFReader +// +//////////////////////////////////////////////////////////////////////////////// + +/** + * OVFReader attempts to open, read in and parse an OVF XML file. This is all done + * in the constructor; if there is any kind of error in the file -- filesystem error + * from IPRT, XML parsing errors from libxml, or OVF logical errors --, exceptions + * are thrown. These are all based on xml::Error. + * + * Hence, use this class as follows: +<code> + OVFReader *pReader = NULL; + try + { + pReader = new("/path/to/file.ovf"); + } + catch (xml::Error &e) + { + printf("A terrible thing happened: %s", e.what()); + } + // now go look at pReader->m_llVirtualSystem and what's in there + if (pReader) + delete pReader; +</code> + */ +class OVFReader +{ +public: + OVFReader(); + OVFReader(const void *pvBuf, size_t cbSize, const RTCString &path); + OVFReader(const RTCString &path); + + // Data fields + EnvelopeData m_envelopeData; //data of root element "Envelope" + RTCString m_strPath; // file name given to constructor + DiskImagesMap m_mapDisks; // map of DiskImage structs, sorted by DiskImage.strDiskId + std::list<VirtualSystem> m_llVirtualSystems; // list of virtual systems, created by and valid after read() + +private: + xml::Document m_doc; + + void parse(); + void LoopThruSections(const xml::ElementNode *pReferencesElem, const xml::ElementNode *pCurElem); + void HandleDiskSection(const xml::ElementNode *pReferencesElem, const xml::ElementNode *pSectionElem); + void HandleNetworkSection(const xml::ElementNode *pSectionElem); + void HandleVirtualSystemContent(const xml::ElementNode *pContentElem); +}; + +} // end namespace ovf + +#endif /* !MAIN_INCLUDED_ovfreader_h */ + |