- Timestamp:
- Apr 8, 2010 6:07:13 PM (15 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/ApplianceImplImport.cpp
r28098 r28110 34 34 #include "GuestOSTypeImpl.h" 35 35 #include "ProgressImpl.h" 36 #include "MachineImpl.h" 36 37 37 38 #include "AutoCaller.h" … … 1121 1122 1122 1123 if (vsdescThis->m->pConfig) 1123 importVBoxMachine( *vsdescThis->m->pConfig, pNewMachine, stack);1124 importVBoxMachine(vsdescThis, pNewMachine, stack); 1124 1125 else 1125 1126 importMachineGeneric(vsysThis, vsdescThis, pNewMachine, stack); 1126 1127 } 1127 catch (HRESULT aRC)1128 catch (HRESULT aRC) 1128 1129 { 1129 1130 rc = aRC; … … 1367 1368 size_t a = 0; 1368 1369 for (nwIt = vsdeNW.begin(); 1369 1370 1370 (nwIt != vsdeNW.end() && a < SchemaDefs::NetworkAdapterCount); 1371 ++nwIt, ++a) 1371 1372 { 1372 1373 const VirtualSystemDescriptionEntry* pvsys = *nwIt; … … 1529 1530 if (FAILED(rc)) throw rc; 1530 1531 1532 // store new machine for roll-back in case of errors 1531 1533 Bstr bstrNewMachineId; 1532 1534 rc = pNewMachine->COMGETTER(Id)(bstrNewMachineId.asOutParam()); 1533 1535 if (FAILED(rc)) throw rc; 1534 1535 // store new machine for roll-back in case of errors1536 1536 stack.llMachinesRegistered.push_back(bstrNewMachineId); 1537 1537 … … 1862 1862 * @param stack 1863 1863 */ 1864 void Appliance::importVBoxMachine( const settings::MachineConfigFile &config,1865 ComPtr<IMachine> &p NewMachine,1864 void Appliance::importVBoxMachine(ComObjPtr<VirtualSystemDescription> &vsdescThis, 1865 ComPtr<IMachine> &pReturnNewMachine, 1866 1866 ImportStack &stack) 1867 1867 { 1868 Assert(vsdescThis->m->pConfig); 1869 const settings::MachineConfigFile &config = *vsdescThis->m->pConfig; 1870 1871 // use the name that we computed in the OVF fields to avoid duplicates 1872 std::list<VirtualSystemDescriptionEntry*> vsdeName = vsdescThis->findByType(VirtualSystemDescriptionType_Name); 1873 if (vsdeName.size() < 1) 1874 throw setError(VBOX_E_FILE_ERROR, 1875 tr("Missing VM name")); 1876 const Utf8Str &strNameVBox = vsdeName.front()->strVbox; 1877 1878 ComObjPtr<Machine> pNewMachine; 1879 HRESULT rc = pNewMachine.createObject(); 1880 if (FAILED(rc)) throw rc; 1881 rc = pNewMachine->init(mVirtualBox, strNameVBox, config); 1882 if (FAILED(rc)) throw rc; 1883 1884 IMachine *p; 1885 rc = pNewMachine.queryInterfaceTo(&p); 1886 if (FAILED(rc)) throw rc; 1887 1888 pReturnNewMachine = p; 1889 1890 rc = mVirtualBox->RegisterMachine(pNewMachine); 1891 if (FAILED(rc)) throw rc; 1892 1893 // store new machine for roll-back in case of errors 1894 Bstr bstrNewMachineId; 1895 rc = pNewMachine->COMGETTER(Id)(bstrNewMachineId.asOutParam()); 1896 if (FAILED(rc)) throw rc; 1897 stack.llMachinesRegistered.push_back(bstrNewMachineId); 1868 1898 } 1869 1899 -
trunk/src/VBox/Main/MachineImpl.cpp
r28098 r28110 296 296 if (FAILED(rc)) return rc; 297 297 298 rc = tryCreateMachineConfigFile(aOverride); 299 if (FAILED(rc)) return rc; 300 301 if (SUCCEEDED(rc)) 302 { 303 // create an empty machine config 304 mData->pMachineConfigFile = new settings::MachineConfigFile(NULL); 305 306 rc = initDataAndChildObjects(); 307 } 308 309 if (SUCCEEDED(rc)) 310 { 311 // set to true now to cause uninit() to call uninitDataAndChildObjects() on failure 312 mData->mAccessible = TRUE; 313 314 unconst(mData->mUuid) = aId; 315 316 mUserData->mName = strName; 317 mUserData->mNameSync = aNameSync; 318 319 /* initialize the default snapshots folder 320 * (note: depends on the name value set above!) */ 321 rc = COMSETTER(SnapshotFolder)(NULL); 322 AssertComRC(rc); 323 324 if (aOsType) 325 { 326 /* Store OS type */ 327 mUserData->mOSTypeId = aOsType->id(); 328 329 /* Apply BIOS defaults */ 330 mBIOSSettings->applyDefaults(aOsType); 331 332 /* Apply network adapters defaults */ 333 for (ULONG slot = 0; slot < RT_ELEMENTS(mNetworkAdapters); ++slot) 334 mNetworkAdapters[slot]->applyDefaults(aOsType); 335 336 /* Apply serial port defaults */ 337 for (ULONG slot = 0; slot < RT_ELEMENTS(mSerialPorts); ++slot) 338 mSerialPorts[slot]->applyDefaults(aOsType); 339 } 340 341 /* commit all changes made during the initialization */ 342 commit(); 343 } 344 345 /* Confirm a successful initialization when it's the case */ 346 if (SUCCEEDED(rc)) 347 { 348 if (mData->mAccessible) 349 autoInitSpan.setSucceeded(); 350 else 351 autoInitSpan.setLimited(); 352 } 353 354 LogFlowThisFunc(("mName='%ls', mRegistered=%RTbool, mAccessible=%RTbool, rc=%08X\n", 355 !!mUserData ? mUserData->mName.raw() : NULL, 356 mData->mRegistered, 357 mData->mAccessible, 358 rc)); 359 360 LogFlowThisFuncLeave(); 361 362 return rc; 363 } 364 365 /** 366 * Initializes a new instance with data from machine XML (formerly Init_Registered). 367 * Gets called in two modes: 368 * -- from VirtualBox::initMachines() during VirtualBox startup; in that case, the 369 * UUID is specified and we mark the machine as "registered"; 370 * -- from the public VirtualBox::OpenMachine() API, in which case the UUID is NULL 371 * and the machine remains unregistered until RegisterMachine() is called. 372 * 373 * @param aParent Associated parent object 374 * @param aConfigFile Local file system path to the VM settings file (can 375 * be relative to the VirtualBox config directory). 376 * @param aId UUID of the machine or NULL (see above). 377 * 378 * @return Success indicator. if not S_OK, the machine object is invalid 379 */ 380 HRESULT Machine::init(VirtualBox *aParent, 381 const Utf8Str &strConfigFile, 382 const Guid *aId) 383 { 384 LogFlowThisFuncEnter(); 385 LogFlowThisFunc(("(Init_Registered) aConfigFile='%s\n", strConfigFile.raw())); 386 387 /* Enclose the state transition NotReady->InInit->Ready */ 388 AutoInitSpan autoInitSpan(this); 389 AssertReturn(autoInitSpan.isOk(), E_FAIL); 390 391 HRESULT rc = initImpl(aParent, strConfigFile); 392 if (FAILED(rc)) return rc; 393 394 if (aId) 395 { 396 // loading a registered VM: 397 unconst(mData->mUuid) = *aId; 398 mData->mRegistered = TRUE; 399 // now load the settings from XML: 400 rc = registeredInit(); 401 // this calls initDataAndChildObjects() and loadSettings() 402 } 403 else 404 { 405 // opening an unregistered VM (VirtualBox::OpenMachine()): 406 rc = initDataAndChildObjects(); 407 408 if (SUCCEEDED(rc)) 409 { 410 // set to true now to cause uninit() to call uninitDataAndChildObjects() on failure 411 mData->mAccessible = TRUE; 412 413 try 414 { 415 // load and parse machine XML; this will throw on XML or logic errors 416 mData->pMachineConfigFile = new settings::MachineConfigFile(&mData->m_strConfigFileFull); 417 418 // use UUID from machine config 419 unconst(mData->mUuid) = mData->pMachineConfigFile->uuid; 420 421 rc = loadMachineDataFromSettings(*mData->pMachineConfigFile); 422 if (FAILED(rc)) throw rc; 423 424 commit(); 425 } 426 catch (HRESULT err) 427 { 428 /* we assume that error info is set by the thrower */ 429 rc = err; 430 } 431 catch (...) 432 { 433 rc = VirtualBox::handleUnexpectedExceptions(RT_SRC_POS); 434 } 435 } 436 } 437 438 /* Confirm a successful initialization when it's the case */ 439 if (SUCCEEDED(rc)) 440 { 441 if (mData->mAccessible) 442 autoInitSpan.setSucceeded(); 443 else 444 autoInitSpan.setLimited(); 445 } 446 447 LogFlowThisFunc(("mName='%ls', mRegistered=%RTbool, mAccessible=%RTbool " 448 "rc=%08X\n", 449 !!mUserData ? mUserData->mName.raw() : NULL, 450 mData->mRegistered, mData->mAccessible, rc)); 451 452 LogFlowThisFuncLeave(); 453 454 return rc; 455 } 456 457 /** 458 * Initializes a new instance from a machine config that is already in memory 459 * (import OVF import case). Since we are importing, the UUID in the machine 460 * config is ignored and we always generate a fresh one. 461 * 462 * @param strName Name for the new machine; this overrides what is specified in config and is used 463 * for the settings file as well. 464 * @param config Machine configuration loaded and parsed from XML. 465 * 466 * @return Success indicator. if not S_OK, the machine object is invalid 467 */ 468 HRESULT Machine::init(VirtualBox *aParent, 469 const Utf8Str &strName, 470 const settings::MachineConfigFile &config) 471 { 472 LogFlowThisFuncEnter(); 473 474 /* Enclose the state transition NotReady->InInit->Ready */ 475 AutoInitSpan autoInitSpan(this); 476 AssertReturn(autoInitSpan.isOk(), E_FAIL); 477 478 Utf8Str strConfigFile(aParent->getDefaultMachineFolder()); 479 strConfigFile.append(Utf8StrFmt("%c%s%c%s.xml", 480 RTPATH_DELIMITER, 481 strName.c_str(), 482 RTPATH_DELIMITER, 483 strName.c_str())); 484 485 HRESULT rc = initImpl(aParent, strConfigFile); 486 if (FAILED(rc)) return rc; 487 488 rc = tryCreateMachineConfigFile(FALSE /* aOverride */); 489 if (FAILED(rc)) return rc; 490 491 rc = initDataAndChildObjects(); 492 493 if (SUCCEEDED(rc)) 494 { 495 // set to true now to cause uninit() to call uninitDataAndChildObjects() on failure 496 mData->mAccessible = TRUE; 497 498 // create empty machine config for instance data 499 mData->pMachineConfigFile = new settings::MachineConfigFile(NULL); 500 501 // generate fresh UUID, ignore machine config 502 unconst(mData->mUuid).create(); 503 504 rc = loadMachineDataFromSettings(config); 505 506 // override VM name as well, it may be different 507 mUserData->mName = strName; 508 509 /* commit all changes made during the initialization */ 510 if (SUCCEEDED(rc)) 511 commit(); 512 } 513 514 /* Confirm a successful initialization when it's the case */ 515 if (SUCCEEDED(rc)) 516 { 517 if (mData->mAccessible) 518 autoInitSpan.setSucceeded(); 519 else 520 autoInitSpan.setLimited(); 521 } 522 523 LogFlowThisFunc(("mName='%ls', mRegistered=%RTbool, mAccessible=%RTbool " 524 "rc=%08X\n", 525 !!mUserData ? mUserData->mName.raw() : NULL, 526 mData->mRegistered, mData->mAccessible, rc)); 527 528 LogFlowThisFuncLeave(); 529 530 return rc; 531 } 532 533 /** 534 * Shared code between the various init() implementations. 535 * @param aParent 536 * @return 537 */ 538 HRESULT Machine::initImpl(VirtualBox *aParent, 539 const Utf8Str &strConfigFile) 540 { 541 LogFlowThisFuncEnter(); 542 543 AssertReturn(aParent, E_INVALIDARG); 544 AssertReturn(!strConfigFile.isEmpty(), E_INVALIDARG); 545 546 HRESULT rc = S_OK; 547 548 /* share the parent weakly */ 549 unconst(mParent) = aParent; 550 551 /* allocate the essential machine data structure (the rest will be 552 * allocated later by initDataAndChildObjects() */ 553 mData.allocate(); 554 555 /* memorize the config file name (as provided) */ 556 mData->m_strConfigFile = strConfigFile; 557 558 /* get the full file name */ 559 int vrc1 = mParent->calculateFullPath(strConfigFile, mData->m_strConfigFileFull); 560 if (RT_FAILURE(vrc1)) 561 return setError(VBOX_E_FILE_ERROR, 562 tr("Invalid machine settings file name '%s' (%Rrc)"), 563 strConfigFile.raw(), 564 vrc1); 565 566 LogFlowThisFuncLeave(); 567 568 return rc; 569 } 570 571 /** 572 * Tries to create a machine settings file in the path stored in the machine 573 * instance data. Used when a new machine is created to fail gracefully if 574 * the settings file could not be written (e.g. because machine dir is read-only). 575 * @return 576 */ 577 HRESULT Machine::tryCreateMachineConfigFile(BOOL aOverride) 578 { 579 HRESULT rc = S_OK; 580 298 581 // when we create a new machine, we must be able to create the settings file 299 582 RTFILE f = NIL_RTFILE; … … 327 610 mData->m_strConfigFileFull.raw(), 328 611 vrc); 329 330 if (SUCCEEDED(rc))331 {332 // create an empty machine config333 mData->pMachineConfigFile = new settings::MachineConfigFile(NULL);334 335 rc = initDataAndChildObjects();336 }337 338 if (SUCCEEDED(rc))339 {340 /* set to true now to cause uninit() to call341 * uninitDataAndChildObjects() on failure */342 mData->mAccessible = TRUE;343 344 unconst(mData->mUuid) = aId;345 346 mUserData->mName = strName;347 mUserData->mNameSync = aNameSync;348 349 /* initialize the default snapshots folder350 * (note: depends on the name value set above!) */351 rc = COMSETTER(SnapshotFolder)(NULL);352 AssertComRC(rc);353 354 if (aOsType)355 {356 /* Store OS type */357 mUserData->mOSTypeId = aOsType->id();358 359 /* Apply BIOS defaults */360 mBIOSSettings->applyDefaults(aOsType);361 362 /* Apply network adapters defaults */363 for (ULONG slot = 0; slot < RT_ELEMENTS(mNetworkAdapters); ++slot)364 mNetworkAdapters[slot]->applyDefaults(aOsType);365 366 /* Apply serial port defaults */367 for (ULONG slot = 0; slot < RT_ELEMENTS(mSerialPorts); ++slot)368 mSerialPorts[slot]->applyDefaults(aOsType);369 }370 371 /* commit all changes made during the initialization */372 commit();373 }374 375 /* Confirm a successful initialization when it's the case */376 if (SUCCEEDED(rc))377 {378 if (mData->mAccessible)379 autoInitSpan.setSucceeded();380 else381 autoInitSpan.setLimited();382 }383 384 LogFlowThisFunc(("mName='%ls', mRegistered=%RTbool, mAccessible=%RTbool, rc=%08X\n",385 !!mUserData ? mUserData->mName.raw() : NULL,386 mData->mRegistered,387 mData->mAccessible,388 rc));389 390 LogFlowThisFuncLeave();391 392 return rc;393 }394 395 /**396 * Initializes a new instance with data from machine XML (formerly Init_Registered).397 * Gets called in two modes:398 * -- from VirtualBox::initMachines() during VirtualBox startup; in that case, the399 * UUID is specified and we mark the machine as "registered";400 * -- from the public VirtualBox::OpenMachine() API, in which case the UUID is NULL401 * and the machine remains unregistered until RegisterMachine() is called.402 *403 * @param aParent Associated parent object404 * @param aConfigFile Local file system path to the VM settings file (can405 * be relative to the VirtualBox config directory).406 * @param aId UUID of the machine or NULL (see above).407 *408 * @return Success indicator. if not S_OK, the machine object is invalid409 */410 HRESULT Machine::init(VirtualBox *aParent,411 const Utf8Str &strConfigFile,412 const Guid *aId)413 {414 LogFlowThisFuncEnter();415 LogFlowThisFunc(("(Init_Registered) aConfigFile='%s\n", strConfigFile.raw()));416 417 /* Enclose the state transition NotReady->InInit->Ready */418 AutoInitSpan autoInitSpan(this);419 AssertReturn(autoInitSpan.isOk(), E_FAIL);420 421 HRESULT rc = initImpl(aParent, strConfigFile);422 if (FAILED(rc)) return rc;423 424 if (aId)425 {426 // loading a registered VM:427 unconst(mData->mUuid) = *aId;428 mData->mRegistered = TRUE;429 // now load the settings from XML:430 rc = registeredInit();431 // this calls initDataAndChildObjects() and loadSettings()432 }433 else434 {435 // opening an unregistered VM (VirtualBox::OpenMachine()):436 rc = initDataAndChildObjects();437 438 if (SUCCEEDED(rc))439 {440 /* set to true now to cause uninit() to call441 * uninitDataAndChildObjects() on failure */442 mData->mAccessible = TRUE;443 444 rc = loadSettings(false /* aRegistered */);445 446 /* commit all changes made during the initialization */447 if (SUCCEEDED(rc))448 commit();449 }450 }451 452 /* Confirm a successful initialization when it's the case */453 if (SUCCEEDED(rc))454 {455 if (mData->mAccessible)456 autoInitSpan.setSucceeded();457 else458 autoInitSpan.setLimited();459 }460 461 LogFlowThisFunc(("mName='%ls', mRegistered=%RTbool, mAccessible=%RTbool "462 "rc=%08X\n",463 !!mUserData ? mUserData->mName.raw() : NULL,464 mData->mRegistered, mData->mAccessible, rc));465 466 LogFlowThisFuncLeave();467 468 return rc;469 }470 471 /**472 * Shared code between the various init() implementation.s473 * @param aParent474 * @return475 */476 HRESULT Machine::initImpl(VirtualBox *aParent,477 const Utf8Str &strConfigFile)478 {479 LogFlowThisFuncEnter();480 481 AssertReturn(aParent, E_INVALIDARG);482 AssertReturn(!strConfigFile.isEmpty(), E_INVALIDARG);483 484 HRESULT rc = S_OK;485 486 /* share the parent weakly */487 unconst(mParent) = aParent;488 489 /* allocate the essential machine data structure (the rest will be490 * allocated later by initDataAndChildObjects() */491 mData.allocate();492 493 /* memorize the config file name (as provided) */494 mData->m_strConfigFile = strConfigFile;495 496 /* get the full file name */497 int vrc1 = mParent->calculateFullPath(strConfigFile, mData->m_strConfigFileFull);498 if (RT_FAILURE(vrc1))499 return setError(VBOX_E_FILE_ERROR,500 tr("Invalid machine settings file name '%s' (%Rrc)"),501 strConfigFile.raw(),502 vrc1);503 504 LogFlowThisFuncLeave();505 506 612 return rc; 507 613 } … … 535 641 mData->mRegistered = FALSE; 536 642 537 rc = loadSettings(true /* aRegistered */); 643 try 644 { 645 // load and parse machine XML; this will throw on XML or logic errors 646 mData->pMachineConfigFile = new settings::MachineConfigFile(&mData->m_strConfigFileFull); 647 648 if (mData->mUuid != mData->pMachineConfigFile->uuid) 649 throw setError(E_FAIL, 650 tr("Machine UUID {%RTuuid} in '%s' doesn't match its UUID {%s} in the registry file '%s'"), 651 mData->pMachineConfigFile->uuid.raw(), 652 mData->m_strConfigFileFull.raw(), 653 mData->mUuid.toString().raw(), 654 mParent->settingsFilePath().raw()); 655 656 rc = loadMachineDataFromSettings(*mData->pMachineConfigFile); 657 if (FAILED(rc)) throw rc; 658 } 659 catch (HRESULT err) 660 { 661 /* we assume that error info is set by the thrower */ 662 rc = err; 663 } 664 catch (...) 665 { 666 rc = VirtualBox::handleUnexpectedExceptions(RT_SRC_POS); 667 } 538 668 539 669 /* Restore the registered flag (even on failure) */ … … 6310 6440 6311 6441 /** 6312 * Loads all the VM settings by walking down the <Machine> node. 6313 * 6314 * @param aRegistered true when the machine is being loaded on VirtualBox 6315 * startup 6316 * 6317 * @note This method is intended to be called only from init(), so it assumes 6318 * all machine data fields have appropriate default values when it is called. 6319 * 6320 * @note Doesn't lock any objects. 6442 * Initializes all machine instance data from the given settings structures 6443 * from XML. The exception is the machine UUID which needs special handling 6444 * depending on the caller's use case, so the caller needs to set that herself. 6445 * 6446 * @param config 6447 * @param fAllowStorage 6321 6448 */ 6322 HRESULT Machine::loadSettings(bool aRegistered) 6323 { 6324 LogFlowThisFuncEnter(); 6325 AssertReturn(getClassID() == clsidMachine, E_FAIL); 6326 6327 AutoCaller autoCaller(this); 6328 AssertReturn(autoCaller.state() == InInit, E_FAIL); 6329 6330 HRESULT rc = S_OK; 6331 6332 try 6333 { 6334 Assert(mData->pMachineConfigFile == NULL); 6335 6336 // load and parse machine XML; this will throw on XML or logic errors 6337 mData->pMachineConfigFile = new settings::MachineConfigFile(&mData->m_strConfigFileFull); 6338 6339 /* If the stored UUID is not empty, it means the registered machine 6340 * is being loaded. Compare the loaded UUID with the stored one taken 6341 * from the global registry. */ 6342 if (!mData->mUuid.isEmpty()) 6343 { 6344 if (mData->mUuid != mData->pMachineConfigFile->uuid) 6345 { 6346 throw setError(E_FAIL, 6347 tr("Machine UUID {%RTuuid} in '%s' doesn't match its UUID {%s} in the registry file '%s'"), 6348 mData->pMachineConfigFile->uuid.raw(), 6349 mData->m_strConfigFileFull.raw(), 6350 mData->mUuid.toString().raw(), 6351 mParent->settingsFilePath().raw()); 6352 } 6353 } 6354 else 6355 unconst(mData->mUuid) = mData->pMachineConfigFile->uuid; 6356 6357 /* name (required) */ 6358 mUserData->mName = mData->pMachineConfigFile->strName; 6359 6360 /* nameSync (optional, default is true) */ 6361 mUserData->mNameSync = mData->pMachineConfigFile->fNameSync; 6362 6363 mUserData->mDescription = mData->pMachineConfigFile->strDescription; 6364 6365 // guest OS type 6366 mUserData->mOSTypeId = mData->pMachineConfigFile->strOsType; 6367 /* look up the object by Id to check it is valid */ 6368 ComPtr<IGuestOSType> guestOSType; 6369 rc = mParent->GetGuestOSType(mUserData->mOSTypeId, 6370 guestOSType.asOutParam()); 6371 if (FAILED(rc)) throw rc; 6372 6373 // stateFile (optional) 6374 if (mData->pMachineConfigFile->strStateFile.isEmpty()) 6375 mSSData->mStateFilePath.setNull(); 6376 else 6377 { 6378 Utf8Str stateFilePathFull(mData->pMachineConfigFile->strStateFile); 6379 int vrc = calculateFullPath(stateFilePathFull, stateFilePathFull); 6380 if (RT_FAILURE(vrc)) 6381 throw setError(E_FAIL, 6382 tr("Invalid saved state file path '%s' (%Rrc)"), 6383 mData->pMachineConfigFile->strStateFile.raw(), 6384 vrc); 6385 mSSData->mStateFilePath = stateFilePathFull; 6386 } 6387 6388 /* snapshotFolder (optional) */ 6389 rc = COMSETTER(SnapshotFolder)(Bstr(mData->pMachineConfigFile->strSnapshotFolder)); 6390 if (FAILED(rc)) throw rc; 6391 6392 /* currentStateModified (optional, default is true) */ 6393 mData->mCurrentStateModified = mData->pMachineConfigFile->fCurrentStateModified; 6394 6395 mData->mLastStateChange = mData->pMachineConfigFile->timeLastStateChange; 6396 6397 /* teleportation */ 6398 mUserData->mTeleporterEnabled = mData->pMachineConfigFile->fTeleporterEnabled; 6399 mUserData->mTeleporterPort = mData->pMachineConfigFile->uTeleporterPort; 6400 mUserData->mTeleporterAddress = mData->pMachineConfigFile->strTeleporterAddress; 6401 mUserData->mTeleporterPassword = mData->pMachineConfigFile->strTeleporterPassword; 6402 6403 /* RTC */ 6404 mUserData->mRTCUseUTC = mData->pMachineConfigFile->fRTCUseUTC; 6405 6406 /* 6407 * note: all mUserData members must be assigned prior this point because 6408 * we need to commit changes in order to let mUserData be shared by all 6409 * snapshot machine instances. 6410 */ 6411 mUserData.commitCopy(); 6412 6413 /* Snapshot node (optional) */ 6414 size_t cRootSnapshots; 6415 if ((cRootSnapshots = mData->pMachineConfigFile->llFirstSnapshot.size())) 6416 { 6417 // there must be only one root snapshot 6418 Assert(cRootSnapshots == 1); 6419 6420 settings::Snapshot &snap = mData->pMachineConfigFile->llFirstSnapshot.front(); 6421 6422 rc = loadSnapshot(snap, 6423 mData->pMachineConfigFile->uuidCurrentSnapshot, 6424 NULL); // no parent == first snapshot 6425 if (FAILED(rc)) throw rc; 6426 } 6427 6428 /* Hardware node (required) */ 6429 rc = loadHardware(mData->pMachineConfigFile->hardwareMachine); 6430 if (FAILED(rc)) throw rc; 6431 6432 /* Load storage controllers */ 6433 rc = loadStorageControllers(mData->pMachineConfigFile->storageMachine, aRegistered); 6434 if (FAILED(rc)) throw rc; 6435 6436 /* 6437 * NOTE: the assignment below must be the last thing to do, 6438 * otherwise it will be not possible to change the settings 6439 * somewehere in the code above because all setters will be 6440 * blocked by checkStateDependency(MutableStateDep). 6441 */ 6442 6443 /* set the machine state to Aborted or Saved when appropriate */ 6444 if (mData->pMachineConfigFile->fAborted) 6445 { 6446 Assert(!mSSData->mStateFilePath.isEmpty()); 6447 mSSData->mStateFilePath.setNull(); 6448 6449 /* no need to use setMachineState() during init() */ 6450 mData->mMachineState = MachineState_Aborted; 6451 } 6452 else if (!mSSData->mStateFilePath.isEmpty()) 6453 { 6454 /* no need to use setMachineState() during init() */ 6455 mData->mMachineState = MachineState_Saved; 6456 } 6457 6458 // after loading settings, we are no longer different from the XML on disk 6459 mData->flModifications = 0; 6460 } 6461 catch (HRESULT err) 6462 { 6463 /* we assume that error info is set by the thrower */ 6464 rc = err; 6465 } 6466 catch (...) 6467 { 6468 rc = VirtualBox::handleUnexpectedExceptions(RT_SRC_POS); 6469 } 6470 6471 LogFlowThisFuncLeave(); 6472 return rc; 6449 HRESULT Machine::loadMachineDataFromSettings(const settings::MachineConfigFile &config) 6450 { 6451 /* name (required) */ 6452 mUserData->mName = config.strName; 6453 6454 /* nameSync (optional, default is true) */ 6455 mUserData->mNameSync = config.fNameSync; 6456 6457 mUserData->mDescription = config.strDescription; 6458 6459 // guest OS type 6460 mUserData->mOSTypeId = config.strOsType; 6461 /* look up the object by Id to check it is valid */ 6462 ComPtr<IGuestOSType> guestOSType; 6463 HRESULT rc = mParent->GetGuestOSType(mUserData->mOSTypeId, 6464 guestOSType.asOutParam()); 6465 if (FAILED(rc)) return rc; 6466 6467 // stateFile (optional) 6468 if (config.strStateFile.isEmpty()) 6469 mSSData->mStateFilePath.setNull(); 6470 else 6471 { 6472 Utf8Str stateFilePathFull(config.strStateFile); 6473 int vrc = calculateFullPath(stateFilePathFull, stateFilePathFull); 6474 if (RT_FAILURE(vrc)) 6475 return setError(E_FAIL, 6476 tr("Invalid saved state file path '%s' (%Rrc)"), 6477 config.strStateFile.raw(), 6478 vrc); 6479 mSSData->mStateFilePath = stateFilePathFull; 6480 } 6481 6482 /* snapshotFolder (optional) */ 6483 rc = COMSETTER(SnapshotFolder)(Bstr(config.strSnapshotFolder)); 6484 if (FAILED(rc)) return rc; 6485 6486 /* currentStateModified (optional, default is true) */ 6487 mData->mCurrentStateModified = config.fCurrentStateModified; 6488 6489 mData->mLastStateChange = config.timeLastStateChange; 6490 6491 /* teleportation */ 6492 mUserData->mTeleporterEnabled = config.fTeleporterEnabled; 6493 mUserData->mTeleporterPort = config.uTeleporterPort; 6494 mUserData->mTeleporterAddress = config.strTeleporterAddress; 6495 mUserData->mTeleporterPassword = config.strTeleporterPassword; 6496 6497 /* RTC */ 6498 mUserData->mRTCUseUTC = config.fRTCUseUTC; 6499 6500 /* 6501 * note: all mUserData members must be assigned prior this point because 6502 * we need to commit changes in order to let mUserData be shared by all 6503 * snapshot machine instances. 6504 */ 6505 mUserData.commitCopy(); 6506 6507 /* Snapshot node (optional) */ 6508 size_t cRootSnapshots; 6509 if ((cRootSnapshots = config.llFirstSnapshot.size())) 6510 { 6511 // there must be only one root snapshot 6512 Assert(cRootSnapshots == 1); 6513 6514 const settings::Snapshot &snap = config.llFirstSnapshot.front(); 6515 6516 rc = loadSnapshot(snap, 6517 config.uuidCurrentSnapshot, 6518 NULL); // no parent == first snapshot 6519 if (FAILED(rc)) return rc; 6520 } 6521 6522 /* Hardware node (required) */ 6523 rc = loadHardware(config.hardwareMachine); 6524 if (FAILED(rc)) return rc; 6525 6526 /* Load storage controllers */ 6527 rc = loadStorageControllers(config.storageMachine); 6528 if (FAILED(rc)) return rc; 6529 6530 /* 6531 * NOTE: the assignment below must be the last thing to do, 6532 * otherwise it will be not possible to change the settings 6533 * somewehere in the code above because all setters will be 6534 * blocked by checkStateDependency(MutableStateDep). 6535 */ 6536 6537 /* set the machine state to Aborted or Saved when appropriate */ 6538 if (config.fAborted) 6539 { 6540 Assert(!mSSData->mStateFilePath.isEmpty()); 6541 mSSData->mStateFilePath.setNull(); 6542 6543 /* no need to use setMachineState() during init() */ 6544 mData->mMachineState = MachineState_Aborted; 6545 } 6546 else if (!mSSData->mStateFilePath.isEmpty()) 6547 { 6548 /* no need to use setMachineState() during init() */ 6549 mData->mMachineState = MachineState_Saved; 6550 } 6551 6552 // after loading settings, we are no longer different from the XML on disk 6553 mData->flModifications = 0; 6554 6555 return S_OK; 6473 6556 } 6474 6557 … … 6761 6844 */ 6762 6845 HRESULT Machine::loadStorageControllers(const settings::Storage &data, 6763 bool aRegistered,6764 6846 const Guid *aSnapshotId /* = NULL */) 6765 6847 { … … 6811 6893 rc = loadStorageDevices(pCtl, 6812 6894 ctlData, 6813 aRegistered,6814 6895 aSnapshotId); 6815 6896 if (FAILED(rc)) return rc; … … 6821 6902 /** 6822 6903 * @param aNode <HardDiskAttachments> node. 6823 * @param aRegistered true when the machine is being loaded on VirtualBox 6824 * startup, or when a snapshot is being loaded (which 6825 * currently can happen on startup only) 6904 * @param fAllowStorage if false, we produce an error if the config requests media attachments 6905 * (used with importing unregistered machines which cannot have media attachments) 6826 6906 * @param aSnapshotId pointer to the snapshot ID if this is a snapshot machine 6827 6907 * … … 6830 6910 HRESULT Machine::loadStorageDevices(StorageController *aStorageController, 6831 6911 const settings::StorageController &data, 6832 bool aRegistered,6833 6912 const Guid *aSnapshotId /*= NULL*/) 6834 6913 { … … 6838 6917 6839 6918 HRESULT rc = S_OK; 6840 6841 if (!aRegistered && data.llAttachedDevices.size() > 0)6842 /* when the machine is being loaded (opened) from a file, it cannot6843 * have hard disks attached (this should not happen normally,6844 * because we don't allow to attach hard disks to an unregistered6845 * VM at all */6846 return setError(E_FAIL,6847 tr("Unregistered machine '%ls' cannot have storage devices attached (found %d attachments)"),6848 mUserData->mName.raw(),6849 data.llAttachedDevices.size());6850 6919 6851 6920 /* paranoia: detect duplicate attachments */ -
trunk/src/VBox/Main/SnapshotImpl.cpp
r28091 r28110 1019 1019 HRESULT rc = loadHardware(hardware); 1020 1020 if (SUCCEEDED(rc)) 1021 rc = loadStorageControllers(storage, true /* aRegistered */,&mSnapshotId);1021 rc = loadStorageControllers(storage, &mSnapshotId); 1022 1022 1023 1023 if (SUCCEEDED(rc)) -
trunk/src/VBox/Main/include/ApplianceImpl.h
r28098 r28110 148 148 HRESULT importFS(const LocationInfo &locInfo, ComObjPtr<Progress> &aProgress); 149 149 struct ImportStack; 150 void importVBoxMachine( const settings::MachineConfigFile &config,150 void importVBoxMachine(ComObjPtr<VirtualSystemDescription> &vsdescThis, 151 151 ComPtr<IMachine> &pNewMachine, 152 152 ImportStack &stack); -
trunk/src/VBox/Main/include/MachineImpl.h
r28091 r28110 364 364 const Guid *aId); 365 365 366 // initializer for machine config in memory (OVF import) 367 HRESULT init(VirtualBox *aParent, 368 const Utf8Str &strName, 369 const settings::MachineConfigFile &config); 370 366 371 void uninit(); 367 372 … … 370 375 const Utf8Str &strConfigFile); 371 376 HRESULT initDataAndChildObjects(); 377 HRESULT registeredInit(); 378 HRESULT tryCreateMachineConfigFile(BOOL aOverride); 372 379 void uninitDataAndChildObjects(); 373 380 … … 703 710 protected: 704 711 705 HRESULT registeredInit();706 707 712 HRESULT checkStateDependency(StateDependency aDepType); 708 713 … … 718 723 719 724 HRESULT loadSettings(bool aRegistered); 725 HRESULT loadMachineDataFromSettings(const settings::MachineConfigFile &config); 720 726 HRESULT loadSnapshot(const settings::Snapshot &data, 721 727 const Guid &aCurSnapshotId, … … 723 729 HRESULT loadHardware(const settings::Hardware &data); 724 730 HRESULT loadStorageControllers(const settings::Storage &data, 725 bool aRegistered,726 731 const Guid *aSnapshotId = NULL); 727 732 HRESULT loadStorageDevices(StorageController *aStorageController, 728 733 const settings::StorageController &data, 729 bool aRegistered,730 734 const Guid *aSnapshotId = NULL); 731 735
Note:
See TracChangeset
for help on using the changeset viewer.