VirtualBox

Changeset 28098 in vbox for trunk


Ignore:
Timestamp:
Apr 8, 2010 3:35:38 PM (15 years ago)
Author:
vboxsync
Message:

Main: don't export snapshots in OVF, separate OVF import from vbox:Machine import

Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/settings.h

    r27918 r28098  
    856856
    857857    void write(const com::Utf8Str &strFilename);
    858     void buildMachineXML(xml::ElementNode &elmMachine);
     858    void buildMachineXML(xml::ElementNode &elmMachine, bool fIncludeSnapshots);
    859859
    860860private:
  • trunk/src/VBox/Main/ApplianceImplExport.cpp

    r27908 r28098  
    12281228        AutoWriteLock machineLock(vsdescThis->m->pMachine COMMA_LOCKVAL_SRC_POS);
    12291229        vsdescThis->m->pMachine->copyMachineDataToSettings(*pConfig);
    1230         pConfig->buildMachineXML(*pelmVBoxMachine);
     1230        pConfig->buildMachineXML(*pelmVBoxMachine,
     1231                                 false /* fIncludeSnapshots */);
    12311232        delete pConfig;
    12321233    }
  • trunk/src/VBox/Main/ApplianceImplImport.cpp

    r27918 r28098  
    952952
    953953/**
     954 * Used by Appliance::importMachineGeneric() to store
     955 * input parameters and rollback information.
     956 */
     957struct Appliance::ImportStack
     958{
     959    // input pointers
     960    const LocationInfo          &locInfo;           // ptr to location info from Appliance::importFS()
     961    const ovf::DiskImagesMap    &mapDisks;          // ptr to disks map in OVF
     962    ComObjPtr<Progress>         &pProgress;         // progress object passed into Appliance::importFS()
     963
     964    // session (not initially created)
     965    ComPtr<ISession>            pSession;           // session opened in Appliance::importFS() for machine manipulation
     966    bool                        fSessionOpen;       // true if the pSession is currently open and needs closing
     967
     968    // a list of images that we created/imported; this is initially empty
     969    // and will be cleaned up on errors
     970    list<MyHardDiskAttachment>  llHardDiskAttachments;      // disks that were attached
     971    list< ComPtr<IMedium> >     llHardDisksCreated;         // media that were created
     972    list<Bstr>                  llMachinesRegistered;       // machines that were registered; list of string UUIDs
     973
     974    ImportStack(const LocationInfo &aLocInfo,
     975                const ovf::DiskImagesMap &aMapDisks,
     976                ComObjPtr<Progress> &aProgress)
     977        : locInfo(aLocInfo),
     978          mapDisks(aMapDisks),
     979          pProgress(aProgress),
     980          fSessionOpen(false)
     981    {
     982    }
     983};
     984
     985/**
    954986 * Actual worker code for importing OVF data into VirtualBox. This is called from Appliance::taskThreadImportOrExport()
    955987 * and therefore runs on the OVF import worker thread. This runs in two contexts:
     
    963995 * @return
    964996 */
    965 HRESULT Appliance::importFS(const LocationInfo &locInfo, ComObjPtr<Progress> &pProgress)
     997HRESULT Appliance::importFS(const LocationInfo &locInfo,
     998                            ComObjPtr<Progress> &pProgress)
    966999{
    9671000    LogFlowFuncEnter();
     
    9751008    if (!isApplianceIdle())
    9761009        return E_ACCESSDENIED;
     1010
     1011    Assert(!pProgress.isNull());
    9771012
    9781013    // Change the appliance state so we can safely leave the lock while doing time-consuming
     
    9841019    HRESULT rc = S_OK;
    9851020
    986     // rollback for errors:
    987     // a list of images that we created/imported
    988     list<MyHardDiskAttachment> llHardDiskAttachments;
    989     list< ComPtr<IMedium> > llHardDisksCreated;
    990     list<Bstr> llMachinesRegistered;            // list of string UUIDs
    991 
    992     ComPtr<ISession> session;
    993     bool fSessionOpen = false;
    994     rc = session.createInprocObject(CLSID_Session);
    995     if (FAILED(rc)) return rc;
    996 
    9971021    const ovf::OVFReader &reader = *m->pReader;
    9981022    // this is safe to access because this thread only gets started
    9991023    // if pReader != NULL
    10001024
    1001     /* If an manifest file exists, verify the content. Therefore we need all
     1025    // rollback for errors:
     1026    ImportStack stack(locInfo, reader.m_mapDisks, pProgress);
     1027    /* If a manifest file exists, verify the content. Therefore we need all
    10021028     * files which are referenced by the OVF & the OVF itself */
    10031029    Utf8Str strMfFile = manifestFileName(locInfo.strPath);
     
    10651091    }
    10661092
     1093    rc = stack.pSession.createInprocObject(CLSID_Session);
     1094    if (FAILED(rc)) return rc;
     1095
    10671096    list<ovf::VirtualSystem>::const_iterator it;
    10681097    list< ComObjPtr<VirtualSystemDescription> >::const_iterator it1;
     
    10701099    size_t i = 0;
    10711100    for (it = reader.m_llVirtualSystems.begin(),
    1072          it1 = m->virtualSystemDescriptions.begin();
     1101            it1 = m->virtualSystemDescriptions.begin();
    10731102         it != reader.m_llVirtualSystems.end();
    10741103         ++it, ++it1, ++i)
     
    10821111        try
    10831112        {
    1084             // there are two ways in which we can create
    1085 
    1086             /* Guest OS type */
    1087             std::list<VirtualSystemDescriptionEntry*> vsdeOS;
    1088             vsdeOS = vsdescThis->findByType(VirtualSystemDescriptionType_OS);
    1089             if (vsdeOS.size() < 1)
    1090                 throw setError(VBOX_E_FILE_ERROR,
    1091                                tr("Missing guest OS type"));
    1092             const Utf8Str &strOsTypeVBox = vsdeOS.front()->strVbox;
    1093 
    1094             /* Now that we know the base system get our internal defaults based on that. */
    1095             ComPtr<IGuestOSType> osType;
    1096             rc = mVirtualBox->GetGuestOSType(Bstr(strOsTypeVBox), osType.asOutParam());
    1097             if (FAILED(rc)) throw rc;
    1098 
    1099             /* Create the machine */
    1100             /* First get the name */
    1101             std::list<VirtualSystemDescriptionEntry*> vsdeName = vsdescThis->findByType(VirtualSystemDescriptionType_Name);
    1102             if (vsdeName.size() < 1)
    1103                 throw setError(VBOX_E_FILE_ERROR,
    1104                                tr("Missing VM name"));
    1105             const Utf8Str &strNameVBox = vsdeName.front()->strVbox;
    1106             rc = mVirtualBox->CreateMachine(Bstr(strNameVBox),
    1107                                             Bstr(strOsTypeVBox),
    1108                                             NULL,
    1109                                             NULL,
    1110                                             FALSE,
    1111                                             pNewMachine.asOutParam());
    1112             if (FAILED(rc)) throw rc;
    1113 
    1114             // and the description
    1115             std::list<VirtualSystemDescriptionEntry*> vsdeDescription = vsdescThis->findByType(VirtualSystemDescriptionType_Description);
    1116             if (vsdeDescription.size())
    1117             {
    1118                 const Utf8Str &strDescription = vsdeDescription.front()->strVbox;
    1119                 rc = pNewMachine->COMSETTER(Description)(Bstr(strDescription));
    1120                 if (FAILED(rc)) throw rc;
    1121             }
    1122 
    1123             /* CPU count */
    1124             std::list<VirtualSystemDescriptionEntry*> vsdeCPU = vsdescThis->findByType(VirtualSystemDescriptionType_CPU);
    1125             ComAssertMsgThrow(vsdeCPU.size() == 1, ("CPU count missing"), E_FAIL);
    1126             const Utf8Str &cpuVBox = vsdeCPU.front()->strVbox;
    1127             ULONG tmpCount = (ULONG)RTStrToUInt64(cpuVBox.c_str());
    1128             rc = pNewMachine->COMSETTER(CPUCount)(tmpCount);
    1129             if (FAILED(rc)) throw rc;
    1130             bool fEnableIOApic = false;
    1131             /* We need HWVirt & IO-APIC if more than one CPU is requested */
    1132             if (tmpCount > 1)
    1133             {
    1134                 rc = pNewMachine->SetHWVirtExProperty(HWVirtExPropertyType_Enabled, TRUE);
    1135                 if (FAILED(rc)) throw rc;
    1136 
    1137                 fEnableIOApic = true;
    1138             }
    1139 
    1140             /* RAM */
    1141             std::list<VirtualSystemDescriptionEntry*> vsdeRAM = vsdescThis->findByType(VirtualSystemDescriptionType_Memory);
    1142             ComAssertMsgThrow(vsdeRAM.size() == 1, ("RAM size missing"), E_FAIL);
    1143             const Utf8Str &memoryVBox = vsdeRAM.front()->strVbox;
    1144             ULONG tt = (ULONG)RTStrToUInt64(memoryVBox.c_str());
    1145             rc = pNewMachine->COMSETTER(MemorySize)(tt);
    1146             if (FAILED(rc)) throw rc;
    1147 
    1148             /* VRAM */
    1149             /* Get the recommended VRAM for this guest OS type */
    1150             ULONG vramVBox;
    1151             rc = osType->COMGETTER(RecommendedVRAM)(&vramVBox);
    1152             if (FAILED(rc)) throw rc;
    1153 
    1154             /* Set the VRAM */
    1155             rc = pNewMachine->COMSETTER(VRAMSize)(vramVBox);
    1156             if (FAILED(rc)) throw rc;
    1157 
    1158             /* I/O APIC: so far we have no setting for this. Enable it if we
    1159               import a Windows VM because if if Windows was installed without IOAPIC,
    1160               it will not mind finding an one later on, but if Windows was installed
    1161               _with_ an IOAPIC, it will bluescreen if it's not found */
    1162             Bstr bstrFamilyId;
    1163             rc = osType->COMGETTER(FamilyId)(bstrFamilyId.asOutParam());
    1164             if (FAILED(rc)) throw rc;
    1165 
    1166             Utf8Str strFamilyId(bstrFamilyId);
    1167             if (strFamilyId == "Windows")
    1168                 fEnableIOApic = true;
    1169 
    1170             /* If IP-APIC should be enabled could be have different reasons.
    1171                See CPU count & the Win test above. Here we enable it if it was
    1172                previously requested. */
    1173             if (fEnableIOApic)
    1174             {
    1175                 ComPtr<IBIOSSettings> pBIOSSettings;
    1176                 rc = pNewMachine->COMGETTER(BIOSSettings)(pBIOSSettings.asOutParam());
    1177                 if (FAILED(rc)) throw rc;
    1178 
    1179                 rc = pBIOSSettings->COMSETTER(IOAPICEnabled)(TRUE);
    1180                 if (FAILED(rc)) throw rc;
    1181             }
    1182 
    1183             /* Audio Adapter */
    1184             std::list<VirtualSystemDescriptionEntry*> vsdeAudioAdapter = vsdescThis->findByType(VirtualSystemDescriptionType_SoundCard);
    1185             /* @todo: we support one audio adapter only */
    1186             if (vsdeAudioAdapter.size() > 0)
    1187             {
    1188                 const Utf8Str& audioAdapterVBox = vsdeAudioAdapter.front()->strVbox;
    1189                 if (audioAdapterVBox.compare("null", Utf8Str::CaseInsensitive) != 0)
    1190                 {
    1191                     uint32_t audio = RTStrToUInt32(audioAdapterVBox.c_str());
    1192                     ComPtr<IAudioAdapter> audioAdapter;
    1193                     rc = pNewMachine->COMGETTER(AudioAdapter)(audioAdapter.asOutParam());
    1194                     if (FAILED(rc)) throw rc;
    1195                     rc = audioAdapter->COMSETTER(Enabled)(true);
    1196                     if (FAILED(rc)) throw rc;
    1197                     rc = audioAdapter->COMSETTER(AudioController)(static_cast<AudioControllerType_T>(audio));
    1198                     if (FAILED(rc)) throw rc;
    1199                 }
    1200             }
    1201 
    1202 #ifdef VBOX_WITH_USB
    1203             /* USB Controller */
    1204             std::list<VirtualSystemDescriptionEntry*> vsdeUSBController = vsdescThis->findByType(VirtualSystemDescriptionType_USBController);
    1205             // USB support is enabled if there's at least one such entry; to disable USB support,
    1206             // the type of the USB item would have been changed to "ignore"
    1207             bool fUSBEnabled = vsdeUSBController.size() > 0;
    1208 
    1209             ComPtr<IUSBController> usbController;
    1210             rc = pNewMachine->COMGETTER(USBController)(usbController.asOutParam());
    1211             if (FAILED(rc)) throw rc;
    1212             rc = usbController->COMSETTER(Enabled)(fUSBEnabled);
    1213             if (FAILED(rc)) throw rc;
    1214 #endif /* VBOX_WITH_USB */
    1215 
    1216             /* Change the network adapters */
    1217             std::list<VirtualSystemDescriptionEntry*> vsdeNW = vsdescThis->findByType(VirtualSystemDescriptionType_NetworkAdapter);
    1218             if (vsdeNW.size() == 0)
    1219             {
    1220                 /* No network adapters, so we have to disable our default one */
    1221                 ComPtr<INetworkAdapter> nwVBox;
    1222                 rc = pNewMachine->GetNetworkAdapter(0, nwVBox.asOutParam());
    1223                 if (FAILED(rc)) throw rc;
    1224                 rc = nwVBox->COMSETTER(Enabled)(false);
    1225                 if (FAILED(rc)) throw rc;
    1226             }
     1113            // there are two ways in which we can create a vbox machine from OVF:
     1114            // -- either this OVF was written by vbox 3.2 or later, in which case there is a <vbox:Machine> element
     1115            //    in the <VirtualSystem>; then the VirtualSystemDescription::Data has a settings::MachineConfigFile
     1116            //    with all the machine config pretty-parsed;
     1117            // -- or this is an OVF from an older vbox or an external source, and then we need to translate the
     1118            //    VirtualSystemDescriptionEntry and do import work
     1119
     1120            // @todo r=dj make this selection configurable at run-time, and from the GUI as well
     1121
     1122            if (vsdescThis->m->pConfig)
     1123                importVBoxMachine(*vsdescThis->m->pConfig, pNewMachine, stack);
    12271124            else
    1228             {
    1229                 list<VirtualSystemDescriptionEntry*>::const_iterator nwIt;
    1230                 /* Iterate through all network cards. We support 8 network adapters
    1231                  * at the maximum. (@todo: warn if there are more!) */
    1232                 size_t a = 0;
    1233                 for (nwIt = vsdeNW.begin();
    1234                      (nwIt != vsdeNW.end() && a < SchemaDefs::NetworkAdapterCount);
    1235                      ++nwIt, ++a)
    1236                 {
    1237                     const VirtualSystemDescriptionEntry* pvsys = *nwIt;
    1238 
    1239                     const Utf8Str &nwTypeVBox = pvsys->strVbox;
    1240                     uint32_t tt1 = RTStrToUInt32(nwTypeVBox.c_str());
    1241                     ComPtr<INetworkAdapter> pNetworkAdapter;
    1242                     rc = pNewMachine->GetNetworkAdapter((ULONG)a, pNetworkAdapter.asOutParam());
    1243                     if (FAILED(rc)) throw rc;
    1244                     /* Enable the network card & set the adapter type */
    1245                     rc = pNetworkAdapter->COMSETTER(Enabled)(true);
    1246                     if (FAILED(rc)) throw rc;
    1247                     rc = pNetworkAdapter->COMSETTER(AdapterType)(static_cast<NetworkAdapterType_T>(tt1));
    1248                     if (FAILED(rc)) throw rc;
    1249 
    1250                     // default is NAT; change to "bridged" if extra conf says so
    1251                     if (!pvsys->strExtraConfig.compare("type=Bridged", Utf8Str::CaseInsensitive))
    1252                     {
    1253                         /* Attach to the right interface */
    1254                         rc = pNetworkAdapter->AttachToBridgedInterface();
    1255                         if (FAILED(rc)) throw rc;
    1256                         ComPtr<IHost> host;
    1257                         rc = mVirtualBox->COMGETTER(Host)(host.asOutParam());
    1258                         if (FAILED(rc)) throw rc;
    1259                         com::SafeIfaceArray<IHostNetworkInterface> nwInterfaces;
    1260                         rc = host->COMGETTER(NetworkInterfaces)(ComSafeArrayAsOutParam(nwInterfaces));
    1261                         if (FAILED(rc)) throw rc;
    1262                         /* We search for the first host network interface which
    1263                          * is usable for bridged networking */
    1264                         for (size_t j = 0;
    1265                              j < nwInterfaces.size();
    1266                              ++j)
    1267                         {
    1268                             HostNetworkInterfaceType_T itype;
    1269                             rc = nwInterfaces[j]->COMGETTER(InterfaceType)(&itype);
    1270                             if (FAILED(rc)) throw rc;
    1271                             if (itype == HostNetworkInterfaceType_Bridged)
    1272                             {
    1273                                 Bstr name;
    1274                                 rc = nwInterfaces[j]->COMGETTER(Name)(name.asOutParam());
    1275                                 if (FAILED(rc)) throw rc;
    1276                                 /* Set the interface name to attach to */
    1277                                 pNetworkAdapter->COMSETTER(HostInterface)(name);
    1278                                 if (FAILED(rc)) throw rc;
    1279                                 break;
    1280                             }
    1281                         }
    1282                     }
    1283                     /* Next test for host only interfaces */
    1284                     else if (!pvsys->strExtraConfig.compare("type=HostOnly", Utf8Str::CaseInsensitive))
    1285                     {
    1286                         /* Attach to the right interface */
    1287                         rc = pNetworkAdapter->AttachToHostOnlyInterface();
    1288                         if (FAILED(rc)) throw rc;
    1289                         ComPtr<IHost> host;
    1290                         rc = mVirtualBox->COMGETTER(Host)(host.asOutParam());
    1291                         if (FAILED(rc)) throw rc;
    1292                         com::SafeIfaceArray<IHostNetworkInterface> nwInterfaces;
    1293                         rc = host->COMGETTER(NetworkInterfaces)(ComSafeArrayAsOutParam(nwInterfaces));
    1294                         if (FAILED(rc)) throw rc;
    1295                         /* We search for the first host network interface which
    1296                          * is usable for host only networking */
    1297                         for (size_t j = 0;
    1298                              j < nwInterfaces.size();
    1299                              ++j)
    1300                         {
    1301                             HostNetworkInterfaceType_T itype;
    1302                             rc = nwInterfaces[j]->COMGETTER(InterfaceType)(&itype);
    1303                             if (FAILED(rc)) throw rc;
    1304                             if (itype == HostNetworkInterfaceType_HostOnly)
    1305                             {
    1306                                 Bstr name;
    1307                                 rc = nwInterfaces[j]->COMGETTER(Name)(name.asOutParam());
    1308                                 if (FAILED(rc)) throw rc;
    1309                                 /* Set the interface name to attach to */
    1310                                 pNetworkAdapter->COMSETTER(HostInterface)(name);
    1311                                 if (FAILED(rc)) throw rc;
    1312                                 break;
    1313                             }
    1314                         }
    1315                     }
    1316                 }
    1317             }
    1318 
    1319             /* Hard disk controller IDE */
    1320             std::list<VirtualSystemDescriptionEntry*> vsdeHDCIDE = vsdescThis->findByType(VirtualSystemDescriptionType_HardDiskControllerIDE);
    1321             if (vsdeHDCIDE.size() > 1)
    1322                 throw setError(VBOX_E_FILE_ERROR,
    1323                                tr("Too many IDE controllers in OVF; import facility only supports one"));
    1324             if (vsdeHDCIDE.size() == 1)
    1325             {
    1326                 ComPtr<IStorageController> pController;
    1327                 rc = pNewMachine->AddStorageController(Bstr("IDE Controller"), StorageBus_IDE, pController.asOutParam());
    1328                 if (FAILED(rc)) throw rc;
    1329 
    1330                 const char *pcszIDEType = vsdeHDCIDE.front()->strVbox.c_str();
    1331                 if (!strcmp(pcszIDEType, "PIIX3"))
    1332                     rc = pController->COMSETTER(ControllerType)(StorageControllerType_PIIX3);
    1333                 else if (!strcmp(pcszIDEType, "PIIX4"))
    1334                     rc = pController->COMSETTER(ControllerType)(StorageControllerType_PIIX4);
    1335                 else if (!strcmp(pcszIDEType, "ICH6"))
    1336                     rc = pController->COMSETTER(ControllerType)(StorageControllerType_ICH6);
    1337                 else
    1338                     throw setError(VBOX_E_FILE_ERROR,
    1339                                    tr("Invalid IDE controller type \"%s\""),
    1340                                    pcszIDEType);
    1341                 if (FAILED(rc)) throw rc;
    1342             }
    1343 #ifdef VBOX_WITH_AHCI
    1344             /* Hard disk controller SATA */
    1345             std::list<VirtualSystemDescriptionEntry*> vsdeHDCSATA = vsdescThis->findByType(VirtualSystemDescriptionType_HardDiskControllerSATA);
    1346             if (vsdeHDCSATA.size() > 1)
    1347                 throw setError(VBOX_E_FILE_ERROR,
    1348                                tr("Too many SATA controllers in OVF; import facility only supports one"));
    1349             if (vsdeHDCSATA.size() > 0)
    1350             {
    1351                 ComPtr<IStorageController> pController;
    1352                 const Utf8Str &hdcVBox = vsdeHDCSATA.front()->strVbox;
    1353                 if (hdcVBox == "AHCI")
    1354                 {
    1355                     rc = pNewMachine->AddStorageController(Bstr("SATA Controller"), StorageBus_SATA, pController.asOutParam());
    1356                     if (FAILED(rc)) throw rc;
    1357                 }
    1358                 else
    1359                     throw setError(VBOX_E_FILE_ERROR,
    1360                                    tr("Invalid SATA controller type \"%s\""),
    1361                                    hdcVBox.c_str());
    1362             }
    1363 #endif /* VBOX_WITH_AHCI */
    1364 
    1365 #ifdef VBOX_WITH_LSILOGIC
    1366             /* Hard disk controller SCSI */
    1367             std::list<VirtualSystemDescriptionEntry*> vsdeHDCSCSI = vsdescThis->findByType(VirtualSystemDescriptionType_HardDiskControllerSCSI);
    1368             if (vsdeHDCSCSI.size() > 1)
    1369                 throw setError(VBOX_E_FILE_ERROR,
    1370                                tr("Too many SCSI controllers in OVF; import facility only supports one"));
    1371             if (vsdeHDCSCSI.size() > 0)
    1372             {
    1373                 ComPtr<IStorageController> pController;
    1374                 StorageControllerType_T controllerType;
    1375                 const Utf8Str &hdcVBox = vsdeHDCSCSI.front()->strVbox;
    1376                 if (hdcVBox == "LsiLogic")
    1377                     controllerType = StorageControllerType_LsiLogic;
    1378                 else if (hdcVBox == "BusLogic")
    1379                     controllerType = StorageControllerType_BusLogic;
    1380                 else
    1381                     throw setError(VBOX_E_FILE_ERROR,
    1382                                    tr("Invalid SCSI controller type \"%s\""),
    1383                                    hdcVBox.c_str());
    1384 
    1385                 rc = pNewMachine->AddStorageController(Bstr("SCSI Controller"), StorageBus_SCSI, pController.asOutParam());
    1386                 if (FAILED(rc)) throw rc;
    1387                 rc = pController->COMSETTER(ControllerType)(controllerType);
    1388                 if (FAILED(rc)) throw rc;
    1389             }
    1390 #endif /* VBOX_WITH_LSILOGIC */
    1391 
    1392             /* Now its time to register the machine before we add any hard disks */
    1393             rc = mVirtualBox->RegisterMachine(pNewMachine);
    1394             if (FAILED(rc)) throw rc;
    1395 
    1396             Bstr bstrNewMachineId;
    1397             rc = pNewMachine->COMGETTER(Id)(bstrNewMachineId.asOutParam());
    1398             if (FAILED(rc)) throw rc;
    1399 
    1400             // store new machine for roll-back in case of errors
    1401             llMachinesRegistered.push_back(bstrNewMachineId);
    1402 
    1403             // Add floppies and CD-ROMs to the appropriate controllers.
    1404             std::list<VirtualSystemDescriptionEntry*> vsdeFloppy = vsdescThis->findByType(VirtualSystemDescriptionType_Floppy);
    1405             if (vsdeFloppy.size() > 1)
    1406                 throw setError(VBOX_E_FILE_ERROR,
    1407                                tr("Too many floppy controllers in OVF; import facility only supports one"));
    1408             std::list<VirtualSystemDescriptionEntry*> vsdeCDROM = vsdescThis->findByType(VirtualSystemDescriptionType_CDROM);
    1409             if (    (vsdeFloppy.size() > 0)
    1410                  || (vsdeCDROM.size() > 0)
    1411                )
    1412             {
    1413                 // If there's an error here we need to close the session, so
    1414                 // we need another try/catch block.
    1415 
    1416                 try
    1417                 {
    1418                     /* In order to attach things we need to open a session
    1419                      * for the new machine */
    1420                     rc = mVirtualBox->OpenSession(session, bstrNewMachineId);
    1421                     if (FAILED(rc)) throw rc;
    1422                     fSessionOpen = true;
    1423 
    1424                     ComPtr<IMachine> sMachine;
    1425                     rc = session->COMGETTER(Machine)(sMachine.asOutParam());
    1426                     if (FAILED(rc)) throw rc;
    1427 
    1428                     // floppy first
    1429                     if (vsdeFloppy.size() == 1)
    1430                     {
    1431                         ComPtr<IStorageController> pController;
    1432                         rc = sMachine->AddStorageController(Bstr("Floppy Controller"), StorageBus_Floppy, pController.asOutParam());
    1433                         if (FAILED(rc)) throw rc;
    1434 
    1435                         Bstr bstrName;
    1436                         rc = pController->COMGETTER(Name)(bstrName.asOutParam());
    1437                         if (FAILED(rc)) throw rc;
    1438 
    1439                         // this is for rollback later
    1440                         MyHardDiskAttachment mhda;
    1441                         mhda.bstrUuid = bstrNewMachineId;
    1442                         mhda.pMachine = pNewMachine;
    1443                         mhda.controllerType = bstrName;
    1444                         mhda.lChannel = 0;
    1445                         mhda.lDevice = 0;
    1446 
    1447                         Log(("Attaching floppy\n"));
    1448 
    1449                         rc = sMachine->AttachDevice(mhda.controllerType,
    1450                                                     mhda.lChannel,
    1451                                                     mhda.lDevice,
    1452                                                     DeviceType_Floppy,
    1453                                                     NULL);
    1454                         if (FAILED(rc)) throw rc;
    1455 
    1456                         llHardDiskAttachments.push_back(mhda);
    1457                     }
    1458 
    1459 
    1460                     // CD-ROMs next
    1461                     for (std::list<VirtualSystemDescriptionEntry*>::const_iterator jt = vsdeCDROM.begin();
    1462                          jt != vsdeCDROM.end();
    1463                          ++jt)
    1464                     {
    1465                         // for now always attach to secondary master on IDE controller;
    1466                         // there seems to be no useful information in OVF where else to
    1467                         // attach jt (@todo test with latest versions of OVF software)
    1468 
    1469                         // find the IDE controller
    1470                         const ovf::HardDiskController *pController = NULL;
    1471                         for (ovf::ControllersMap::const_iterator kt = vsysThis.mapControllers.begin();
    1472                              kt != vsysThis.mapControllers.end();
    1473                              ++kt)
    1474                         {
    1475                             if (kt->second.system == ovf::HardDiskController::IDE)
    1476                             {
    1477                                 pController = &kt->second;
    1478                             }
    1479                         }
    1480 
    1481                         if (!pController)
    1482                             throw setError(VBOX_E_FILE_ERROR,
    1483                                            tr("OVF wants a CD-ROM drive but cannot find IDE controller, which is required in this version of VirtualBox"));
    1484 
    1485                         // this is for rollback later
    1486                         MyHardDiskAttachment mhda;
    1487                         mhda.bstrUuid = bstrNewMachineId;
    1488                         mhda.pMachine = pNewMachine;
    1489 
    1490                         convertDiskAttachmentValues(*pController,
    1491                                                     2,     // interpreted as secondary master
    1492                                                     mhda.controllerType,        // Bstr
    1493                                                     mhda.lChannel,
    1494                                                     mhda.lDevice);
    1495 
    1496                         Log(("Attaching CD-ROM to channel %d on device %d\n", mhda.lChannel, mhda.lDevice));
    1497 
    1498                         rc = sMachine->AttachDevice(mhda.controllerType,
    1499                                                     mhda.lChannel,
    1500                                                     mhda.lDevice,
    1501                                                     DeviceType_DVD,
    1502                                                     NULL);
    1503                         if (FAILED(rc)) throw rc;
    1504 
    1505                         llHardDiskAttachments.push_back(mhda);
    1506                     } // end for (itHD = avsdeHDs.begin();
    1507 
    1508                     rc = sMachine->SaveSettings();
    1509                     if (FAILED(rc)) throw rc;
    1510 
    1511                     // only now that we're done with all disks, close the session
    1512                     rc = session->Close();
    1513                     if (FAILED(rc)) throw rc;
    1514                     fSessionOpen = false;
    1515                 }
    1516                 catch(HRESULT /* aRC */)
    1517                 {
    1518                     if (fSessionOpen)
    1519                         session->Close();
    1520 
    1521                     throw;
    1522                 }
    1523             }
    1524 
    1525             /* Create the hard disks & connect them to the appropriate controllers. */
    1526             std::list<VirtualSystemDescriptionEntry*> avsdeHDs = vsdescThis->findByType(VirtualSystemDescriptionType_HardDiskImage);
    1527             if (avsdeHDs.size() > 0)
    1528             {
    1529                 // If there's an error here we need to close the session, so
    1530                 // we need another try/catch block.
    1531                 ComPtr<IMedium> srcHdVBox;
    1532                 bool fSourceHdNeedsClosing = false;
    1533 
    1534                 try
    1535                 {
    1536                     /* In order to attach hard disks we need to open a session
    1537                      * for the new machine */
    1538                     rc = mVirtualBox->OpenSession(session, bstrNewMachineId);
    1539                     if (FAILED(rc)) throw rc;
    1540                     fSessionOpen = true;
    1541 
    1542                     /* The disk image has to be on the same place as the OVF file. So
    1543                      * strip the filename out of the full file path. */
    1544                     Utf8Str strSrcDir(locInfo.strPath);
    1545                     strSrcDir.stripFilename();
    1546 
    1547                     /* Iterate over all given disk images */
    1548                     list<VirtualSystemDescriptionEntry*>::const_iterator itHD;
    1549                     for (itHD = avsdeHDs.begin();
    1550                          itHD != avsdeHDs.end();
    1551                          ++itHD)
    1552                     {
    1553                         VirtualSystemDescriptionEntry *vsdeHD = *itHD;
    1554 
    1555                         /* Check if the destination file exists already or the
    1556                          * destination path is empty. */
    1557                         if (    vsdeHD->strVbox.isEmpty()
    1558                              || RTPathExists(vsdeHD->strVbox.c_str())
    1559                            )
    1560                             /* This isn't allowed */
    1561                             throw setError(VBOX_E_FILE_ERROR,
    1562                                            tr("Destination file '%s' exists",
    1563                                               vsdeHD->strVbox.c_str()));
    1564 
    1565                         /* Find the disk from the OVF's disk list */
    1566                         ovf::DiskImagesMap::const_iterator itDiskImage = reader.m_mapDisks.find(vsdeHD->strRef);
    1567                         /* vsdeHD->strRef contains the disk identifier (e.g. "vmdisk1"), which should exist
    1568                            in the virtual system's disks map under that ID and also in the global images map. */
    1569                         ovf::VirtualDisksMap::const_iterator itVirtualDisk = vsysThis.mapVirtualDisks.find(vsdeHD->strRef);
    1570 
    1571                         if (    itDiskImage == reader.m_mapDisks.end()
    1572                              || itVirtualDisk == vsysThis.mapVirtualDisks.end()
    1573                            )
    1574                             throw setError(E_FAIL,
    1575                                            tr("Internal inconsistency looking up disk images."));
    1576 
    1577                         const ovf::DiskImage &di = itDiskImage->second;
    1578                         const ovf::VirtualDisk &vd = itVirtualDisk->second;
    1579 
    1580                         /* Make sure all target directories exists */
    1581                         rc = VirtualBox::ensureFilePathExists(vsdeHD->strVbox.c_str());
    1582                         if (FAILED(rc))
    1583                             throw rc;
    1584 
    1585                         // subprogress object for hard disk
    1586                         ComPtr<IProgress> pProgress2;
    1587 
    1588                         ComPtr<IMedium> dstHdVBox;
    1589                         /* If strHref is empty we have to create a new file */
    1590                         if (di.strHref.isEmpty())
    1591                         {
    1592                             /* Which format to use? */
    1593                             Bstr srcFormat = L"VDI";
    1594                             if (   di.strFormat.compare("http://www.vmware.com/specifications/vmdk.html#sparse", Utf8Str::CaseInsensitive)
    1595                                 || di.strFormat.compare("http://www.vmware.com/specifications/vmdk.html#compressed", Utf8Str::CaseInsensitive))
    1596                                 srcFormat = L"VMDK";
    1597                             /* Create an empty hard disk */
    1598                             rc = mVirtualBox->CreateHardDisk(srcFormat, Bstr(vsdeHD->strVbox), dstHdVBox.asOutParam());
    1599                             if (FAILED(rc)) throw rc;
    1600 
    1601                             /* Create a dynamic growing disk image with the given capacity */
    1602                             rc = dstHdVBox->CreateBaseStorage(di.iCapacity / _1M, MediumVariant_Standard, pProgress2.asOutParam());
    1603                             if (FAILED(rc)) throw rc;
    1604 
    1605                             /* Advance to the next operation */
    1606                             if (!pProgress.isNull())
    1607                                 pProgress->SetNextOperation(BstrFmt(tr("Creating virtual disk image '%s'"), vsdeHD->strVbox.c_str()),
    1608                                                             vsdeHD->ulSizeMB);     // operation's weight, as set up with the IProgress originally
    1609                         }
    1610                         else
    1611                         {
    1612                             /* Construct the source file path */
    1613                             Utf8StrFmt strSrcFilePath("%s%c%s", strSrcDir.c_str(), RTPATH_DELIMITER, di.strHref.c_str());
    1614                             /* Check if the source file exists */
    1615                             if (!RTPathExists(strSrcFilePath.c_str()))
    1616                                 /* This isn't allowed */
    1617                                 throw setError(VBOX_E_FILE_ERROR,
    1618                                                tr("Source virtual disk image file '%s' doesn't exist"),
    1619                                                   strSrcFilePath.c_str());
    1620 
    1621                             /* Clone the disk image (this is necessary cause the id has
    1622                              * to be recreated for the case the same hard disk is
    1623                              * attached already from a previous import) */
    1624 
    1625                             /* First open the existing disk image */
    1626                             rc = mVirtualBox->OpenHardDisk(Bstr(strSrcFilePath),
    1627                                                            AccessMode_ReadOnly,
    1628                                                            false,
    1629                                                            NULL,
    1630                                                            false,
    1631                                                            NULL,
    1632                                                            srcHdVBox.asOutParam());
    1633                             if (FAILED(rc)) throw rc;
    1634                             fSourceHdNeedsClosing = true;
    1635 
    1636                             /* We need the format description of the source disk image */
    1637                             Bstr srcFormat;
    1638                             rc = srcHdVBox->COMGETTER(Format)(srcFormat.asOutParam());
    1639                             if (FAILED(rc)) throw rc;
    1640                             /* Create a new hard disk interface for the destination disk image */
    1641                             rc = mVirtualBox->CreateHardDisk(srcFormat, Bstr(vsdeHD->strVbox), dstHdVBox.asOutParam());
    1642                             if (FAILED(rc)) throw rc;
    1643                             /* Clone the source disk image */
    1644                             rc = srcHdVBox->CloneTo(dstHdVBox, MediumVariant_Standard, NULL, pProgress2.asOutParam());
    1645                             if (FAILED(rc)) throw rc;
    1646 
    1647                             /* Advance to the next operation */
    1648                             if (!pProgress.isNull())
    1649                                 pProgress->SetNextOperation(BstrFmt(tr("Importing virtual disk image '%s'"), strSrcFilePath.c_str()),
    1650                                                             vsdeHD->ulSizeMB);     // operation's weight, as set up with the IProgress originally);
    1651                         }
    1652 
    1653                         // now wait for the background disk operation to complete; this throws HRESULTs on error
    1654                         waitForAsyncProgress(pProgress, pProgress2);
    1655 
    1656                         if (fSourceHdNeedsClosing)
    1657                         {
    1658                             rc = srcHdVBox->Close();
    1659                             if (FAILED(rc)) throw rc;
    1660                             fSourceHdNeedsClosing = false;
    1661                         }
    1662 
    1663                         llHardDisksCreated.push_back(dstHdVBox);
    1664                         /* Now use the new uuid to attach the disk image to our new machine */
    1665                         ComPtr<IMachine> sMachine;
    1666                         rc = session->COMGETTER(Machine)(sMachine.asOutParam());
    1667                         if (FAILED(rc)) throw rc;
    1668                         Bstr hdId;
    1669                         rc = dstHdVBox->COMGETTER(Id)(hdId.asOutParam());
    1670                         if (FAILED(rc)) throw rc;
    1671 
    1672                         /* For now we assume we have one controller of every type only */
    1673                         ovf::HardDiskController hdc = (*vsysThis.mapControllers.find(vd.idController)).second;
    1674 
    1675                         // this is for rollback later
    1676                         MyHardDiskAttachment mhda;
    1677                         mhda.bstrUuid = bstrNewMachineId;
    1678                         mhda.pMachine = pNewMachine;
    1679 
    1680                         convertDiskAttachmentValues(hdc,
    1681                                                     vd.ulAddressOnParent,
    1682                                                     mhda.controllerType,        // Bstr
    1683                                                     mhda.lChannel,
    1684                                                     mhda.lDevice);
    1685 
    1686                         Log(("Attaching disk %s to channel %d on device %d\n", vsdeHD->strVbox.c_str(), mhda.lChannel, mhda.lDevice));
    1687 
    1688                         rc = sMachine->AttachDevice(mhda.controllerType,
    1689                                                     mhda.lChannel,
    1690                                                     mhda.lDevice,
    1691                                                     DeviceType_HardDisk,
    1692                                                     hdId);
    1693                         if (FAILED(rc)) throw rc;
    1694 
    1695                         llHardDiskAttachments.push_back(mhda);
    1696 
    1697                         rc = sMachine->SaveSettings();
    1698                         if (FAILED(rc)) throw rc;
    1699                     } // end for (itHD = avsdeHDs.begin();
    1700 
    1701                     // only now that we're done with all disks, close the session
    1702                     rc = session->Close();
    1703                     if (FAILED(rc)) throw rc;
    1704                     fSessionOpen = false;
    1705                 }
    1706                 catch(HRESULT /* aRC */)
    1707                 {
    1708                     if (fSourceHdNeedsClosing)
    1709                         srcHdVBox->Close();
    1710 
    1711                     if (fSessionOpen)
    1712                         session->Close();
    1713 
    1714                     throw;
    1715                 }
    1716             }
     1125                importMachineGeneric(vsysThis, vsdescThis, pNewMachine, stack);
    17171126        }
    17181127        catch(HRESULT aRC)
     
    17351144        // detach all hard disks from all machines we created
    17361145        list<MyHardDiskAttachment>::iterator itM;
    1737         for (itM = llHardDiskAttachments.begin();
    1738              itM != llHardDiskAttachments.end();
     1146        for (itM = stack.llHardDiskAttachments.begin();
     1147             itM != stack.llHardDiskAttachments.end();
    17391148             ++itM)
    17401149        {
    17411150            const MyHardDiskAttachment &mhda = *itM;
    17421151            Bstr bstrUuid(mhda.bstrUuid);           // make a copy, Windows can't handle const Bstr
    1743             rc2 = mVirtualBox->OpenSession(session, bstrUuid);
     1152            rc2 = mVirtualBox->OpenSession(stack.pSession, bstrUuid);
    17441153            if (SUCCEEDED(rc2))
    17451154            {
    17461155                ComPtr<IMachine> sMachine;
    1747                 rc2 = session->COMGETTER(Machine)(sMachine.asOutParam());
     1156                rc2 = stack.pSession->COMGETTER(Machine)(sMachine.asOutParam());
    17481157                if (SUCCEEDED(rc2))
    17491158                {
     
    17511160                    rc2 = sMachine->SaveSettings();
    17521161                }
    1753                 session->Close();
     1162                stack.pSession->Close();
    17541163            }
    17551164        }
     
    17571166        // now clean up all hard disks we created
    17581167        list< ComPtr<IMedium> >::iterator itHD;
    1759         for (itHD = llHardDisksCreated.begin();
    1760              itHD != llHardDisksCreated.end();
     1168        for (itHD = stack.llHardDisksCreated.begin();
     1169             itHD != stack.llHardDisksCreated.end();
    17611170             ++itHD)
    17621171        {
     
    17691178        // finally, deregister and remove all machines
    17701179        list<Bstr>::iterator itID;
    1771         for (itID = llMachinesRegistered.begin();
    1772              itID != llMachinesRegistered.end();
     1180        for (itID = stack.llMachinesRegistered.begin();
     1181             itID != stack.llMachinesRegistered.end();
    17731182             ++itID)
    17741183        {
     
    17891198
    17901199    return rc;
     1200}
     1201
     1202/**
     1203 * Imports one OVF virtual system (described by the given ovf::VirtualSystem and VirtualSystemDescription)
     1204 * into VirtualBox by creating an IMachine instance, which is returned.
     1205 *
     1206 * This throws HRESULT error codes for anything that goes wrong, in which case the caller must clean
     1207 * up any leftovers from this function. For this, the given ImportStack instance has received information
     1208 * about what needs cleaning up (to support rollback).
     1209 *
     1210 * @param locInfo
     1211 * @param vsysThis
     1212 * @param vsdescThis
     1213 * @param pNewMachine
     1214 * @param stack
     1215 */
     1216void Appliance::importMachineGeneric(const ovf::VirtualSystem &vsysThis,
     1217                                     ComObjPtr<VirtualSystemDescription> &vsdescThis,
     1218                                     ComPtr<IMachine> &pNewMachine,
     1219                                     ImportStack &stack)
     1220{
     1221    /* Guest OS type */
     1222    std::list<VirtualSystemDescriptionEntry*> vsdeOS;
     1223    vsdeOS = vsdescThis->findByType(VirtualSystemDescriptionType_OS);
     1224    if (vsdeOS.size() < 1)
     1225        throw setError(VBOX_E_FILE_ERROR,
     1226                        tr("Missing guest OS type"));
     1227    const Utf8Str &strOsTypeVBox = vsdeOS.front()->strVbox;
     1228
     1229    /* Now that we know the base system get our internal defaults based on that. */
     1230    ComPtr<IGuestOSType> osType;
     1231    HRESULT rc = mVirtualBox->GetGuestOSType(Bstr(strOsTypeVBox), osType.asOutParam());
     1232    if (FAILED(rc)) throw rc;
     1233
     1234    /* Create the machine */
     1235    /* First get the name */
     1236    std::list<VirtualSystemDescriptionEntry*> vsdeName = vsdescThis->findByType(VirtualSystemDescriptionType_Name);
     1237    if (vsdeName.size() < 1)
     1238        throw setError(VBOX_E_FILE_ERROR,
     1239                        tr("Missing VM name"));
     1240    const Utf8Str &strNameVBox = vsdeName.front()->strVbox;
     1241    rc = mVirtualBox->CreateMachine(Bstr(strNameVBox),
     1242                                    Bstr(strOsTypeVBox),
     1243                                    NULL,
     1244                                    NULL,
     1245                                    FALSE,
     1246                                    pNewMachine.asOutParam());
     1247    if (FAILED(rc)) throw rc;
     1248
     1249    // and the description
     1250    std::list<VirtualSystemDescriptionEntry*> vsdeDescription = vsdescThis->findByType(VirtualSystemDescriptionType_Description);
     1251    if (vsdeDescription.size())
     1252    {
     1253        const Utf8Str &strDescription = vsdeDescription.front()->strVbox;
     1254        rc = pNewMachine->COMSETTER(Description)(Bstr(strDescription));
     1255        if (FAILED(rc)) throw rc;
     1256    }
     1257
     1258    /* CPU count */
     1259    std::list<VirtualSystemDescriptionEntry*> vsdeCPU = vsdescThis->findByType(VirtualSystemDescriptionType_CPU);
     1260    ComAssertMsgThrow(vsdeCPU.size() == 1, ("CPU count missing"), E_FAIL);
     1261    const Utf8Str &cpuVBox = vsdeCPU.front()->strVbox;
     1262    ULONG tmpCount = (ULONG)RTStrToUInt64(cpuVBox.c_str());
     1263    rc = pNewMachine->COMSETTER(CPUCount)(tmpCount);
     1264    if (FAILED(rc)) throw rc;
     1265    bool fEnableIOApic = false;
     1266    /* We need HWVirt & IO-APIC if more than one CPU is requested */
     1267    if (tmpCount > 1)
     1268    {
     1269        rc = pNewMachine->SetHWVirtExProperty(HWVirtExPropertyType_Enabled, TRUE);
     1270        if (FAILED(rc)) throw rc;
     1271
     1272        fEnableIOApic = true;
     1273    }
     1274
     1275    /* RAM */
     1276    std::list<VirtualSystemDescriptionEntry*> vsdeRAM = vsdescThis->findByType(VirtualSystemDescriptionType_Memory);
     1277    ComAssertMsgThrow(vsdeRAM.size() == 1, ("RAM size missing"), E_FAIL);
     1278    const Utf8Str &memoryVBox = vsdeRAM.front()->strVbox;
     1279    ULONG tt = (ULONG)RTStrToUInt64(memoryVBox.c_str());
     1280    rc = pNewMachine->COMSETTER(MemorySize)(tt);
     1281    if (FAILED(rc)) throw rc;
     1282
     1283    /* VRAM */
     1284    /* Get the recommended VRAM for this guest OS type */
     1285    ULONG vramVBox;
     1286    rc = osType->COMGETTER(RecommendedVRAM)(&vramVBox);
     1287    if (FAILED(rc)) throw rc;
     1288
     1289    /* Set the VRAM */
     1290    rc = pNewMachine->COMSETTER(VRAMSize)(vramVBox);
     1291    if (FAILED(rc)) throw rc;
     1292
     1293    /* I/O APIC: so far we have no setting for this. Enable it if we
     1294        import a Windows VM because if if Windows was installed without IOAPIC,
     1295        it will not mind finding an one later on, but if Windows was installed
     1296        _with_ an IOAPIC, it will bluescreen if it's not found */
     1297    Bstr bstrFamilyId;
     1298    rc = osType->COMGETTER(FamilyId)(bstrFamilyId.asOutParam());
     1299    if (FAILED(rc)) throw rc;
     1300
     1301    Utf8Str strFamilyId(bstrFamilyId);
     1302    if (strFamilyId == "Windows")
     1303        fEnableIOApic = true;
     1304
     1305    /* If IP-APIC should be enabled could be have different reasons.
     1306        See CPU count & the Win test above. Here we enable it if it was
     1307        previously requested. */
     1308    if (fEnableIOApic)
     1309    {
     1310        ComPtr<IBIOSSettings> pBIOSSettings;
     1311        rc = pNewMachine->COMGETTER(BIOSSettings)(pBIOSSettings.asOutParam());
     1312        if (FAILED(rc)) throw rc;
     1313
     1314        rc = pBIOSSettings->COMSETTER(IOAPICEnabled)(TRUE);
     1315        if (FAILED(rc)) throw rc;
     1316    }
     1317
     1318    /* Audio Adapter */
     1319    std::list<VirtualSystemDescriptionEntry*> vsdeAudioAdapter = vsdescThis->findByType(VirtualSystemDescriptionType_SoundCard);
     1320    /* @todo: we support one audio adapter only */
     1321    if (vsdeAudioAdapter.size() > 0)
     1322    {
     1323        const Utf8Str& audioAdapterVBox = vsdeAudioAdapter.front()->strVbox;
     1324        if (audioAdapterVBox.compare("null", Utf8Str::CaseInsensitive) != 0)
     1325        {
     1326            uint32_t audio = RTStrToUInt32(audioAdapterVBox.c_str());
     1327            ComPtr<IAudioAdapter> audioAdapter;
     1328            rc = pNewMachine->COMGETTER(AudioAdapter)(audioAdapter.asOutParam());
     1329            if (FAILED(rc)) throw rc;
     1330            rc = audioAdapter->COMSETTER(Enabled)(true);
     1331            if (FAILED(rc)) throw rc;
     1332            rc = audioAdapter->COMSETTER(AudioController)(static_cast<AudioControllerType_T>(audio));
     1333            if (FAILED(rc)) throw rc;
     1334        }
     1335    }
     1336
     1337#ifdef VBOX_WITH_USB
     1338    /* USB Controller */
     1339    std::list<VirtualSystemDescriptionEntry*> vsdeUSBController = vsdescThis->findByType(VirtualSystemDescriptionType_USBController);
     1340    // USB support is enabled if there's at least one such entry; to disable USB support,
     1341    // the type of the USB item would have been changed to "ignore"
     1342    bool fUSBEnabled = vsdeUSBController.size() > 0;
     1343
     1344    ComPtr<IUSBController> usbController;
     1345    rc = pNewMachine->COMGETTER(USBController)(usbController.asOutParam());
     1346    if (FAILED(rc)) throw rc;
     1347    rc = usbController->COMSETTER(Enabled)(fUSBEnabled);
     1348    if (FAILED(rc)) throw rc;
     1349#endif /* VBOX_WITH_USB */
     1350
     1351    /* Change the network adapters */
     1352    std::list<VirtualSystemDescriptionEntry*> vsdeNW = vsdescThis->findByType(VirtualSystemDescriptionType_NetworkAdapter);
     1353    if (vsdeNW.size() == 0)
     1354    {
     1355        /* No network adapters, so we have to disable our default one */
     1356        ComPtr<INetworkAdapter> nwVBox;
     1357        rc = pNewMachine->GetNetworkAdapter(0, nwVBox.asOutParam());
     1358        if (FAILED(rc)) throw rc;
     1359        rc = nwVBox->COMSETTER(Enabled)(false);
     1360        if (FAILED(rc)) throw rc;
     1361    }
     1362    else
     1363    {
     1364        list<VirtualSystemDescriptionEntry*>::const_iterator nwIt;
     1365        /* Iterate through all network cards. We support 8 network adapters
     1366            * at the maximum. (@todo: warn if there are more!) */
     1367        size_t a = 0;
     1368        for (nwIt = vsdeNW.begin();
     1369                (nwIt != vsdeNW.end() && a < SchemaDefs::NetworkAdapterCount);
     1370                ++nwIt, ++a)
     1371        {
     1372            const VirtualSystemDescriptionEntry* pvsys = *nwIt;
     1373
     1374            const Utf8Str &nwTypeVBox = pvsys->strVbox;
     1375            uint32_t tt1 = RTStrToUInt32(nwTypeVBox.c_str());
     1376            ComPtr<INetworkAdapter> pNetworkAdapter;
     1377            rc = pNewMachine->GetNetworkAdapter((ULONG)a, pNetworkAdapter.asOutParam());
     1378            if (FAILED(rc)) throw rc;
     1379            /* Enable the network card & set the adapter type */
     1380            rc = pNetworkAdapter->COMSETTER(Enabled)(true);
     1381            if (FAILED(rc)) throw rc;
     1382            rc = pNetworkAdapter->COMSETTER(AdapterType)(static_cast<NetworkAdapterType_T>(tt1));
     1383            if (FAILED(rc)) throw rc;
     1384
     1385            // default is NAT; change to "bridged" if extra conf says so
     1386            if (!pvsys->strExtraConfig.compare("type=Bridged", Utf8Str::CaseInsensitive))
     1387            {
     1388                /* Attach to the right interface */
     1389                rc = pNetworkAdapter->AttachToBridgedInterface();
     1390                if (FAILED(rc)) throw rc;
     1391                ComPtr<IHost> host;
     1392                rc = mVirtualBox->COMGETTER(Host)(host.asOutParam());
     1393                if (FAILED(rc)) throw rc;
     1394                com::SafeIfaceArray<IHostNetworkInterface> nwInterfaces;
     1395                rc = host->COMGETTER(NetworkInterfaces)(ComSafeArrayAsOutParam(nwInterfaces));
     1396                if (FAILED(rc)) throw rc;
     1397                /* We search for the first host network interface which
     1398                    * is usable for bridged networking */
     1399                for (size_t j = 0;
     1400                        j < nwInterfaces.size();
     1401                        ++j)
     1402                {
     1403                    HostNetworkInterfaceType_T itype;
     1404                    rc = nwInterfaces[j]->COMGETTER(InterfaceType)(&itype);
     1405                    if (FAILED(rc)) throw rc;
     1406                    if (itype == HostNetworkInterfaceType_Bridged)
     1407                    {
     1408                        Bstr name;
     1409                        rc = nwInterfaces[j]->COMGETTER(Name)(name.asOutParam());
     1410                        if (FAILED(rc)) throw rc;
     1411                        /* Set the interface name to attach to */
     1412                        pNetworkAdapter->COMSETTER(HostInterface)(name);
     1413                        if (FAILED(rc)) throw rc;
     1414                        break;
     1415                    }
     1416                }
     1417            }
     1418            /* Next test for host only interfaces */
     1419            else if (!pvsys->strExtraConfig.compare("type=HostOnly", Utf8Str::CaseInsensitive))
     1420            {
     1421                /* Attach to the right interface */
     1422                rc = pNetworkAdapter->AttachToHostOnlyInterface();
     1423                if (FAILED(rc)) throw rc;
     1424                ComPtr<IHost> host;
     1425                rc = mVirtualBox->COMGETTER(Host)(host.asOutParam());
     1426                if (FAILED(rc)) throw rc;
     1427                com::SafeIfaceArray<IHostNetworkInterface> nwInterfaces;
     1428                rc = host->COMGETTER(NetworkInterfaces)(ComSafeArrayAsOutParam(nwInterfaces));
     1429                if (FAILED(rc)) throw rc;
     1430                /* We search for the first host network interface which
     1431                    * is usable for host only networking */
     1432                for (size_t j = 0;
     1433                        j < nwInterfaces.size();
     1434                        ++j)
     1435                {
     1436                    HostNetworkInterfaceType_T itype;
     1437                    rc = nwInterfaces[j]->COMGETTER(InterfaceType)(&itype);
     1438                    if (FAILED(rc)) throw rc;
     1439                    if (itype == HostNetworkInterfaceType_HostOnly)
     1440                    {
     1441                        Bstr name;
     1442                        rc = nwInterfaces[j]->COMGETTER(Name)(name.asOutParam());
     1443                        if (FAILED(rc)) throw rc;
     1444                        /* Set the interface name to attach to */
     1445                        pNetworkAdapter->COMSETTER(HostInterface)(name);
     1446                        if (FAILED(rc)) throw rc;
     1447                        break;
     1448                    }
     1449                }
     1450            }
     1451        }
     1452    }
     1453
     1454    /* Hard disk controller IDE */
     1455    std::list<VirtualSystemDescriptionEntry*> vsdeHDCIDE = vsdescThis->findByType(VirtualSystemDescriptionType_HardDiskControllerIDE);
     1456    if (vsdeHDCIDE.size() > 1)
     1457        throw setError(VBOX_E_FILE_ERROR,
     1458                        tr("Too many IDE controllers in OVF; import facility only supports one"));
     1459    if (vsdeHDCIDE.size() == 1)
     1460    {
     1461        ComPtr<IStorageController> pController;
     1462        rc = pNewMachine->AddStorageController(Bstr("IDE Controller"), StorageBus_IDE, pController.asOutParam());
     1463        if (FAILED(rc)) throw rc;
     1464
     1465        const char *pcszIDEType = vsdeHDCIDE.front()->strVbox.c_str();
     1466        if (!strcmp(pcszIDEType, "PIIX3"))
     1467            rc = pController->COMSETTER(ControllerType)(StorageControllerType_PIIX3);
     1468        else if (!strcmp(pcszIDEType, "PIIX4"))
     1469            rc = pController->COMSETTER(ControllerType)(StorageControllerType_PIIX4);
     1470        else if (!strcmp(pcszIDEType, "ICH6"))
     1471            rc = pController->COMSETTER(ControllerType)(StorageControllerType_ICH6);
     1472        else
     1473            throw setError(VBOX_E_FILE_ERROR,
     1474                            tr("Invalid IDE controller type \"%s\""),
     1475                            pcszIDEType);
     1476        if (FAILED(rc)) throw rc;
     1477    }
     1478#ifdef VBOX_WITH_AHCI
     1479    /* Hard disk controller SATA */
     1480    std::list<VirtualSystemDescriptionEntry*> vsdeHDCSATA = vsdescThis->findByType(VirtualSystemDescriptionType_HardDiskControllerSATA);
     1481    if (vsdeHDCSATA.size() > 1)
     1482        throw setError(VBOX_E_FILE_ERROR,
     1483                        tr("Too many SATA controllers in OVF; import facility only supports one"));
     1484    if (vsdeHDCSATA.size() > 0)
     1485    {
     1486        ComPtr<IStorageController> pController;
     1487        const Utf8Str &hdcVBox = vsdeHDCSATA.front()->strVbox;
     1488        if (hdcVBox == "AHCI")
     1489        {
     1490            rc = pNewMachine->AddStorageController(Bstr("SATA Controller"), StorageBus_SATA, pController.asOutParam());
     1491            if (FAILED(rc)) throw rc;
     1492        }
     1493        else
     1494            throw setError(VBOX_E_FILE_ERROR,
     1495                            tr("Invalid SATA controller type \"%s\""),
     1496                            hdcVBox.c_str());
     1497    }
     1498#endif /* VBOX_WITH_AHCI */
     1499
     1500#ifdef VBOX_WITH_LSILOGIC
     1501    /* Hard disk controller SCSI */
     1502    std::list<VirtualSystemDescriptionEntry*> vsdeHDCSCSI = vsdescThis->findByType(VirtualSystemDescriptionType_HardDiskControllerSCSI);
     1503    if (vsdeHDCSCSI.size() > 1)
     1504        throw setError(VBOX_E_FILE_ERROR,
     1505                        tr("Too many SCSI controllers in OVF; import facility only supports one"));
     1506    if (vsdeHDCSCSI.size() > 0)
     1507    {
     1508        ComPtr<IStorageController> pController;
     1509        StorageControllerType_T controllerType;
     1510        const Utf8Str &hdcVBox = vsdeHDCSCSI.front()->strVbox;
     1511        if (hdcVBox == "LsiLogic")
     1512            controllerType = StorageControllerType_LsiLogic;
     1513        else if (hdcVBox == "BusLogic")
     1514            controllerType = StorageControllerType_BusLogic;
     1515        else
     1516            throw setError(VBOX_E_FILE_ERROR,
     1517                            tr("Invalid SCSI controller type \"%s\""),
     1518                            hdcVBox.c_str());
     1519
     1520        rc = pNewMachine->AddStorageController(Bstr("SCSI Controller"), StorageBus_SCSI, pController.asOutParam());
     1521        if (FAILED(rc)) throw rc;
     1522        rc = pController->COMSETTER(ControllerType)(controllerType);
     1523        if (FAILED(rc)) throw rc;
     1524    }
     1525#endif /* VBOX_WITH_LSILOGIC */
     1526
     1527    /* Now its time to register the machine before we add any hard disks */
     1528    rc = mVirtualBox->RegisterMachine(pNewMachine);
     1529    if (FAILED(rc)) throw rc;
     1530
     1531    Bstr bstrNewMachineId;
     1532    rc = pNewMachine->COMGETTER(Id)(bstrNewMachineId.asOutParam());
     1533    if (FAILED(rc)) throw rc;
     1534
     1535    // store new machine for roll-back in case of errors
     1536    stack.llMachinesRegistered.push_back(bstrNewMachineId);
     1537
     1538    // Add floppies and CD-ROMs to the appropriate controllers.
     1539    std::list<VirtualSystemDescriptionEntry*> vsdeFloppy = vsdescThis->findByType(VirtualSystemDescriptionType_Floppy);
     1540    if (vsdeFloppy.size() > 1)
     1541        throw setError(VBOX_E_FILE_ERROR,
     1542                        tr("Too many floppy controllers in OVF; import facility only supports one"));
     1543    std::list<VirtualSystemDescriptionEntry*> vsdeCDROM = vsdescThis->findByType(VirtualSystemDescriptionType_CDROM);
     1544    if (    (vsdeFloppy.size() > 0)
     1545            || (vsdeCDROM.size() > 0)
     1546        )
     1547    {
     1548        // If there's an error here we need to close the session, so
     1549        // we need another try/catch block.
     1550
     1551        try
     1552        {
     1553            /* In order to attach things we need to open a session
     1554                * for the new machine */
     1555            rc = mVirtualBox->OpenSession(stack.pSession, bstrNewMachineId);
     1556            if (FAILED(rc)) throw rc;
     1557            stack.fSessionOpen = true;
     1558
     1559            ComPtr<IMachine> sMachine;
     1560            rc = stack.pSession->COMGETTER(Machine)(sMachine.asOutParam());
     1561            if (FAILED(rc)) throw rc;
     1562
     1563            // floppy first
     1564            if (vsdeFloppy.size() == 1)
     1565            {
     1566                ComPtr<IStorageController> pController;
     1567                rc = sMachine->AddStorageController(Bstr("Floppy Controller"), StorageBus_Floppy, pController.asOutParam());
     1568                if (FAILED(rc)) throw rc;
     1569
     1570                Bstr bstrName;
     1571                rc = pController->COMGETTER(Name)(bstrName.asOutParam());
     1572                if (FAILED(rc)) throw rc;
     1573
     1574                // this is for rollback later
     1575                MyHardDiskAttachment mhda;
     1576                mhda.bstrUuid = bstrNewMachineId;
     1577                mhda.pMachine = pNewMachine;
     1578                mhda.controllerType = bstrName;
     1579                mhda.lChannel = 0;
     1580                mhda.lDevice = 0;
     1581
     1582                Log(("Attaching floppy\n"));
     1583
     1584                rc = sMachine->AttachDevice(mhda.controllerType,
     1585                                            mhda.lChannel,
     1586                                            mhda.lDevice,
     1587                                            DeviceType_Floppy,
     1588                                            NULL);
     1589                if (FAILED(rc)) throw rc;
     1590
     1591                stack.llHardDiskAttachments.push_back(mhda);
     1592            }
     1593
     1594
     1595            // CD-ROMs next
     1596            for (std::list<VirtualSystemDescriptionEntry*>::const_iterator jt = vsdeCDROM.begin();
     1597                    jt != vsdeCDROM.end();
     1598                    ++jt)
     1599            {
     1600                // for now always attach to secondary master on IDE controller;
     1601                // there seems to be no useful information in OVF where else to
     1602                // attach jt (@todo test with latest versions of OVF software)
     1603
     1604                // find the IDE controller
     1605                const ovf::HardDiskController *pController = NULL;
     1606                for (ovf::ControllersMap::const_iterator kt = vsysThis.mapControllers.begin();
     1607                     kt != vsysThis.mapControllers.end();
     1608                     ++kt)
     1609                {
     1610                    if (kt->second.system == ovf::HardDiskController::IDE)
     1611                    {
     1612                        pController = &kt->second;
     1613                    }
     1614                }
     1615
     1616                if (!pController)
     1617                    throw setError(VBOX_E_FILE_ERROR,
     1618                                    tr("OVF wants a CD-ROM drive but cannot find IDE controller, which is required in this version of VirtualBox"));
     1619
     1620                // this is for rollback later
     1621                MyHardDiskAttachment mhda;
     1622                mhda.bstrUuid = bstrNewMachineId;
     1623                mhda.pMachine = pNewMachine;
     1624
     1625                convertDiskAttachmentValues(*pController,
     1626                                            2,     // interpreted as secondary master
     1627                                            mhda.controllerType,        // Bstr
     1628                                            mhda.lChannel,
     1629                                            mhda.lDevice);
     1630
     1631                Log(("Attaching CD-ROM to channel %d on device %d\n", mhda.lChannel, mhda.lDevice));
     1632
     1633                rc = sMachine->AttachDevice(mhda.controllerType,
     1634                                            mhda.lChannel,
     1635                                            mhda.lDevice,
     1636                                            DeviceType_DVD,
     1637                                            NULL);
     1638                if (FAILED(rc)) throw rc;
     1639
     1640                stack.llHardDiskAttachments.push_back(mhda);
     1641            } // end for (itHD = avsdeHDs.begin();
     1642
     1643            rc = sMachine->SaveSettings();
     1644            if (FAILED(rc)) throw rc;
     1645
     1646            // only now that we're done with all disks, close the session
     1647            rc = stack.pSession->Close();
     1648            if (FAILED(rc)) throw rc;
     1649            stack.fSessionOpen = false;
     1650        }
     1651        catch(HRESULT /* aRC */)
     1652        {
     1653            if (stack.fSessionOpen)
     1654                stack.pSession->Close();
     1655
     1656            throw;
     1657        }
     1658    }
     1659
     1660    /* Create the hard disks & connect them to the appropriate controllers. */
     1661    std::list<VirtualSystemDescriptionEntry*> avsdeHDs = vsdescThis->findByType(VirtualSystemDescriptionType_HardDiskImage);
     1662    if (avsdeHDs.size() > 0)
     1663    {
     1664        // If there's an error here we need to close the session, so
     1665        // we need another try/catch block.
     1666        ComPtr<IMedium> srcHdVBox;
     1667        bool fSourceHdNeedsClosing = false;
     1668
     1669        try
     1670        {
     1671            /* In order to attach hard disks we need to open a session
     1672             * for the new machine */
     1673            rc = mVirtualBox->OpenSession(stack.pSession, bstrNewMachineId);
     1674            if (FAILED(rc)) throw rc;
     1675            stack.fSessionOpen = true;
     1676
     1677            /* The disk image has to be on the same place as the OVF file. So
     1678             * strip the filename out of the full file path. */
     1679            Utf8Str strSrcDir(stack.locInfo.strPath);
     1680            strSrcDir.stripFilename();
     1681
     1682            /* Iterate over all given disk images */
     1683            list<VirtualSystemDescriptionEntry*>::const_iterator itHD;
     1684            for (itHD = avsdeHDs.begin();
     1685                 itHD != avsdeHDs.end();
     1686                 ++itHD)
     1687            {
     1688                VirtualSystemDescriptionEntry *vsdeHD = *itHD;
     1689
     1690                /* Check if the destination file exists already or the
     1691                    * destination path is empty. */
     1692                if (    vsdeHD->strVbox.isEmpty()
     1693                     || RTPathExists(vsdeHD->strVbox.c_str())
     1694                   )
     1695                    /* This isn't allowed */
     1696                    throw setError(VBOX_E_FILE_ERROR,
     1697                                    tr("Destination file '%s' exists",
     1698                                        vsdeHD->strVbox.c_str()));
     1699
     1700                /* Find the disk from the OVF's disk list */
     1701                ovf::DiskImagesMap::const_iterator itDiskImage = stack.mapDisks.find(vsdeHD->strRef);
     1702                /* vsdeHD->strRef contains the disk identifier (e.g. "vmdisk1"), which should exist
     1703                   in the virtual system's disks map under that ID and also in the global images map. */
     1704                ovf::VirtualDisksMap::const_iterator itVirtualDisk = vsysThis.mapVirtualDisks.find(vsdeHD->strRef);
     1705
     1706                if (    itDiskImage == stack.mapDisks.end()
     1707                     || itVirtualDisk == vsysThis.mapVirtualDisks.end()
     1708                   )
     1709                    throw setError(E_FAIL,
     1710                                    tr("Internal inconsistency looking up disk images."));
     1711
     1712                const ovf::DiskImage &di = itDiskImage->second;
     1713                const ovf::VirtualDisk &vd = itVirtualDisk->second;
     1714
     1715                /* Make sure all target directories exists */
     1716                rc = VirtualBox::ensureFilePathExists(vsdeHD->strVbox.c_str());
     1717                if (FAILED(rc))
     1718                    throw rc;
     1719
     1720                // subprogress object for hard disk
     1721                ComPtr<IProgress> pProgress2;
     1722
     1723                ComPtr<IMedium> dstHdVBox;
     1724                /* If strHref is empty we have to create a new file */
     1725                if (di.strHref.isEmpty())
     1726                {
     1727                    /* Which format to use? */
     1728                    Bstr srcFormat = L"VDI";
     1729                    if (   di.strFormat.compare("http://www.vmware.com/specifications/vmdk.html#sparse", Utf8Str::CaseInsensitive)
     1730                        || di.strFormat.compare("http://www.vmware.com/specifications/vmdk.html#compressed", Utf8Str::CaseInsensitive))
     1731                        srcFormat = L"VMDK";
     1732                    /* Create an empty hard disk */
     1733                    rc = mVirtualBox->CreateHardDisk(srcFormat, Bstr(vsdeHD->strVbox), dstHdVBox.asOutParam());
     1734                    if (FAILED(rc)) throw rc;
     1735
     1736                    /* Create a dynamic growing disk image with the given capacity */
     1737                    rc = dstHdVBox->CreateBaseStorage(di.iCapacity / _1M, MediumVariant_Standard, pProgress2.asOutParam());
     1738                    if (FAILED(rc)) throw rc;
     1739
     1740                    /* Advance to the next operation */
     1741                    stack.pProgress->SetNextOperation(BstrFmt(tr("Creating virtual disk image '%s'"), vsdeHD->strVbox.c_str()),
     1742                                                      vsdeHD->ulSizeMB);     // operation's weight, as set up with the IProgress originally
     1743                }
     1744                else
     1745                {
     1746                    /* Construct the source file path */
     1747                    Utf8StrFmt strSrcFilePath("%s%c%s", strSrcDir.c_str(), RTPATH_DELIMITER, di.strHref.c_str());
     1748                    /* Check if the source file exists */
     1749                    if (!RTPathExists(strSrcFilePath.c_str()))
     1750                        /* This isn't allowed */
     1751                        throw setError(VBOX_E_FILE_ERROR,
     1752                                        tr("Source virtual disk image file '%s' doesn't exist"),
     1753                                            strSrcFilePath.c_str());
     1754
     1755                    /* Clone the disk image (this is necessary cause the id has
     1756                        * to be recreated for the case the same hard disk is
     1757                        * attached already from a previous import) */
     1758
     1759                    /* First open the existing disk image */
     1760                    rc = mVirtualBox->OpenHardDisk(Bstr(strSrcFilePath),
     1761                                                    AccessMode_ReadOnly,
     1762                                                    false,
     1763                                                    NULL,
     1764                                                    false,
     1765                                                    NULL,
     1766                                                    srcHdVBox.asOutParam());
     1767                    if (FAILED(rc)) throw rc;
     1768                    fSourceHdNeedsClosing = true;
     1769
     1770                    /* We need the format description of the source disk image */
     1771                    Bstr srcFormat;
     1772                    rc = srcHdVBox->COMGETTER(Format)(srcFormat.asOutParam());
     1773                    if (FAILED(rc)) throw rc;
     1774                    /* Create a new hard disk interface for the destination disk image */
     1775                    rc = mVirtualBox->CreateHardDisk(srcFormat, Bstr(vsdeHD->strVbox), dstHdVBox.asOutParam());
     1776                    if (FAILED(rc)) throw rc;
     1777                    /* Clone the source disk image */
     1778                    rc = srcHdVBox->CloneTo(dstHdVBox, MediumVariant_Standard, NULL, pProgress2.asOutParam());
     1779                    if (FAILED(rc)) throw rc;
     1780
     1781                    /* Advance to the next operation */
     1782                    stack.pProgress->SetNextOperation(BstrFmt(tr("Importing virtual disk image '%s'"), strSrcFilePath.c_str()),
     1783                                                      vsdeHD->ulSizeMB);     // operation's weight, as set up with the IProgress originally);
     1784                }
     1785
     1786                // now wait for the background disk operation to complete; this throws HRESULTs on error
     1787                waitForAsyncProgress(stack.pProgress, pProgress2);
     1788
     1789                if (fSourceHdNeedsClosing)
     1790                {
     1791                    rc = srcHdVBox->Close();
     1792                    if (FAILED(rc)) throw rc;
     1793                    fSourceHdNeedsClosing = false;
     1794                }
     1795
     1796                stack.llHardDisksCreated.push_back(dstHdVBox);
     1797                /* Now use the new uuid to attach the disk image to our new machine */
     1798                ComPtr<IMachine> sMachine;
     1799                rc = stack.pSession->COMGETTER(Machine)(sMachine.asOutParam());
     1800                if (FAILED(rc)) throw rc;
     1801                Bstr hdId;
     1802                rc = dstHdVBox->COMGETTER(Id)(hdId.asOutParam());
     1803                if (FAILED(rc)) throw rc;
     1804
     1805                /* For now we assume we have one controller of every type only */
     1806                ovf::HardDiskController hdc = (*vsysThis.mapControllers.find(vd.idController)).second;
     1807
     1808                // this is for rollback later
     1809                MyHardDiskAttachment mhda;
     1810                mhda.bstrUuid = bstrNewMachineId;
     1811                mhda.pMachine = pNewMachine;
     1812
     1813                convertDiskAttachmentValues(hdc,
     1814                                            vd.ulAddressOnParent,
     1815                                            mhda.controllerType,        // Bstr
     1816                                            mhda.lChannel,
     1817                                            mhda.lDevice);
     1818
     1819                Log(("Attaching disk %s to channel %d on device %d\n", vsdeHD->strVbox.c_str(), mhda.lChannel, mhda.lDevice));
     1820
     1821                rc = sMachine->AttachDevice(mhda.controllerType,
     1822                                            mhda.lChannel,
     1823                                            mhda.lDevice,
     1824                                            DeviceType_HardDisk,
     1825                                            hdId);
     1826                if (FAILED(rc)) throw rc;
     1827
     1828                stack.llHardDiskAttachments.push_back(mhda);
     1829
     1830                rc = sMachine->SaveSettings();
     1831                if (FAILED(rc)) throw rc;
     1832            } // end for (itHD = avsdeHDs.begin();
     1833
     1834            // only now that we're done with all disks, close the session
     1835            rc = stack.pSession->Close();
     1836            if (FAILED(rc)) throw rc;
     1837            stack.fSessionOpen = false;
     1838        }
     1839        catch(HRESULT /* aRC */)
     1840        {
     1841            if (fSourceHdNeedsClosing)
     1842                srcHdVBox->Close();
     1843
     1844            if (stack.fSessionOpen)
     1845                stack.pSession->Close();
     1846
     1847            throw;
     1848        }
     1849    }
     1850}
     1851
     1852/**
     1853 * Imports one OVF virtual system (described by a vbox:Machine tag represented by the given config
     1854 * structure) into VirtualBox by creating an IMachine instance, which is returned.
     1855 *
     1856 * This throws HRESULT error codes for anything that goes wrong, in which case the caller must clean
     1857 * up any leftovers from this function. For this, the given ImportStack instance has received information
     1858 * about what needs cleaning up (to support rollback).
     1859 *
     1860 * @param config
     1861 * @param pNewMachine
     1862 * @param stack
     1863 */
     1864void Appliance::importVBoxMachine(const settings::MachineConfigFile &config,
     1865                                  ComPtr<IMachine> &pNewMachine,
     1866                                  ImportStack &stack)
     1867{
    17911868}
    17921869
  • trunk/src/VBox/Main/MachineImpl.cpp

    r28091 r28098  
    75007500 * from the previous machine config file in the instance data, if any.
    75017501 *
    7502  * This fills all the fields in there, including snapshots, *except*
     7502 * This gets called from two locations:
     7503 *
     7504 *  --  Machine::saveSettings(), during the regular XML writing;
     7505 *
     7506 *  --  Appliance::buildXMLForOneVirtualSystem(), when a machine gets
     7507 *      exported to OVF and we write the VirtualBox proprietary XML
     7508 *      into a <vbox:Machine> tag.
     7509 *
     7510 * This routine fills all the fields in there, including snapshots, *except*
    75037511 * for the following:
    75047512 *
  • trunk/src/VBox/Main/include/ApplianceImpl.h

    r27918 r28098  
    3535{
    3636    struct HardDiskController;
     37    struct VirtualSystem;
    3738    class OVFReader;
    3839}
     
    146147
    147148    HRESULT importFS(const LocationInfo &locInfo, ComObjPtr<Progress> &aProgress);
     149    struct ImportStack;
     150    void importVBoxMachine(const settings::MachineConfigFile &config,
     151                           ComPtr<IMachine> &pNewMachine,
     152                           ImportStack &stack);
     153    void importMachineGeneric(const ovf::VirtualSystem &vsysThis,
     154                              ComObjPtr<VirtualSystemDescription> &vsdescThis,
     155                              ComPtr<IMachine> &pNewMachine,
     156                              ImportStack &stack);
    148157    HRESULT importS3(TaskOVF *pTask);
    149158
  • trunk/src/VBox/Main/xml/Settings.cpp

    r27918 r28098  
    36933693/**
    36943694 * Builds the XML DOM tree for the machine config under the given XML element.
     3695 *
    36953696 * This has been separated out from write() so it can be called from elsewhere,
    36963697 * such as the OVF code, to build machine XML in an existing XML tree.
    3697  * @param elmMachine
    3698  */
    3699 void MachineConfigFile::buildMachineXML(xml::ElementNode &elmMachine)
     3698 *
     3699 * As a result, this gets called from two locations:
     3700 *
     3701 *  --  MachineConfigFile::write();
     3702 *
     3703 *  --  Appliance::buildXMLForOneVirtualSystem()
     3704 *
     3705 * @param elmMachine XML <Machine> element to add attributes and elements to.
     3706 * @param fWriteSnapshots If false, we omit snapshots entirely (we don't recurse then).
     3707 */
     3708void MachineConfigFile::buildMachineXML(xml::ElementNode &elmMachine,
     3709                                        bool fIncludeSnapshots)
    37003710{
    37013711    elmMachine.setAttribute("uuid", makeString(uuid));
     
    37083718    if (strStateFile.length())
    37093719        elmMachine.setAttribute("stateFile", strStateFile);
    3710     if (!uuidCurrentSnapshot.isEmpty())
     3720    if (fIncludeSnapshots && !uuidCurrentSnapshot.isEmpty())
    37113721        elmMachine.setAttribute("currentSnapshot", makeString(uuidCurrentSnapshot));
    37123722    if (strSnapshotFolder.length())
     
    37343744    writeExtraData(elmMachine, mapExtraDataItems);
    37353745
    3736     if (llFirstSnapshot.size())
     3746    if (fIncludeSnapshots && llFirstSnapshot.size())
    37373747        buildSnapshotXML(elmMachine, llFirstSnapshot.front());
    37383748
     
    39013911
    39023912        xml::ElementNode *pelmMachine = m->pelmRoot->createChild("Machine");
    3903         buildMachineXML(*pelmMachine);
     3913        buildMachineXML(*pelmMachine,
     3914                        true /* fIncludeSnapshots */);
    39043915
    39053916        // now go write the XML
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette