VirtualBox

儲存庫 vbox 的更動 16503


忽略:
時間撮記:
2009-2-4 上午10:31:15 (16 年 以前)
作者:
vboxsync
訊息:

OVF: last local changes; make import multi threaded; return IProgress object; better COM locking/error handling

位置:
trunk/src/VBox/Main
檔案:
修改 3 筆資料

圖例:

未更動
新增
刪除
  • trunk/src/VBox/Main/ApplianceImpl.cpp

    r16495 r16503  
    2929#include "VirtualBoxImpl.h"
    3030#include "GuestOSTypeImpl.h"
     31#include "ProgressImpl.h"
    3132
    3233#include "Logging.h"
     
    198199};
    199200
     201struct Appliance::Task
     202{
     203    Task(Appliance *aThat, Progress *aProgress)
     204        : that(aThat)
     205        , progress(aProgress)
     206        , rc(S_OK)
     207    {}
     208    ~Task() {}
     209
     210    HRESULT startThread();
     211
     212    Appliance *that;
     213    ComObjPtr<Progress> progress;
     214    HRESULT rc;
     215};
     216
    200217// globals
    201218////////////////////////////////////////////////////////////////////////////////
     
    221238 * @return S_OK or error.
    222239 */
    223 STDMETHODIMP VirtualBox::OpenAppliance (IN_BSTR bstrPath, IAppliance** anAppliance)
     240STDMETHODIMP VirtualBox::OpenAppliance(IN_BSTR bstrPath, IAppliance** anAppliance)
    224241{
    225242    HRESULT rc;
     
    234251
    235252    return rc;
     253}
     254
     255// Appliance::task methods
     256////////////////////////////////////////////////////////////////////////////////
     257
     258HRESULT Appliance::Task::startThread()
     259{
     260    int vrc = RTThreadCreate(NULL, Appliance::taskThread, this,
     261                             0, RTTHREADTYPE_MAIN_HEAVY_WORKER, 0,
     262                             "Applicane::Task");
     263    ComAssertMsgRCRet(vrc,
     264                      ("Could not create Appliance::Task thread (%Rrc)\n", vrc), E_FAIL);
     265
     266    return S_OK;
    236267}
    237268
     
    11521183        default:
    11531184            {
    1154                 /* If we are here we have no clue what OS this should be. Set to
    1155                     * other type as default. */
     1185                /* If we are here we have no clue what OS this should be. Set
     1186                   to other type as default. */
    11561187                osTypeVBox = SchemaDefs_OSTypeId_Other;
    11571188            }
     
    11691200    CheckComRCReturnRC(autoCaller.rc());
    11701201
     1202    AutoWriteLock(this);
     1203
    11711204    HRESULT rc = S_OK;
    11721205
     
    11781211    ComPtr<ISystemProperties> systemProps;
    11791212    rc = mVirtualBox->COMGETTER(SystemProperties)(systemProps.asOutParam());
    1180     ComAssertComRCThrowRC(rc);
     1213    CheckComRCReturnRC(rc);
    11811214    Bstr bstrDefaultHardDiskLocation;
    11821215    rc = systemProps->COMGETTER(DefaultHardDiskFolder)(bstrDefaultHardDiskLocation.asOutParam());
    1183     ComAssertComRCThrowRC(rc);
    1184 
    1185     list<VirtualSystem>::const_iterator it;
    1186     /* Iterate through all appliances */
    1187     for (it = m->llVirtualSystems.begin();
    1188          it != m->llVirtualSystems.end();
    1189          ++it)
     1216    CheckComRCReturnRC(rc);
     1217
     1218    try
    11901219    {
    1191         const VirtualSystem &vsysThis = *it;
    1192 
    1193         ComObjPtr<VirtualSystemDescription> pNewDesc;
    1194         pNewDesc.createObject();
    1195         rc = pNewDesc->init();
    1196         ComAssertComRCThrowRC(rc);
    1197 
    1198         /* Guest OS type */
    1199         Utf8Str strOsTypeVBox,
    1200                 strCIMOSType = toString<ULONG>(vsysThis.cimos);
    1201         convertCIMOSType2VBoxOSType(strOsTypeVBox, vsysThis.cimos);
    1202         pNewDesc->addEntry(VirtualSystemDescriptionType_OS,
    1203                       0,
    1204                       strCIMOSType,
    1205                       strOsTypeVBox);
    1206 
    1207         /* VM name */
    1208         /* If the there isn't any name specified create a default one out of
    1209          * the OS type */
    1210         Utf8Str nameVBox = vsysThis.strName;
    1211         if (nameVBox == "")
    1212             nameVBox = strOsTypeVBox;
    1213         searchUniqueVMName(nameVBox);
    1214         pNewDesc->addEntry(VirtualSystemDescriptionType_Name,
    1215                            0,
    1216                            vsysThis.strName,
    1217                            nameVBox);
    1218 
    1219         /* Now that we know the OS type, get our internal defaults based on that. */
    1220         ComPtr<IGuestOSType> pGuestOSType;
    1221         rc = mVirtualBox->GetGuestOSType(Bstr(strOsTypeVBox), pGuestOSType.asOutParam());
    1222         ComAssertComRCThrowRC(rc);
    1223 
    1224         /* CPU count */
    1225         /* @todo: check min/max requirements of VBox (SchemaDefs::Min/MaxCPUCount) */
    1226         ULONG cpuCountVBox = vsysThis.cCPUs;
    1227         if (vsysThis.cCPUs == 0)
    1228             cpuCountVBox = 1;
    1229         pNewDesc->addEntry(VirtualSystemDescriptionType_CPU,
    1230                            0,
    1231                            toString<ULONG>(vsysThis.cCPUs),
    1232                            toString<ULONG>(cpuCountVBox));
    1233 
    1234         /* RAM */
    1235         /* @todo: check min/max requirements of VBox (SchemaDefs::Min/MaxGuestRAM) */
    1236         uint64_t ullMemSizeVBox = vsysThis.ullMemorySize;
    1237         if (vsysThis.ullMemorySize == 0)
     1220        list<VirtualSystem>::const_iterator it;
     1221        /* Iterate through all appliances */
     1222        for (it = m->llVirtualSystems.begin();
     1223             it != m->llVirtualSystems.end();
     1224             ++it)
    12381225        {
    1239             /* If the RAM of the OVF is zero, use our predefined values */
    1240             ULONG memSizeVBox2;
    1241             rc = pGuestOSType->COMGETTER(RecommendedRAM)(&memSizeVBox2);
     1226            const VirtualSystem &vsysThis = *it;
     1227
     1228            ComObjPtr<VirtualSystemDescription> pNewDesc;
     1229            rc = pNewDesc.createObject();
     1230            CheckComRCThrowRC(rc);
     1231            rc = pNewDesc->init();
     1232            CheckComRCThrowRC(rc);
     1233
     1234            /* Guest OS type */
     1235            Utf8Str strOsTypeVBox,
     1236                    strCIMOSType = toString<ULONG>(vsysThis.cimos);
     1237            convertCIMOSType2VBoxOSType(strOsTypeVBox, vsysThis.cimos);
     1238            pNewDesc->addEntry(VirtualSystemDescriptionType_OS,
     1239                               0,
     1240                               strCIMOSType,
     1241                               strOsTypeVBox);
     1242
     1243            /* VM name */
     1244            /* If the there isn't any name specified create a default one out of
     1245             * the OS type */
     1246            Utf8Str nameVBox = vsysThis.strName;
     1247            if (nameVBox == "")
     1248                nameVBox = strOsTypeVBox;
     1249            searchUniqueVMName(nameVBox);
     1250            pNewDesc->addEntry(VirtualSystemDescriptionType_Name,
     1251                               0,
     1252                               vsysThis.strName,
     1253                               nameVBox);
     1254
     1255            /* Now that we know the OS type, get our internal defaults based on that. */
     1256            ComPtr<IGuestOSType> pGuestOSType;
     1257            rc = mVirtualBox->GetGuestOSType(Bstr(strOsTypeVBox), pGuestOSType.asOutParam());
    12421258            ComAssertComRCThrowRC(rc);
    1243             /* VBox stores that in MByte */
    1244             ullMemSizeVBox = (uint64_t)memSizeVBox2 * _1M;
    1245         }
    1246         pNewDesc->addEntry(VirtualSystemDescriptionType_Memory,
    1247                            0,
    1248                            toString<uint64_t>(vsysThis.ullMemorySize),
    1249                            toString<uint64_t>(ullMemSizeVBox));
    1250 
    1251         /* Audio */
    1252         if (!vsysThis.strSoundCardType.isNull())
    1253             /* Currently we set the AC97 always.
    1254                @todo: figure out the hardware which could be possible */
    1255             pNewDesc->addEntry(VirtualSystemDescriptionType_SoundCard,
     1259
     1260            /* CPU count */
     1261            /* @todo: check min/max requirements of VBox (SchemaDefs::Min/MaxCPUCount) */
     1262            ULONG cpuCountVBox = vsysThis.cCPUs;
     1263            if (vsysThis.cCPUs == 0)
     1264                cpuCountVBox = 1;
     1265            pNewDesc->addEntry(VirtualSystemDescriptionType_CPU,
    12561266                               0,
    1257                                vsysThis.strSoundCardType,
    1258                                "");
    1259 
    1260         /* USB Controller */
    1261         if (vsysThis.fHasUsbController)
    1262             pNewDesc->addEntry(VirtualSystemDescriptionType_USBController, 0, "", "");
    1263 
    1264         /* Network Controller */
    1265         // @todo: there is no hardware specification in the OVF file; supposedly the
    1266         // hardware will then be determined by the VirtualSystemType element (e.g. "vmx-07")
    1267         if (vsysThis.llNetworkNames.size() > 0)
    1268         {
    1269             /* Get the default network adapter type for the selected guest OS */
    1270             NetworkAdapterType_T nwAdapterVBox = NetworkAdapterType_Am79C970A;
    1271             rc = pGuestOSType->COMGETTER(AdapterType)(&nwAdapterVBox);
    1272             ComAssertComRCThrowRC(rc);
    1273             list<Utf8Str>::const_iterator nwIt;
    1274             /* Iterate through all abstract networks. We support 8 network
    1275              * adapters at the maximum. (@todo: warn if it are more!) */
    1276             size_t a = 0;
    1277             for (nwIt = vsysThis.llNetworkNames.begin();
    1278                  nwIt != vsysThis.llNetworkNames.end() && a < SchemaDefs::NetworkAdapterCount;
    1279                  ++nwIt, ++a)
     1267                               toString<ULONG>(vsysThis.cCPUs),
     1268                               toString<ULONG>(cpuCountVBox));
     1269
     1270            /* RAM */
     1271            /* @todo: check min/max requirements of VBox (SchemaDefs::Min/MaxGuestRAM) */
     1272            uint64_t ullMemSizeVBox = vsysThis.ullMemorySize;
     1273            if (vsysThis.ullMemorySize == 0)
    12801274            {
    1281                 Utf8Str nwController = *nwIt; // @todo: not used yet
    1282                 pNewDesc->addEntry(VirtualSystemDescriptionType_NetworkAdapter, 0, "", toString<ULONG>(nwAdapterVBox));
     1275                /* If the RAM of the OVF is zero, use our predefined values */
     1276                ULONG memSizeVBox2;
     1277                rc = pGuestOSType->COMGETTER(RecommendedRAM)(&memSizeVBox2);
     1278                ComAssertComRCThrowRC(rc);
     1279                /* VBox stores that in MByte */
     1280                ullMemSizeVBox = (uint64_t)memSizeVBox2 * _1M;
    12831281            }
    1284         }
    1285 
    1286         /* Floppy Drive */
    1287         if (vsysThis.fHasFloppyDrive)
    1288             pNewDesc->addEntry(VirtualSystemDescriptionType_Floppy, 0, "", "");
    1289 
    1290         /* CD Drive */
    1291         if (vsysThis.fHasCdromDrive)
    1292            pNewDesc->addEntry(VirtualSystemDescriptionType_CDROM, 0, "", "");
    1293 
    1294         /* Hard disk Controller */
    1295         ControllersMap::const_iterator hdcIt;
    1296         /* Iterate through all hard disk controllers */
    1297         for (hdcIt = vsysThis.mapControllers.begin();
    1298              hdcIt != vsysThis.mapControllers.end();
    1299              ++hdcIt)
    1300         {
    1301             const HardDiskController &hdc = hdcIt->second;
    1302             switch (hdc.system)
     1282            pNewDesc->addEntry(VirtualSystemDescriptionType_Memory,
     1283                               0,
     1284                               toString<uint64_t>(vsysThis.ullMemorySize),
     1285                               toString<uint64_t>(ullMemSizeVBox));
     1286
     1287            /* Audio */
     1288            if (!vsysThis.strSoundCardType.isNull())
     1289                /* Currently we set the AC97 always.
     1290                   @todo: figure out the hardware which could be possible */
     1291                pNewDesc->addEntry(VirtualSystemDescriptionType_SoundCard,
     1292                                   0,
     1293                                   vsysThis.strSoundCardType,
     1294                                   "");
     1295
     1296            /* USB Controller */
     1297            if (vsysThis.fHasUsbController)
     1298                pNewDesc->addEntry(VirtualSystemDescriptionType_USBController, 0, "", "");
     1299
     1300            /* Network Controller */
     1301            // @todo: there is no hardware specification in the OVF file; supposedly the
     1302            // hardware will then be determined by the VirtualSystemType element (e.g. "vmx-07")
     1303            if (vsysThis.llNetworkNames.size() > 0)
    13031304            {
    1304                 case HardDiskController::IDE:
     1305                /* Get the default network adapter type for the selected guest OS */
     1306                NetworkAdapterType_T nwAdapterVBox = NetworkAdapterType_Am79C970A;
     1307                rc = pGuestOSType->COMGETTER(AdapterType)(&nwAdapterVBox);
     1308                ComAssertComRCThrowRC(rc);
     1309                list<Utf8Str>::const_iterator nwIt;
     1310                /* Iterate through all abstract networks. We support 8 network
     1311                 * adapters at the maximum. (@todo: warn if it are more!) */
     1312                size_t a = 0;
     1313                for (nwIt = vsysThis.llNetworkNames.begin();
     1314                     nwIt != vsysThis.llNetworkNames.end() && a < SchemaDefs::NetworkAdapterCount;
     1315                     ++nwIt, ++a)
    13051316                {
    1306                     // @todo: figure out the IDE types
    1307                     /* Use PIIX4 as default */
    1308                     IDEControllerType_T hdcController = IDEControllerType_PIIX4;
    1309                     if (!RTStrICmp(hdc.strControllerType.c_str(), "PIIX3"))
    1310                         hdcController = IDEControllerType_PIIX3;
    1311                     else if (!RTStrICmp(hdc.strControllerType.c_str(), "PIIX4"))
    1312                         hdcController = IDEControllerType_PIIX4;
    1313                     pNewDesc->addEntry(VirtualSystemDescriptionType_HardDiskControllerIDE,
    1314                                        hdc.idController,
    1315                                        hdc.strControllerType,
    1316                                        toString<ULONG>(hdcController));
    1317                     break;
    1318                 }
    1319 
    1320                 case HardDiskController::SATA:
    1321                 {
    1322                     // @todo: figure out the SATA types
    1323                     /* We only support a plain AHCI controller, so use them always */
    1324                     pNewDesc->addEntry(VirtualSystemDescriptionType_HardDiskControllerSATA,
    1325                                        hdc.idController,
    1326                                        hdc.strControllerType,
    1327                                        "AHCI");
    1328                     break;
    1329                 }
    1330 
    1331                 case HardDiskController::SCSI:
    1332                 {
    1333                     // @todo: figure out the SCSI types
    1334                     Utf8Str hdcController = "LsiLogic";
    1335                     if (!RTStrICmp(hdc.strControllerType.c_str(), "LsiLogic"))
    1336                         hdcController = "LsiLogic";
    1337                     else if (!RTStrICmp(hdc.strControllerType.c_str(), "BusLogic"))
    1338                         hdcController = "BusLogic";
    1339                     pNewDesc->addEntry(VirtualSystemDescriptionType_HardDiskControllerSCSI,
    1340                                        hdc.idController,
    1341                                        hdc.strControllerType,
    1342                                        hdcController);
    1343                     break;
     1317                    Utf8Str nwController = *nwIt; // @todo: not used yet
     1318                    pNewDesc->addEntry(VirtualSystemDescriptionType_NetworkAdapter, 0, "", toString<ULONG>(nwAdapterVBox));
    13441319                }
    13451320            }
    1346         }
    1347 
    1348         /* Hard disks */
    1349         if (vsysThis.mapVirtualDisks.size() > 0)
    1350         {
    1351             // @todo:
    1352             //  - strHref could be empty (construct a new default file name)
    1353             //  - check that the filename is unique to vbox in any case
    1354             VirtualDisksMap::const_iterator hdIt;
    1355             /* Iterate through all hard disks ()*/
    1356             for (hdIt = vsysThis.mapVirtualDisks.begin();
    1357                  hdIt != vsysThis.mapVirtualDisks.end();
    1358                  ++hdIt)
     1321
     1322            /* Floppy Drive */
     1323            if (vsysThis.fHasFloppyDrive)
     1324                pNewDesc->addEntry(VirtualSystemDescriptionType_Floppy, 0, "", "");
     1325
     1326            /* CD Drive */
     1327            if (vsysThis.fHasCdromDrive)
     1328                pNewDesc->addEntry(VirtualSystemDescriptionType_CDROM, 0, "", "");
     1329
     1330            /* Hard disk Controller */
     1331            ControllersMap::const_iterator hdcIt;
     1332            /* Iterate through all hard disk controllers */
     1333            for (hdcIt = vsysThis.mapControllers.begin();
     1334                 hdcIt != vsysThis.mapControllers.end();
     1335                 ++hdcIt)
    13591336            {
    1360                 const VirtualDisk &hd = hdIt->second;
    1361                 /* Get the associated disk image */
    1362                 const DiskImage &di = m->mapDisks[hd.strDiskId];
    1363 
    1364                 // @todo:
    1365                 //  - figure out all possible vmdk formats we also support
    1366                 //  - figure out if there is a url specifier for vhd already
    1367                 //  - we need a url specifier for the vdi format
    1368                 if (    (!RTStrICmp(di.strFormat.c_str(), "http://www.vmware.com/specifications/vmdk.html#sparse"))
    1369                      || (!RTStrICmp(di.strFormat.c_str(), "http://www.vmware.com/specifications/vmdk.html#compressed"))
    1370                    )
     1337                const HardDiskController &hdc = hdcIt->second;
     1338                switch (hdc.system)
    13711339                {
    1372                     /* Construct the path */
    1373                     Utf8StrFmt path("%ls%c%s", bstrDefaultHardDiskLocation.raw(), RTPATH_DELIMITER, di.strHref.c_str());
    1374                     /* Make the path unique to the VBox installation */
    1375                     searchUniqueDiskImageFilePath(path);
    1376                     pNewDesc->addEntry(VirtualSystemDescriptionType_HardDiskImage,
    1377                                        hd.idController,
    1378                                        di.strHref,
    1379                                        path);
     1340                    case HardDiskController::IDE:
     1341                        {
     1342                            // @todo: figure out the IDE types
     1343                            /* Use PIIX4 as default */
     1344                            IDEControllerType_T hdcController = IDEControllerType_PIIX4;
     1345                            if (!RTStrICmp(hdc.strControllerType.c_str(), "PIIX3"))
     1346                                hdcController = IDEControllerType_PIIX3;
     1347                            else if (!RTStrICmp(hdc.strControllerType.c_str(), "PIIX4"))
     1348                                hdcController = IDEControllerType_PIIX4;
     1349                            pNewDesc->addEntry(VirtualSystemDescriptionType_HardDiskControllerIDE,
     1350                                               hdc.idController,
     1351                                               hdc.strControllerType,
     1352                                               toString<ULONG>(hdcController));
     1353                            break;
     1354                        }
     1355
     1356                    case HardDiskController::SATA:
     1357                        {
     1358                            // @todo: figure out the SATA types
     1359                            /* We only support a plain AHCI controller, so use them always */
     1360                            pNewDesc->addEntry(VirtualSystemDescriptionType_HardDiskControllerSATA,
     1361                                               hdc.idController,
     1362                                               hdc.strControllerType,
     1363                                               "AHCI");
     1364                            break;
     1365                        }
     1366
     1367                    case HardDiskController::SCSI:
     1368                        {
     1369                            // @todo: figure out the SCSI types
     1370                            Utf8Str hdcController = "LsiLogic";
     1371                            if (!RTStrICmp(hdc.strControllerType.c_str(), "LsiLogic"))
     1372                                hdcController = "LsiLogic";
     1373                            else if (!RTStrICmp(hdc.strControllerType.c_str(), "BusLogic"))
     1374                                hdcController = "BusLogic";
     1375                            pNewDesc->addEntry(VirtualSystemDescriptionType_HardDiskControllerSCSI,
     1376                                               hdc.idController,
     1377                                               hdc.strControllerType,
     1378                                               hdcController);
     1379                            break;
     1380                        }
    13801381                }
    13811382            }
     1383
     1384            /* Hard disks */
     1385            if (vsysThis.mapVirtualDisks.size() > 0)
     1386            {
     1387                // @todo:
     1388                //  - strHref could be empty (construct a new default file name)
     1389                //  - check that the filename is unique to vbox in any case
     1390                VirtualDisksMap::const_iterator hdIt;
     1391                /* Iterate through all hard disks ()*/
     1392                for (hdIt = vsysThis.mapVirtualDisks.begin();
     1393                     hdIt != vsysThis.mapVirtualDisks.end();
     1394                     ++hdIt)
     1395                {
     1396                    const VirtualDisk &hd = hdIt->second;
     1397                    /* Get the associated disk image */
     1398                    const DiskImage &di = m->mapDisks[hd.strDiskId];
     1399
     1400                    // @todo:
     1401                    //  - figure out all possible vmdk formats we also support
     1402                    //  - figure out if there is a url specifier for vhd already
     1403                    //  - we need a url specifier for the vdi format
     1404                    if (    (!RTStrICmp(di.strFormat.c_str(), "http://www.vmware.com/specifications/vmdk.html#sparse"))
     1405                            || (!RTStrICmp(di.strFormat.c_str(), "http://www.vmware.com/specifications/vmdk.html#compressed"))
     1406                       )
     1407                    {
     1408                        /* Construct the path */
     1409                        Utf8StrFmt path("%ls%c%s", bstrDefaultHardDiskLocation.raw(), RTPATH_DELIMITER, di.strHref.c_str());
     1410                        /* Make the path unique to the VBox installation */
     1411                        searchUniqueDiskImageFilePath(path);
     1412                        pNewDesc->addEntry(VirtualSystemDescriptionType_HardDiskImage,
     1413                                           hd.idController,
     1414                                           di.strHref,
     1415                                           path);
     1416                    }
     1417                }
     1418            }
     1419
     1420            m->virtualSystemDescriptions.push_back(pNewDesc);
    13821421        }
    1383 
    1384         m->virtualSystemDescriptions.push_back(pNewDesc);
    13851422    }
    1386 
    1387     return S_OK;
    1388 }
    1389 
    1390 STDMETHODIMP Appliance::ImportAppliance()
    1391 {
    1392     // @todo: we need definitely a IProgress object here (disk image copying, ...)
     1423    catch (HRESULT aRC)
     1424    {
     1425        /* On error we clear the list & return */
     1426        //m->virtualSystemDescriptions.clear();
     1427        rc = aRC;
     1428    }
     1429
     1430    return rc;
     1431}
     1432
     1433STDMETHODIMP Appliance::ImportAppliance(IProgress **aProgress)
     1434{
     1435    CheckComArgOutPointerValid(aProgress);
     1436
    13931437    AutoCaller autoCaller(this);
    13941438    CheckComRCReturnRC(autoCaller.rc());
    13951439
     1440    AutoReadLock(this);
     1441
    13961442    HRESULT rc = S_OK;
    13971443
    1398     list<VirtualSystem>::const_iterator it;
    1399     list< ComObjPtr<VirtualSystemDescription> >::const_iterator it1;
    1400     /* Iterate through all virtual systems of that appliance */
    1401     size_t i = 0;
    1402     for (it = m->llVirtualSystems.begin(),
    1403             it1 = m->virtualSystemDescriptions.begin();
    1404          it != m->llVirtualSystems.end();
    1405          ++it, ++it1, ++i)
     1444    ComObjPtr<Progress> progress;
     1445
     1446    try
    14061447    {
    1407         const VirtualSystem &vsysThis = *it;
    1408         ComObjPtr<VirtualSystemDescription> vsdescThis = (*it1);
    1409 
    1410         /* Guest OS type */
    1411         std::list<VirtualSystemDescriptionEntry*> vsdeOS = vsdescThis->findByType(VirtualSystemDescriptionType_OS);
    1412         Assert(vsdeOS.size() == 1);
    1413         const Utf8Str &osTypeVBox = vsdeOS.front()->strConfig;
    1414 
    1415         /* Now that we know the base system get our internal defaults based on that. */
    1416         ComPtr<IGuestOSType> osType;
    1417         rc = mVirtualBox->GetGuestOSType(Bstr(osTypeVBox), osType.asOutParam());
    1418         ComAssertComRCThrowRC(rc);
    1419 
    1420         /* Create the machine */
    1421         /* First get the name */
    1422         std::list<VirtualSystemDescriptionEntry*> vsdeName = vsdescThis->findByType(VirtualSystemDescriptionType_Name);
    1423         Assert(vsdeName.size() == 1);
    1424         const Utf8Str &nameVBox = vsdeName.front()->strConfig;
    1425         ComPtr<IMachine> newMachine;
    1426         rc = mVirtualBox->CreateMachine(Bstr(nameVBox), Bstr(osTypeVBox),
    1427                                         Bstr(), Guid(),
    1428                                         newMachine.asOutParam());
    1429         ComAssertComRCThrowRC(rc);
    1430 
    1431         /* CPU count (ignored for now) */
    1432         /* @todo: check min/max requirements of VBox (SchemaDefs::Min/MaxCPUCount) */
    1433         // EntriesList vsdeCPU = vsd->findByType (VirtualSystemDescriptionType_CPU);
    1434 
    1435         /* RAM */
    1436         /* @todo: check min/max requirements of VBox (SchemaDefs::Min/MaxGuestRAM) */
    1437         std::list<VirtualSystemDescriptionEntry*> vsdeRAM = vsdescThis->findByType(VirtualSystemDescriptionType_Memory);
    1438         Assert(vsdeRAM.size() == 1);
    1439         const Utf8Str &memoryVBox = vsdeRAM.front()->strConfig;
    1440         uint64_t tt = RTStrToUInt64(memoryVBox.c_str()) / _1M;
    1441 
    1442         rc = newMachine->COMSETTER(MemorySize)(tt);
    1443         ComAssertComRCThrowRC(rc);
    1444 
    1445         /* VRAM */
    1446         /* Get the recommended VRAM for this guest OS type */
    1447         /* @todo: check min/max requirements of VBox (SchemaDefs::Min/MaxGuestVRAM) */
    1448         ULONG vramVBox;
    1449         rc = osType->COMGETTER(RecommendedVRAM)(&vramVBox);
    1450         ComAssertComRCThrowRC(rc);
    1451         /* Set the VRAM */
    1452         rc = newMachine->COMSETTER(VRAMSize)(vramVBox);
    1453         ComAssertComRCThrowRC(rc);
    1454 
    1455 
    1456         /* Audio Adapter */
    1457         std::list<VirtualSystemDescriptionEntry*> vsdeAudioAdapter = vsdescThis->findByType(VirtualSystemDescriptionType_SoundCard);
    1458         /* @todo: we support one audio adapter only */
    1459         if (vsdeAudioAdapter.size() > 0)
    1460         {
    1461             const Utf8Str& audioAdapterVBox = vsdeAudioAdapter.front()->strConfig;
    1462             if (RTStrICmp(audioAdapterVBox, "null") != 0)
    1463             {
    1464                 uint32_t audio = RTStrToUInt32(audioAdapterVBox.c_str());
    1465                 ComPtr<IAudioAdapter> audioAdapter;
    1466                 rc = newMachine->COMGETTER(AudioAdapter)(audioAdapter.asOutParam());
    1467                 ComAssertComRCThrowRC(rc);
    1468                 rc = audioAdapter->COMSETTER(Enabled)(true);
    1469                 ComAssertComRCThrowRC(rc);
    1470                 /* @todo: For now this is preselected, but on Linux for example
    1471                    more drivers are possible. The user should be able to change
    1472                    this also. */
    1473                 AudioDriverType_T adt = AudioDriverType_Null;
    1474 #if defined(RT_OS_WINDOWS)
    1475 # ifdef VBOX_WITH_WINMM
    1476                 adt = AudioDriverType_WinMM;
    1477 # else
    1478                 adt = AudioDriverType_DirectSound;
    1479 # endif
    1480 #elif defined(RT_OS_LINUX)
    1481 # ifdef VBOX_WITH_ALSA
    1482                 adt = AudioDriverType_ALSA;
    1483 # elif defined(VBOX_WITH_PULSE)
    1484                 adt = AudioDriverType_Pulse;
    1485 # else
    1486                 adt = AudioDriverType_OSS;
    1487 # endif
    1488 #elif defined(RT_OS_DARWIN)
    1489                 adt = AudioDriverType_CoreAudio;
    1490 #elif defined(RT_OS_SOLARIS)
    1491                 adt = AudioDriverType_SolAudio;
    1492 #elif defined(RT_OS_OS2)
    1493                 adt = AudioDriverType_MMPM;
    1494 #endif
    1495                 rc = audioAdapter->COMSETTER(AudioDriver)(adt);
    1496                 ComAssertComRCThrowRC(rc);
    1497                 rc = audioAdapter->COMSETTER(AudioController)(static_cast<AudioControllerType_T>(audio));
    1498                 ComAssertComRCThrowRC(rc);
    1499             }
    1500         }
    1501 
    1502         /* USB Controller */
    1503         std::list<VirtualSystemDescriptionEntry*> vsdeUSBController = vsdescThis->findByType(VirtualSystemDescriptionType_USBController);
    1504         /* If there is no USB controller entry it will be disabled */
    1505         bool fUSBEnabled = vsdeUSBController.size() > 0;
    1506         if (fUSBEnabled)
    1507         {
    1508             /* Check if the user has disabled the USB controller in the client */
    1509             const Utf8Str& usbVBox = vsdeUSBController.front()->strConfig;
    1510             fUSBEnabled = usbVBox == "1";
    1511         }
    1512         ComPtr<IUSBController> usbController;
    1513         rc = newMachine->COMGETTER(USBController)(usbController.asOutParam());
    1514         ComAssertComRCThrowRC(rc);
    1515         rc = usbController->COMSETTER(Enabled)(fUSBEnabled);
    1516         ComAssertComRCThrowRC(rc);
    1517 
    1518         /* Change the network adapters */
    1519         std::list<VirtualSystemDescriptionEntry*> vsdeNW = vsdescThis->findByType(VirtualSystemDescriptionType_NetworkAdapter);
    1520         if (vsdeNW.size() == 0)
    1521         {
    1522             /* No network adapters, so we have to disable our default one */
    1523             ComPtr<INetworkAdapter> nwVBox;
    1524             rc = newMachine->GetNetworkAdapter(0, nwVBox.asOutParam());
    1525             ComAssertComRCThrowRC(rc);
    1526             rc = nwVBox->COMSETTER(Enabled)(false);
    1527             ComAssertComRCThrowRC(rc);
    1528         }
    1529         else
    1530         {
    1531             list<VirtualSystemDescriptionEntry*>::const_iterator nwIt;
    1532             /* Iterate through all network cards. We support 8 network adapters
    1533              * at the maximum. (@todo: warn if it are more!) */
    1534             size_t a = 0;
    1535             for (nwIt = vsdeNW.begin();
    1536                  (nwIt != vsdeNW.end() && a < SchemaDefs::NetworkAdapterCount);
    1537                  ++nwIt, ++a)
    1538             {
    1539                 const Utf8Str &nwTypeVBox = (*nwIt)->strConfig;
    1540                 uint32_t tt1 = RTStrToUInt32(nwTypeVBox.c_str());
    1541                 ComPtr<INetworkAdapter> nwVBox;
    1542                 rc = newMachine->GetNetworkAdapter((ULONG)a, nwVBox.asOutParam());
    1543                 ComAssertComRCThrowRC(rc);
    1544                 /* Enable the network card & set the adapter type */
    1545                 /* NAT is set as default */
    1546                 rc = nwVBox->COMSETTER(Enabled)(true);
    1547                 ComAssertComRCThrowRC(rc);
    1548                 rc = nwVBox->COMSETTER(AdapterType)(static_cast<NetworkAdapterType_T>(tt1));
    1549                 ComAssertComRCThrowRC(rc);
    1550             }
    1551         }
    1552 
    1553         /* Floppy drive */
    1554         std::list<VirtualSystemDescriptionEntry*> vsdeFloppy = vsdescThis->findByType(VirtualSystemDescriptionType_Floppy);
    1555         /* If there is no floppy drive entry it will be disabled */
    1556         bool fFloppyEnabled = vsdeFloppy.size() > 0;
    1557         if (fFloppyEnabled)
    1558         {
    1559             /* Check if the user has disabled the floppy drive in the client */
    1560             const Utf8Str& floppyVBox = vsdeFloppy.front()->strConfig;
    1561             fFloppyEnabled = floppyVBox == "1";
    1562         }
    1563         ComPtr<IFloppyDrive> floppyDrive;
    1564         rc = newMachine->COMGETTER(FloppyDrive)(floppyDrive.asOutParam());
    1565         ComAssertComRCThrowRC(rc);
    1566         rc = floppyDrive->COMSETTER(Enabled)(fFloppyEnabled);
    1567         ComAssertComRCThrowRC(rc);
    1568 
    1569         /* CDROM drive */
    1570         /* @todo: I can't disable the CDROM. So nothing to do for now */
    1571         // std::list<VirtualSystemDescriptionEntry*> vsdeFloppy = vsd->findByType(VirtualSystemDescriptionType_CDROM);
    1572 
    1573         /* Hard disk controller IDE */
    1574         std::list<VirtualSystemDescriptionEntry*> vsdeHDCIDE = vsdescThis->findByType(VirtualSystemDescriptionType_HardDiskControllerIDE);
    1575         /* @todo: we support one IDE controller only */
    1576         if (vsdeHDCIDE.size() > 0)
    1577         {
    1578              IDEControllerType_T hdcVBox = static_cast<IDEControllerType_T>(RTStrToUInt32(vsdeHDCIDE.front()->strConfig.c_str()));
    1579              /* Set the appropriate IDE controller in the virtual BIOS of the
    1580               * VM. */
    1581              ComPtr<IBIOSSettings> biosSettings;
    1582              rc = newMachine->COMGETTER(BIOSSettings)(biosSettings.asOutParam());
    1583              CheckComRCReturnRC(rc);
    1584              rc = biosSettings->COMSETTER(IDEControllerType)(hdcVBox);
    1585              CheckComRCReturnRC(rc);
    1586         }
    1587 #ifdef VBOX_WITH_AHCI
    1588         /* Hard disk controller SATA */
    1589         std::list<VirtualSystemDescriptionEntry*> vsdeHDCSATA = vsdescThis->findByType(VirtualSystemDescriptionType_HardDiskControllerSATA);
    1590         /* @todo: we support one SATA controller only */
    1591         if (vsdeHDCSATA.size() > 0)
    1592         {
    1593             const Utf8Str &hdcVBox = vsdeHDCIDE.front()->strConfig;
    1594             if (hdcVBox == "AHCI")
    1595             {
    1596                 /* For now we have just to enable the AHCI controller. */
    1597                 ComPtr<ISATAController> hdcSATAVBox;
    1598                 rc = newMachine->COMGETTER(SATAController)(hdcSATAVBox.asOutParam());
    1599                 CheckComRCReturnRC(rc);
    1600                 rc = hdcSATAVBox->COMSETTER(Enabled)(true);
    1601                 CheckComRCReturnRC(rc);
    1602             }
    1603             else
    1604             {
    1605                 /* @todo: set an error if this is other than AHCI */
    1606             }
    1607         }
    1608 #endif /* VBOX_WITH_AHCI */
    1609 #ifdef VBOX_WITH_SCSI
    1610         /* Hard disk controller SCSI */
    1611         EntriesList vsdeHDCSCSI = vsdescThis->findByType(VirtualSystemDescriptionType_HardDiskControllerSCSI);
    1612         /* @todo: do we support more than one SCSI controller? */
    1613         if (vsdeHDCSCSI.size() > 0)
    1614         {
    1615             /* @todo: Currently I have no idea how to enable this. Someone has
    1616              * to write main support for SCSI at all. */
    1617         }
    1618 #endif /* VBOX_WITH_SCSI */
    1619 
    1620         /* Now its time to register the machine before we add any hard disks */
    1621         rc = mVirtualBox->RegisterMachine(newMachine);
    1622         ComAssertComRCThrowRC(rc);
    1623 
    1624         /* Create the hard disks & connect them to the appropriate controllers. */
    1625         std::list<VirtualSystemDescriptionEntry*> avsdeHDs = vsdescThis->findByType(VirtualSystemDescriptionType_HardDiskImage);
    1626         if (avsdeHDs.size() > 0)
    1627         {
    1628             /* That we can attach hard disks we need to open a session for the
    1629              * new machine */
    1630             Guid newMachineId;
    1631             rc = newMachine->COMGETTER(Id)(newMachineId.asOutParam());
    1632             CheckComRCReturnRC(rc);
    1633             ComPtr<ISession> session;
    1634             rc = session.createInprocObject(CLSID_Session);
    1635             CheckComRCReturnRC(rc);
    1636             rc = mVirtualBox->OpenSession(session, newMachineId);
    1637             CheckComRCReturnRC(rc);
    1638 
    1639             int result;
    1640             /* The disk image has to be on the same place as the OVF file. So
    1641              * strip the filename out of the full file path. */
    1642             char *pszSrcDir = RTStrDup(Utf8Str(m->bstrPath).raw());
    1643             RTPathStripFilename(pszSrcDir);
    1644             Utf8Str strSrcDir(pszSrcDir);
    1645             RTStrFree(pszSrcDir);
    1646 
    1647             /* Iterate over all given disk images */
    1648             list<VirtualSystemDescriptionEntry*>::const_iterator hdIt;
    1649             for (hdIt = avsdeHDs.begin();
    1650                  hdIt != avsdeHDs.end();
    1651                  ++hdIt)
    1652             {
    1653                 const VirtualSystemDescriptionEntry &vsdeHD = (**hdIt);
    1654 
    1655                 const char *pcszDestFilePath = vsdeHD.strConfig.c_str();
    1656                 /* Check if the destination file exists already or the
    1657                  * destination path is empty. */
    1658                 if (RTPathExists(pcszDestFilePath) ||
    1659                     !RTStrCmp(pcszDestFilePath, ""))
    1660                 {
    1661                     /* @todo: what now? For now we override in no
    1662                      * circumstances. */
    1663                     continue;
    1664                 }
    1665 
    1666                 uint32_t ulRef = (*hdIt)->ulRef;
    1667                 /* Get the associated disk image */
    1668                 if (m->mapDisks.find(ulRef) == m->mapDisks.end() ||
    1669                     vsysThis.mapVirtualDisks.find(ulRef) == vsysThis.mapVirtualDisks.end())
    1670                 {
    1671                     /* @todo: error: entry doesn't exists */
    1672                 }
    1673                 DiskImage di = m->mapDisks[ulRef];
    1674                 VirtualDisk vd = (*vsysThis.mapVirtualDisks.find(ulRef)).second;
    1675                 /* Construct the source file path */
    1676                 Utf8StrFmt strSrcFilePath("%s/%s", strSrcDir.c_str(), di.strHref.c_str());
    1677                 /* Check if the source file exists */
    1678                 if (!RTPathExists(strSrcFilePath.c_str()))
    1679                 {
    1680                     /* @todo: we have to create a new one */
    1681                 }
    1682                 else
    1683                 {
    1684                     /* Make sure all target directories exists */
    1685                     rc = VirtualBox::ensureFilePathExists(pcszDestFilePath);
    1686                     CheckComRCThrowRC(rc);
    1687                     /* Clone the disk image (this is necessary cause the id has
    1688                      * to be recreated for the case the same hard disk is
    1689                      * attached already from a previous import) */
    1690                     /* First open the existing disk image */
    1691                     ComPtr<IHardDisk2> srcHdVBox;
    1692                     rc = mVirtualBox->OpenHardDisk2(Bstr(strSrcFilePath), srcHdVBox.asOutParam());
    1693                     CheckComRCReturnRC(rc);
    1694                     /* We need the format description of the source disk image */
    1695                     Bstr srcFormat;
    1696                     rc = srcHdVBox->COMGETTER(Format)(srcFormat.asOutParam());
    1697                     CheckComRCReturnRC(rc);
    1698                     /* Create a new hard disk interface for the destination disk image */
    1699                     ComPtr<IHardDisk2> dstHdVBox;
    1700                     rc = mVirtualBox->CreateHardDisk2(srcFormat, Bstr(pcszDestFilePath), dstHdVBox.asOutParam());
    1701                     CheckComRCReturnRC(rc);
    1702                     /* Clone the source disk image */
    1703                     ComPtr<IProgress> progress;
    1704                     rc = srcHdVBox->CloneTo(dstHdVBox, progress.asOutParam());
    1705                     CheckComRCReturnRC(rc);
    1706                     rc = progress->WaitForCompletion(-1);
    1707                     CheckComRCReturnRC(rc);
    1708                     /* We *must* close the source disk image in order to deregister it */
    1709                     rc = srcHdVBox->Close();
    1710                     CheckComRCReturnRC(rc);
    1711                     /* Now use the new uuid to attach the disk image to our new machine */
    1712                     ComPtr<IMachine> sMachine;
    1713                     rc = session->COMGETTER(Machine)(sMachine.asOutParam());
    1714                     Guid hdId;
    1715                     rc = dstHdVBox->COMGETTER(Id)(hdId.asOutParam());;
    1716                     CheckComRCReturnRC(rc);
    1717                     /* For now we assume we have one controller of every type only */
    1718                     HardDiskController hdc = (*vsysThis.mapControllers.find(vd.idController)).second;
    1719                     StorageBus_T sbt = StorageBus_IDE;
    1720                     switch (hdc.system)
    1721                     {
    1722                         case HardDiskController::IDE: sbt = StorageBus_IDE; break;
    1723                         case HardDiskController::SATA: sbt = StorageBus_SATA; break;
    1724                         //case SCSI: sbt = StorageBus_SCSI; break; // @todo: not available yet
    1725                         default: break;
    1726                     }
    1727                     rc = sMachine->AttachHardDisk2(hdId, sbt, hdc.ulBusNumber, 0);
    1728                     CheckComRCReturnRC(rc);
    1729                     rc = sMachine->SaveSettings();
    1730                     CheckComRCReturnRC(rc);
    1731                     rc = session->Close();
    1732                     CheckComRCReturnRC(rc);
    1733                 }
    1734             }
    1735         }
    1736         /* @todo: Unregister on failure */
    1737 #if 0
    1738         vbox.UnregisterMachine (machineId);
    1739         if (vbox.isOk())
    1740             mMachine.DeleteSettings();
    1741         return false;
    1742 #endif
     1448        /* Create the progress object */
     1449        progress.createObject();
     1450        rc = progress->init(mVirtualBox, static_cast<IAppliance *>(this),
     1451                            BstrFmt(tr("Import appliance '%ls'"),
     1452                                    m->bstrPath.raw()),
     1453                            FALSE /* aCancelable */);
     1454        CheckComRCThrowRC(rc);
     1455
     1456        /* Initialize our worker task */
     1457        std::auto_ptr<Task> task(new Task(this, progress));
     1458        //AssertComRCThrowRC (task->autoCaller.rc());
     1459
     1460        rc = task->startThread();
     1461        CheckComRCThrowRC(rc);
     1462
     1463        task.release();
    17431464    }
    1744 
    1745     return S_OK;
     1465    catch (HRESULT aRC)
     1466    {
     1467        rc = aRC;
     1468    }
     1469
     1470    if (SUCCEEDED(rc))
     1471        /* Return progress to the caller */
     1472        progress.queryInterfaceTo(aProgress);
     1473
     1474    return rc;
    17461475}
    17471476
     
    17921521}
    17931522
     1523/* static */
     1524DECLCALLBACK(int) Appliance::taskThread(RTTHREAD aThread, void *pvUser)
     1525{
     1526    std::auto_ptr <Task> task(static_cast<Task *>(pvUser));
     1527    AssertReturn(task.get(), VERR_GENERAL_FAILURE);
     1528
     1529    Appliance *app = task->that;
     1530
     1531    /// @todo ugly hack, fix ComAssert... (same as in HardDisk2::taskThread)
     1532    #define setError app->setError
     1533
     1534    AutoCaller autoCaller(app);
     1535    CheckComRCReturnRC(autoCaller.rc());
     1536
     1537    AutoWriteLock appLock(app);
     1538
     1539    HRESULT rc = S_OK;
     1540
     1541    /* For now we report 2 steps for every virtual system. Later we may add the
     1542       progress of the image cloning. */
     1543    float opCountMax = 100.0/(app->m->llVirtualSystems.size() * 2);
     1544    uint32_t opCount = 0;
     1545
     1546    list<VirtualSystem>::const_iterator it;
     1547    list< ComObjPtr<VirtualSystemDescription> >::const_iterator it1;
     1548    /* Iterate through all virtual systems of that appliance */
     1549    size_t i = 0;
     1550    for (it = app->m->llVirtualSystems.begin(),
     1551            it1 = app->m->virtualSystemDescriptions.begin();
     1552         it != app->m->llVirtualSystems.end();
     1553         ++it, ++it1, ++i)
     1554    {
     1555        const VirtualSystem &vsysThis = *it;
     1556        ComObjPtr<VirtualSystemDescription> vsdescThis = (*it1);
     1557
     1558        /* Catch possible errors */
     1559        try
     1560        {
     1561            /* Guest OS type */
     1562            std::list<VirtualSystemDescriptionEntry*> vsdeOS = vsdescThis->findByType(VirtualSystemDescriptionType_OS);
     1563            Assert(vsdeOS.size() == 1);
     1564            const Utf8Str &osTypeVBox = vsdeOS.front()->strConfig;
     1565
     1566            /* Now that we know the base system get our internal defaults based on that. */
     1567            ComPtr<IGuestOSType> osType;
     1568            rc = app->mVirtualBox->GetGuestOSType(Bstr(osTypeVBox), osType.asOutParam());
     1569            CheckComRCThrowRC(rc);
     1570
     1571            /* Create the machine */
     1572            /* First get the name */
     1573            std::list<VirtualSystemDescriptionEntry*> vsdeName = vsdescThis->findByType(VirtualSystemDescriptionType_Name);
     1574            Assert(vsdeName.size() == 1);
     1575            const Utf8Str &nameVBox = vsdeName.front()->strConfig;
     1576            ComPtr<IMachine> newMachine;
     1577            rc = app->mVirtualBox->CreateMachine(Bstr(nameVBox.c_str()), Bstr(osTypeVBox.c_str()),
     1578                                                 Bstr(), Guid(),
     1579                                                 newMachine.asOutParam());
     1580            CheckComRCThrowRC(rc);
     1581
     1582            /* CPU count (ignored for now) */
     1583            /* @todo: check min/max requirements of VBox (SchemaDefs::Min/MaxCPUCount) */
     1584            // EntriesList vsdeCPU = vsd->findByType (VirtualSystemDescriptionType_CPU);
     1585
     1586            /* RAM */
     1587            /* @todo: check min/max requirements of VBox (SchemaDefs::Min/MaxGuestRAM) */
     1588            std::list<VirtualSystemDescriptionEntry*> vsdeRAM = vsdescThis->findByType(VirtualSystemDescriptionType_Memory);
     1589            Assert(vsdeRAM.size() == 1);
     1590            const Utf8Str &memoryVBox = vsdeRAM.front()->strConfig;
     1591            uint64_t tt = RTStrToUInt64(memoryVBox.c_str()) / _1M;
     1592
     1593            rc = newMachine->COMSETTER(MemorySize)(tt);
     1594            CheckComRCThrowRC(rc);
     1595
     1596            /* VRAM */
     1597            /* Get the recommended VRAM for this guest OS type */
     1598            /* @todo: check min/max requirements of VBox (SchemaDefs::Min/MaxGuestVRAM) */
     1599            ULONG vramVBox;
     1600            rc = osType->COMGETTER(RecommendedVRAM)(&vramVBox);
     1601            CheckComRCThrowRC(rc);
     1602            /* Set the VRAM */
     1603            rc = newMachine->COMSETTER(VRAMSize)(vramVBox);
     1604            CheckComRCThrowRC(rc);
     1605
     1606            /* Audio Adapter */
     1607            std::list<VirtualSystemDescriptionEntry*> vsdeAudioAdapter = vsdescThis->findByType(VirtualSystemDescriptionType_SoundCard);
     1608            /* @todo: we support one audio adapter only */
     1609            if (vsdeAudioAdapter.size() > 0)
     1610            {
     1611                const Utf8Str& audioAdapterVBox = vsdeAudioAdapter.front()->strConfig;
     1612                if (RTStrICmp(audioAdapterVBox, "null") != 0)
     1613                {
     1614                    uint32_t audio = RTStrToUInt32(audioAdapterVBox.c_str());
     1615                    ComPtr<IAudioAdapter> audioAdapter;
     1616                    rc = newMachine->COMGETTER(AudioAdapter)(audioAdapter.asOutParam());
     1617                    CheckComRCThrowRC(rc);
     1618                    rc = audioAdapter->COMSETTER(Enabled)(true);
     1619                    CheckComRCThrowRC(rc);
     1620                    /* @todo: For now this is preselected, but on Linux for example
     1621                       more drivers are possible. The user should be able to change
     1622                       this also. */
     1623                    AudioDriverType_T adt = AudioDriverType_Null;
     1624#if defined(RT_OS_WINDOWS)
     1625# ifdef VBOX_WITH_WINMM
     1626                    adt = AudioDriverType_WinMM;
     1627# else
     1628                    adt = AudioDriverType_DirectSound;
     1629# endif
     1630#elif defined(RT_OS_LINUX)
     1631# ifdef VBOX_WITH_ALSA
     1632                    adt = AudioDriverType_ALSA;
     1633# elif defined(VBOX_WITH_PULSE)
     1634                    adt = AudioDriverType_Pulse;
     1635# else
     1636                    adt = AudioDriverType_OSS;
     1637# endif
     1638#elif defined(RT_OS_DARWIN)
     1639                    adt = AudioDriverType_CoreAudio;
     1640#elif defined(RT_OS_SOLARIS)
     1641                    adt = AudioDriverType_SolAudio;
     1642#elif defined(RT_OS_OS2)
     1643                    adt = AudioDriverType_MMPM;
     1644#endif
     1645                    rc = audioAdapter->COMSETTER(AudioDriver)(adt);
     1646                    CheckComRCThrowRC(rc);
     1647                    rc = audioAdapter->COMSETTER(AudioController)(static_cast<AudioControllerType_T>(audio));
     1648                    CheckComRCThrowRC(rc);
     1649                }
     1650            }
     1651
     1652            /* USB Controller */
     1653            std::list<VirtualSystemDescriptionEntry*> vsdeUSBController = vsdescThis->findByType(VirtualSystemDescriptionType_USBController);
     1654            /* If there is no USB controller entry it will be disabled */
     1655            bool fUSBEnabled = vsdeUSBController.size() > 0;
     1656            if (fUSBEnabled)
     1657            {
     1658                /* Check if the user has disabled the USB controller in the client */
     1659                const Utf8Str& usbVBox = vsdeUSBController.front()->strConfig;
     1660                fUSBEnabled = usbVBox == "1";
     1661            }
     1662            ComPtr<IUSBController> usbController;
     1663            rc = newMachine->COMGETTER(USBController)(usbController.asOutParam());
     1664            CheckComRCThrowRC(rc);
     1665            rc = usbController->COMSETTER(Enabled)(fUSBEnabled);
     1666            CheckComRCThrowRC(rc);
     1667
     1668            /* Change the network adapters */
     1669            std::list<VirtualSystemDescriptionEntry*> vsdeNW = vsdescThis->findByType(VirtualSystemDescriptionType_NetworkAdapter);
     1670            if (vsdeNW.size() == 0)
     1671            {
     1672                /* No network adapters, so we have to disable our default one */
     1673                ComPtr<INetworkAdapter> nwVBox;
     1674                rc = newMachine->GetNetworkAdapter(0, nwVBox.asOutParam());
     1675                CheckComRCThrowRC(rc);
     1676                rc = nwVBox->COMSETTER(Enabled)(false);
     1677                CheckComRCThrowRC(rc);
     1678            }
     1679            else
     1680            {
     1681                list<VirtualSystemDescriptionEntry*>::const_iterator nwIt;
     1682                /* Iterate through all network cards. We support 8 network adapters
     1683                 * at the maximum. (@todo: warn if it are more!) */
     1684                size_t a = 0;
     1685                for (nwIt = vsdeNW.begin();
     1686                     (nwIt != vsdeNW.end() && a < SchemaDefs::NetworkAdapterCount);
     1687                     ++nwIt, ++a)
     1688                {
     1689                    const Utf8Str &nwTypeVBox = (*nwIt)->strConfig;
     1690                    uint32_t tt1 = RTStrToUInt32(nwTypeVBox.c_str());
     1691                    ComPtr<INetworkAdapter> nwVBox;
     1692                    rc = newMachine->GetNetworkAdapter((ULONG)a, nwVBox.asOutParam());
     1693                    CheckComRCThrowRC(rc);
     1694                    /* Enable the network card & set the adapter type */
     1695                    /* NAT is set as default */
     1696                    rc = nwVBox->COMSETTER(Enabled)(true);
     1697                    CheckComRCThrowRC(rc);
     1698                    rc = nwVBox->COMSETTER(AdapterType)(static_cast<NetworkAdapterType_T>(tt1));
     1699                    CheckComRCThrowRC(rc);
     1700                }
     1701            }
     1702
     1703            /* Floppy drive */
     1704            std::list<VirtualSystemDescriptionEntry*> vsdeFloppy = vsdescThis->findByType(VirtualSystemDescriptionType_Floppy);
     1705            /* If there is no floppy drive entry it will be disabled */
     1706            bool fFloppyEnabled = vsdeFloppy.size() > 0;
     1707            if (fFloppyEnabled)
     1708            {
     1709                /* Check if the user has disabled the floppy drive in the client */
     1710                const Utf8Str& floppyVBox = vsdeFloppy.front()->strConfig;
     1711                fFloppyEnabled = floppyVBox == "1";
     1712            }
     1713            ComPtr<IFloppyDrive> floppyDrive;
     1714            rc = newMachine->COMGETTER(FloppyDrive)(floppyDrive.asOutParam());
     1715            CheckComRCThrowRC(rc);
     1716            rc = floppyDrive->COMSETTER(Enabled)(fFloppyEnabled);
     1717            CheckComRCThrowRC(rc);
     1718
     1719            /* CDROM drive */
     1720            /* @todo: I can't disable the CDROM. So nothing to do for now */
     1721            // std::list<VirtualSystemDescriptionEntry*> vsdeFloppy = vsd->findByType(VirtualSystemDescriptionType_CDROM);
     1722
     1723            /* Hard disk controller IDE */
     1724            std::list<VirtualSystemDescriptionEntry*> vsdeHDCIDE = vsdescThis->findByType(VirtualSystemDescriptionType_HardDiskControllerIDE);
     1725            /* @todo: we support one IDE controller only */
     1726            if (vsdeHDCIDE.size() > 0)
     1727            {
     1728                IDEControllerType_T hdcVBox = static_cast<IDEControllerType_T>(RTStrToUInt32(vsdeHDCIDE.front()->strConfig.c_str()));
     1729                /* Set the appropriate IDE controller in the virtual BIOS of the
     1730                 * VM. */
     1731                ComPtr<IBIOSSettings> biosSettings;
     1732                rc = newMachine->COMGETTER(BIOSSettings)(biosSettings.asOutParam());
     1733                CheckComRCThrowRC(rc);
     1734                rc = biosSettings->COMSETTER(IDEControllerType)(hdcVBox);
     1735                CheckComRCThrowRC(rc);
     1736            }
     1737#ifdef VBOX_WITH_AHCI
     1738            /* Hard disk controller SATA */
     1739            std::list<VirtualSystemDescriptionEntry*> vsdeHDCSATA = vsdescThis->findByType(VirtualSystemDescriptionType_HardDiskControllerSATA);
     1740            /* @todo: we support one SATA controller only */
     1741            if (vsdeHDCSATA.size() > 0)
     1742            {
     1743                const Utf8Str &hdcVBox = vsdeHDCIDE.front()->strConfig;
     1744                if (hdcVBox == "AHCI")
     1745                {
     1746                    /* For now we have just to enable the AHCI controller. */
     1747                    ComPtr<ISATAController> hdcSATAVBox;
     1748                    rc = newMachine->COMGETTER(SATAController)(hdcSATAVBox.asOutParam());
     1749                    CheckComRCThrowRC(rc);
     1750                    rc = hdcSATAVBox->COMSETTER(Enabled)(true);
     1751                    CheckComRCThrowRC(rc);
     1752                }
     1753                else
     1754                {
     1755                    /* @todo: set an error if this is other than AHCI */
     1756                }
     1757            }
     1758#endif /* VBOX_WITH_AHCI */
     1759#ifdef VBOX_WITH_SCSI
     1760            /* Hard disk controller SCSI */
     1761            EntriesList vsdeHDCSCSI = vsdescThis->findByType(VirtualSystemDescriptionType_HardDiskControllerSCSI);
     1762            /* @todo: do we support more than one SCSI controller? */
     1763            if (vsdeHDCSCSI.size() > 0)
     1764            {
     1765                /* @todo: Currently I have no idea how to enable this. Someone has
     1766                 * to write main support for SCSI at all. */
     1767            }
     1768#endif /* VBOX_WITH_SCSI */
     1769
     1770            /* Now its time to register the machine before we add any hard disks */
     1771            rc = app->mVirtualBox->RegisterMachine(newMachine);
     1772            CheckComRCThrowRC(rc);
     1773
     1774            if (!task->progress.isNull())
     1775                task->progress->notifyProgress(static_cast<ULONG>(opCountMax * opCount++));
     1776
     1777            /* Create the hard disks & connect them to the appropriate controllers. */
     1778            std::list<VirtualSystemDescriptionEntry*> avsdeHDs = vsdescThis->findByType(VirtualSystemDescriptionType_HardDiskImage);
     1779            if (avsdeHDs.size() > 0)
     1780            {
     1781                Guid newMachineId;
     1782                rc = newMachine->COMGETTER(Id)(newMachineId.asOutParam());
     1783                CheckComRCThrowRC(rc);
     1784                /* If in the next block an error occur we have to deregister
     1785                   the machine, so make an extra try/catch block. */
     1786                ComPtr<ISession> session;
     1787                try
     1788                {
     1789                    /* That we can attach hard disks we need to open a session for the
     1790                     * new machine */
     1791                    rc = session.createInprocObject(CLSID_Session);
     1792                    CheckComRCThrowRC(rc);
     1793                    rc = app->mVirtualBox->OpenSession(session, newMachineId);
     1794                    CheckComRCThrowRC(rc);
     1795
     1796                    int result;
     1797                    /* The disk image has to be on the same place as the OVF file. So
     1798                     * strip the filename out of the full file path. */
     1799                    char *pszSrcDir = RTStrDup(Utf8Str(app->m->bstrPath).raw());
     1800                    RTPathStripFilename(pszSrcDir);
     1801                    Utf8Str strSrcDir(pszSrcDir);
     1802                    RTStrFree(pszSrcDir);
     1803
     1804                    /* Iterate over all given disk images */
     1805                    list<VirtualSystemDescriptionEntry*>::const_iterator hdIt;
     1806                    for (hdIt = avsdeHDs.begin();
     1807                         hdIt != avsdeHDs.end();
     1808                         ++hdIt)
     1809                    {
     1810                        const char *pcszDstFilePath = (*hdIt)->strConfig.c_str();
     1811                        /* Check if the destination file exists already or the
     1812                         * destination path is empty. */
     1813                        if (RTPathExists(pcszDstFilePath) ||
     1814                            !RTStrCmp(pcszDstFilePath, ""))
     1815                        {
     1816                            /* This isn't allowed */
     1817                            throw setError(VBOX_E_FILE_ERROR,
     1818                                           tr("Destination file '%s' exists",
     1819                                              pcszDstFilePath));
     1820                        }
     1821                        ULONG ulRef = (*hdIt)->ulRef;
     1822                        /* Get the associated disk image */
     1823                        if (app->m->mapDisks.find(ulRef) == app->m->mapDisks.end() ||
     1824                            vsysThis.mapVirtualDisks.find(ulRef) == vsysThis.mapVirtualDisks.end())
     1825                        {
     1826                            /* This isn't allowed */
     1827                            throw setError(E_FAIL,
     1828                                           tr("Some internal error occured"));
     1829                        }
     1830                        DiskImage di = app->m->mapDisks[ulRef];
     1831                        VirtualDisk vd = (*vsysThis.mapVirtualDisks.find(ulRef)).second;
     1832                        /* Construct the source file path */
     1833                        Utf8StrFmt strSrcFilePath("%s/%s", strSrcDir.c_str(), di.strHref.c_str());
     1834                        /* Check if the source file exists */
     1835                        if (!RTPathExists(strSrcFilePath.c_str()))
     1836                        {
     1837                            /* @todo: we have to create a new one */
     1838                        }
     1839                        else
     1840                        {
     1841                            /* Make sure all target directories exists */
     1842                            rc = VirtualBox::ensureFilePathExists(pcszDstFilePath);
     1843                            CheckComRCThrowRC(rc);
     1844                            /* Clone the disk image (this is necessary cause the id has
     1845                             * to be recreated for the case the same hard disk is
     1846                             * attached already from a previous import) */
     1847                            /* First open the existing disk image */
     1848                            ComPtr<IHardDisk2> srcHdVBox;
     1849                            rc = app->mVirtualBox->OpenHardDisk2(Bstr(strSrcFilePath), srcHdVBox.asOutParam());
     1850                            CheckComRCThrowRC(rc);
     1851                            /* We need the format description of the source disk image */
     1852                            Bstr srcFormat;
     1853                            rc = srcHdVBox->COMGETTER(Format)(srcFormat.asOutParam());
     1854                            CheckComRCThrowRC(rc);
     1855                            /* Create a new hard disk interface for the destination disk image */
     1856                            ComPtr<IHardDisk2> dstHdVBox;
     1857                            rc = app->mVirtualBox->CreateHardDisk2(srcFormat, Bstr(pcszDstFilePath), dstHdVBox.asOutParam());
     1858                            CheckComRCThrowRC(rc);
     1859                            /* Clone the source disk image */
     1860                            ComPtr<IProgress> progress;
     1861                            rc = srcHdVBox->CloneTo(dstHdVBox, progress.asOutParam());
     1862                            CheckComRCThrowRC(rc);
     1863                            rc = progress->WaitForCompletion(-1);
     1864                            CheckComRCThrowRC(rc);
     1865                            /* We *must* close the source disk image in order to deregister it */
     1866                            rc = srcHdVBox->Close();
     1867                            CheckComRCThrowRC(rc);
     1868                            /* Now use the new uuid to attach the disk image to our new machine */
     1869                            ComPtr<IMachine> sMachine;
     1870                            rc = session->COMGETTER(Machine)(sMachine.asOutParam());
     1871                            Guid hdId;
     1872                            rc = dstHdVBox->COMGETTER(Id)(hdId.asOutParam());;
     1873                            CheckComRCThrowRC(rc);
     1874                            /* For now we assume we have one controller of every type only */
     1875                            HardDiskController hdc = (*vsysThis.mapControllers.find(vd.idController)).second;
     1876                            StorageBus_T sbt = StorageBus_IDE;
     1877                            switch (hdc.system)
     1878                            {
     1879                                case HardDiskController::IDE: sbt = StorageBus_IDE; break;
     1880                                case HardDiskController::SATA: sbt = StorageBus_SATA; break;
     1881                                           //case HardDiskController::SCSI: sbt = StorageBus_SCSI; break; // @todo: not available yet
     1882                                default: break;
     1883                            }
     1884                            rc = sMachine->AttachHardDisk2(hdId, sbt, hdc.ulBusNumber, 0);
     1885                            CheckComRCThrowRC(rc);
     1886                            rc = sMachine->SaveSettings();
     1887                            CheckComRCThrowRC(rc);
     1888                            rc = session->Close();
     1889                            CheckComRCThrowRC(rc);
     1890                        }
     1891                    }
     1892                }
     1893                catch(HRESULT aRC)
     1894                {
     1895                    /* Unregister/Delete the failed machine */
     1896                    /* @todo: Not sure what to do when there are succesfully
     1897                       added disk images. Delete them also? For now we leave
     1898                       them. */
     1899                    if (!session.isNull())
     1900                    {
     1901                        /* If there is an open session, close them before doing
     1902                           anything further. */
     1903                        rc = session->Close();
     1904                        CheckComRCThrowRC(rc);
     1905                    }
     1906                    ComPtr<IMachine> failedMachine;
     1907                    rc = app->mVirtualBox->UnregisterMachine(newMachineId, failedMachine.asOutParam());
     1908                    CheckComRCThrowRC(rc);
     1909                    rc = failedMachine->DeleteSettings();
     1910                    CheckComRCThrowRC(rc);
     1911                    /* Throw the original error number */
     1912                    throw aRC;
     1913                }
     1914            }
     1915            if (!task->progress.isNull())
     1916                task->progress->notifyProgress(static_cast<ULONG>(opCountMax * opCount++));
     1917        }
     1918        catch(HRESULT aRC)
     1919        {
     1920            /* @todo: If we are here an error on importing of *one* virtual
     1921               system has occured. We didn't break now, but try to import the
     1922               other virtual systems. This needs some further discussion. */
     1923            rc = aRC;
     1924        }
     1925    }
     1926
     1927    task->rc = rc;
     1928
     1929    if (!task->progress.isNull())
     1930        task->progress->notifyComplete (rc);
     1931
     1932    /// @todo ugly hack, fix ComAssert... (same as in HardDisk2::taskThread)
     1933    #undef setError
     1934
     1935    return VINF_SUCCESS;
     1936}
     1937
    17941938// IVirtualSystemDescription constructor / destructor
    17951939////////////////////////////////////////////////////////////////////////////////
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r16495 r16503  
    28772877  <interface
    28782878     name="IAppliance" extends="$unknown"
    2879      uuid="f3aa3a74-7b66-425b-9d3d-973924ddf163"
     2879     uuid="a7a71c1f-20d3-4483-95c0-7357dda77f50"
    28802880     wsmap="managed"
    28812881     >
     
    29792979        see <link to="IAppliance" /> for an overview.
    29802980      </desc>
     2981
     2982      <param name="aProgress" type="IProgress" dir="out">
     2983        <desc></desc>
     2984      </param>
    29812985    </method>
    29822986
  • trunk/src/VBox/Main/include/ApplianceImpl.h

    r16495 r16503  
    7373    /* void interpret (); */
    7474    STDMETHOD(Interpret)(void);
     75    STDMETHOD(ImportAppliance)(IProgress **aProgress);
    7576
    7677    /* public methods only for internal purposes */
    77     STDMETHOD(ImportAppliance)();
    7878
    7979    /* private instance data */
     
    8181    /** weak VirtualBox parent */
    8282    const ComObjPtr <VirtualBox, ComWeakRef> mVirtualBox;
     83
     84    struct Task; /* Worker thread for import */
    8385
    8486    struct Data;            // obscure, defined in AppliannceImpl.cpp
     
    9294    HRESULT searchUniqueVMName(Utf8Str& aName) const;
    9395    HRESULT searchUniqueDiskImageFilePath(Utf8Str& aName) const;
     96
     97    static DECLCALLBACK(int) taskThread(RTTHREAD thread, void *pvUser);
    9498};
    9599
注意: 瀏覽 TracChangeset 來幫助您使用更動檢視器

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