儲存庫 vbox 的更動 16503
- 時間撮記:
- 2009-2-4 上午10:31:15 (16 年 以前)
- 位置:
- trunk/src/VBox/Main
- 檔案:
-
- 修改 3 筆資料
圖例:
- 未更動
- 新增
- 刪除
-
trunk/src/VBox/Main/ApplianceImpl.cpp
r16495 r16503 29 29 #include "VirtualBoxImpl.h" 30 30 #include "GuestOSTypeImpl.h" 31 #include "ProgressImpl.h" 31 32 32 33 #include "Logging.h" … … 198 199 }; 199 200 201 struct 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 200 217 // globals 201 218 //////////////////////////////////////////////////////////////////////////////// … … 221 238 * @return S_OK or error. 222 239 */ 223 STDMETHODIMP VirtualBox::OpenAppliance 240 STDMETHODIMP VirtualBox::OpenAppliance(IN_BSTR bstrPath, IAppliance** anAppliance) 224 241 { 225 242 HRESULT rc; … … 234 251 235 252 return rc; 253 } 254 255 // Appliance::task methods 256 //////////////////////////////////////////////////////////////////////////////// 257 258 HRESULT 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; 236 267 } 237 268 … … 1152 1183 default: 1153 1184 { 1154 /* If we are here we have no clue what OS this should be. Set to1155 *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. */ 1156 1187 osTypeVBox = SchemaDefs_OSTypeId_Other; 1157 1188 } … … 1169 1200 CheckComRCReturnRC(autoCaller.rc()); 1170 1201 1202 AutoWriteLock(this); 1203 1171 1204 HRESULT rc = S_OK; 1172 1205 … … 1178 1211 ComPtr<ISystemProperties> systemProps; 1179 1212 rc = mVirtualBox->COMGETTER(SystemProperties)(systemProps.asOutParam()); 1180 C omAssertComRCThrowRC(rc);1213 CheckComRCReturnRC(rc); 1181 1214 Bstr bstrDefaultHardDiskLocation; 1182 1215 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 1190 1219 { 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) 1238 1225 { 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()); 1242 1258 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, 1256 1266 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) 1280 1274 { 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; 1283 1281 } 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) 1303 1304 { 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) 1305 1316 { 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)); 1344 1319 } 1345 1320 } 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) 1359 1336 { 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) 1371 1339 { 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 } 1380 1381 } 1381 1382 } 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); 1382 1421 } 1383 1384 m->virtualSystemDescriptions.push_back(pNewDesc);1385 1422 } 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 1433 STDMETHODIMP Appliance::ImportAppliance(IProgress **aProgress) 1434 { 1435 CheckComArgOutPointerValid(aProgress); 1436 1393 1437 AutoCaller autoCaller(this); 1394 1438 CheckComRCReturnRC(autoCaller.rc()); 1395 1439 1440 AutoReadLock(this); 1441 1396 1442 HRESULT rc = S_OK; 1397 1443 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 1406 1447 { 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(); 1743 1464 } 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; 1746 1475 } 1747 1476 … … 1792 1521 } 1793 1522 1523 /* static */ 1524 DECLCALLBACK(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 1794 1938 // IVirtualSystemDescription constructor / destructor 1795 1939 //////////////////////////////////////////////////////////////////////////////// -
trunk/src/VBox/Main/idl/VirtualBox.xidl
r16495 r16503 2877 2877 <interface 2878 2878 name="IAppliance" extends="$unknown" 2879 uuid=" f3aa3a74-7b66-425b-9d3d-973924ddf163"2879 uuid="a7a71c1f-20d3-4483-95c0-7357dda77f50" 2880 2880 wsmap="managed" 2881 2881 > … … 2979 2979 see <link to="IAppliance" /> for an overview. 2980 2980 </desc> 2981 2982 <param name="aProgress" type="IProgress" dir="out"> 2983 <desc></desc> 2984 </param> 2981 2985 </method> 2982 2986 -
trunk/src/VBox/Main/include/ApplianceImpl.h
r16495 r16503 73 73 /* void interpret (); */ 74 74 STDMETHOD(Interpret)(void); 75 STDMETHOD(ImportAppliance)(IProgress **aProgress); 75 76 76 77 /* public methods only for internal purposes */ 77 STDMETHOD(ImportAppliance)();78 78 79 79 /* private instance data */ … … 81 81 /** weak VirtualBox parent */ 82 82 const ComObjPtr <VirtualBox, ComWeakRef> mVirtualBox; 83 84 struct Task; /* Worker thread for import */ 83 85 84 86 struct Data; // obscure, defined in AppliannceImpl.cpp … … 92 94 HRESULT searchUniqueVMName(Utf8Str& aName) const; 93 95 HRESULT searchUniqueDiskImageFilePath(Utf8Str& aName) const; 96 97 static DECLCALLBACK(int) taskThread(RTTHREAD thread, void *pvUser); 94 98 }; 95 99
注意:
瀏覽 TracChangeset
來幫助您使用更動檢視器