Changeset 6076 in vbox for trunk/src/VBox/Main
- Timestamp:
- Dec 14, 2007 7:23:03 PM (17 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 2 added
- 1 deleted
- 46 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/AudioAdapterImpl.cpp
r6056 r6076 272 272 273 273 /** 274 * Loads settings from the given machine node. 275 * May be called once right after this object creation. 276 * 277 * @param aMachineNode <Machine> node. 278 * 279 * @note Locks this object for writing. 280 */ 281 HRESULT AudioAdapter::loadSettings (const settings::Key &aMachineNode) 282 { 283 using namespace settings; 284 285 AssertReturn (!aMachineNode.isNull(), E_FAIL); 286 287 AutoCaller autoCaller (this); 288 AssertComRCReturnRC (autoCaller.rc()); 289 290 AutoLock alock (this); 291 292 /* Note: we assume that the default values for attributes of optional 293 * nodes are assigned in the Data::Data() constructor and don't do it 294 * here. It implies that this method may only be called after constructing 295 * a new BIOSSettings object while all its data fields are in the default 296 * values. Exceptions are fields whose creation time defaults don't match 297 * values that should be applied when these fields are not explicitly set 298 * in the settings file (for backwards compatibility reasons). This takes 299 * place when a setting of a newly created object must default to A while 300 * the same setting of an object loaded from the old settings file must 301 * default to B. */ 302 303 /* AudioAdapter node (required) */ 304 Key audioAdapterNode = aMachineNode.key ("AudioAdapter"); 305 306 /* is the adapter enabled? (required) */ 307 mData->mEnabled = audioAdapterNode.value <bool> ("enabled"); 308 309 /* now check the audio driver (required) */ 310 const char *driver = audioAdapterNode.stringValue ("driver"); 311 mData->mAudioDriver = AudioDriverType_NullAudioDriver; 312 if (strcmp (driver, "null") == 0) 313 ; /* Null has been set above */ 314 #ifdef RT_OS_WINDOWS 315 else if (strcmp (driver, "winmm") == 0) 316 #ifdef VBOX_WITH_WINMM 317 mData->mAudioDriver = AudioDriverType_WINMMAudioDriver; 318 #else 319 /* fall back to dsound */ 320 mData->mAudioDriver = AudioDriverType_DSOUNDAudioDriver; 321 #endif 322 else if (strcmp (driver, "dsound") == 0) 323 mData->mAudioDriver = AudioDriverType_DSOUNDAudioDriver; 324 #endif // RT_OS_WINDOWS 325 #ifdef RT_OS_LINUX 326 else if (strcmp (driver, "oss") == 0) 327 mData->mAudioDriver = AudioDriverType_OSSAudioDriver; 328 else if (strcmp (driver, "alsa") == 0) 329 # ifdef VBOX_WITH_ALSA 330 mData->mAudioDriver = AudioDriverType_ALSAAudioDriver; 331 # else 332 /* fall back to OSS */ 333 mData->mAudioDriver = AudioDriverType_OSSAudioDriver; 334 # endif 335 else if (strcmp (driver, "pulse") == 0) 336 # ifdef VBOX_WITH_PULSE 337 mData->mAudioDriver = AudioDriverType_PulseAudioDriver; 338 # else 339 /* fall back to OSS */ 340 mData->mAudioDriver = AudioDriverType_OSSAudioDriver; 341 # endif 342 #endif // RT_OS_LINUX 343 #ifdef RT_OS_DARWIN 344 else if (strcmp (driver, "coreaudio") == 0) 345 mData->mAudioDriver = AudioDriverType_CoreAudioDriver; 346 #endif 347 #ifdef RT_OS_OS2 348 else if (strcmp (driver, "mmpm") == 0) 349 mData->mAudioDriver = AudioDriverType_MMPMAudioDriver; 350 #endif 351 else 352 AssertMsgFailed (("Invalid driver '%s'\n", driver)); 353 354 return S_OK; 355 } 356 357 /** 358 * Saves settings to the given machine node. 359 * 360 * @param aMachineNode <Machine> node. 361 * 362 * @note Locks this object for reading. 363 */ 364 HRESULT AudioAdapter::saveSettings (settings::Key &aMachineNode) 365 { 366 using namespace settings; 367 368 AssertReturn (!aMachineNode.isNull(), E_FAIL); 369 370 AutoCaller autoCaller (this); 371 AssertComRCReturnRC (autoCaller.rc()); 372 373 AutoReaderLock alock (this); 374 375 Key node = aMachineNode.createKey ("AudioAdapter"); 376 377 const char *driverStr = NULL; 378 switch (mData->mAudioDriver) 379 { 380 case AudioDriverType_NullAudioDriver: 381 { 382 driverStr = "null"; 383 break; 384 } 385 #ifdef RT_OS_WINDOWS 386 case AudioDriverType_WINMMAudioDriver: 387 # ifdef VBOX_WITH_WINMM 388 { 389 driverStr = "winmm"; 390 break; 391 } 392 # endif 393 case AudioDriverType_DSOUNDAudioDriver: 394 { 395 driverStr = "dsound"; 396 break; 397 } 398 #endif /* RT_OS_WINDOWS */ 399 #ifdef RT_OS_LINUX 400 case AudioDriverType_ALSAAudioDriver: 401 # ifdef VBOX_WITH_ALSA 402 { 403 driverStr = "alsa"; 404 break; 405 } 406 # endif 407 case AudioDriverType_PulseAudioDriver: 408 # ifdef VBOX_WITH_PULSE 409 { 410 driverStr = "pulse"; 411 break; 412 } 413 # endif 414 case AudioDriverType_OSSAudioDriver: 415 { 416 driverStr = "oss"; 417 break; 418 } 419 #endif /* RT_OS_LINUX */ 420 #ifdef RT_OS_DARWIN 421 case AudioDriverType_CoreAudioDriver: 422 { 423 driverStr = "coreaudio"; 424 break; 425 } 426 #endif 427 #ifdef RT_OS_OS2 428 case AudioDriverType_MMPMAudioDriver: 429 { 430 driverStr = "mmpm"; 431 break; 432 } 433 #endif 434 default: 435 ComAssertMsgFailedRet (("Wrong audio driver type! driver = %d\n", 436 mData->mAudioDriver), 437 E_FAIL); 438 } 439 node.setStringValue ("driver", driverStr); 440 441 node.setValue <bool> ("enabled", !!mData->mEnabled); 442 443 return S_OK; 444 } 445 446 /** 274 447 * @note Locks this object for writing. 275 448 */ -
trunk/src/VBox/Main/BIOSSettingsImpl.cpp
r5999 r6076 489 489 ///////////////////////////////////////////////////////////////////////////// 490 490 491 /** 492 * Loads settings from the given machine node. 493 * May be called once right after this object creation. 494 * 495 * @param aMachineNode <Machine> node. 496 * 497 * @note Locks this object for writing. 498 */ 499 HRESULT BIOSSettings::loadSettings (const settings::Key &aMachineNode) 500 { 501 using namespace settings; 502 503 AssertReturn (!aMachineNode.isNull(), E_FAIL); 504 505 AutoCaller autoCaller (this); 506 AssertComRCReturnRC (autoCaller.rc()); 507 508 AutoLock alock (this); 509 510 /* Note: we assume that the default values for attributes of optional 511 * nodes are assigned in the Data::Data() constructor and don't do it 512 * here. It implies that this method may only be called after constructing 513 * a new BIOSSettings object while all its data fields are in the default 514 * values. Exceptions are fields whose creation time defaults don't match 515 * values that should be applied when these fields are not explicitly set 516 * in the settings file (for backwards compatibility reasons). This takes 517 * place when a setting of a newly created object must default to A while 518 * the same setting of an object loaded from the old settings file must 519 * default to B. */ 520 521 /* BIOS node (required) */ 522 Key biosNode = aMachineNode.key ("BIOS"); 523 524 /* ACPI (required) */ 525 { 526 Key acpiNode = biosNode.key ("ACPI"); 527 528 mData->mACPIEnabled = acpiNode.value <bool> ("enabled"); 529 } 530 531 /* IOAPIC (optional) */ 532 { 533 Key ioapicNode = biosNode.findKey ("IOAPIC"); 534 if (!ioapicNode.isNull()) 535 mData->mIOAPICEnabled = ioapicNode.value <bool> ("enabled"); 536 } 537 538 /* Logo (optional) */ 539 { 540 Key logoNode = biosNode.findKey ("Logo"); 541 if (!logoNode.isNull()) 542 { 543 mData->mLogoFadeIn = logoNode.value <bool> ("fadeIn"); 544 mData->mLogoFadeOut = logoNode.value <bool> ("fadeOut"); 545 mData->mLogoDisplayTime = logoNode.value <ULONG> ("displayTime"); 546 mData->mLogoImagePath = logoNode.stringValue ("imagePath"); 547 } 548 } 549 550 /* boot menu (optional) */ 551 { 552 Key bootMenuNode = biosNode.findKey ("BootMenu"); 553 if (!bootMenuNode.isNull()) 554 { 555 mData->mBootMenuMode = BIOSBootMenuMode_MessageAndMenu; 556 const char *modeStr = bootMenuNode.stringValue ("mode"); 557 558 if (strcmp (modeStr, "disabled") == 0) 559 mData->mBootMenuMode = BIOSBootMenuMode_Disabled; 560 else if (strcmp (modeStr, "menuonly") == 0) 561 mData->mBootMenuMode = BIOSBootMenuMode_MenuOnly; 562 else if (strcmp (modeStr, "messageandmenu") == 0) 563 mData->mBootMenuMode = BIOSBootMenuMode_MessageAndMenu; 564 else 565 ComAssertMsgFailedRet (("Invalid boot menu mode '%s'\n", modeStr), 566 E_FAIL); 567 } 568 } 569 570 /* PXE debug logging (optional) */ 571 { 572 Key pxedebugNode = biosNode.findKey ("PXEDebug"); 573 if (!pxedebugNode.isNull()) 574 mData->mPXEDebugEnabled = pxedebugNode.value <bool> ("enabled"); 575 } 576 577 /* time offset (optional) */ 578 { 579 Key timeOffsetNode = biosNode.findKey ("TimeOffset"); 580 if (!timeOffsetNode.isNull()) 581 mData->mTimeOffset = timeOffsetNode.value <LONG64> ("value"); 582 } 583 584 /* IDE controller type (optional, for old machines that lack this node, 585 * defaults to PIIX3) */ 586 { 587 mData->mIDEControllerType = IDEControllerType_IDEControllerPIIX3; 588 589 Key ideControllerNode = biosNode.findKey ("IDEController"); 590 if (!ideControllerNode.isNull()) 591 { 592 const char *typeStr = ideControllerNode.stringValue ("type"); 593 if (strcmp (typeStr, "PIIX3") == 0) 594 mData->mIDEControllerType = IDEControllerType_IDEControllerPIIX3; 595 else if (strcmp (typeStr, "PIIX4") == 0) 596 mData->mIDEControllerType = IDEControllerType_IDEControllerPIIX4; 597 else 598 ComAssertMsgFailedRet (("Invalid boot menu mode '%s'\n", typeStr), 599 E_FAIL); 600 } 601 } 602 603 return S_OK; 604 } 605 606 /** 607 * Saves settings to the given machine node. 608 * 609 * @param aMachineNode <Machine> node. 610 * 611 * @note Locks this object for reading. 612 */ 613 HRESULT BIOSSettings::saveSettings (settings::Key &aMachineNode) 614 { 615 using namespace settings; 616 617 AssertReturn (!aMachineNode.isNull(), E_FAIL); 618 619 AutoCaller autoCaller (this); 620 AssertComRCReturnRC (autoCaller.rc()); 621 622 AutoReaderLock alock (this); 623 624 Key biosNode = aMachineNode.createKey ("BIOS"); 625 626 /* ACPI */ 627 { 628 Key acpiNode = biosNode.createKey ("ACPI"); 629 acpiNode.setValue <bool> ("enabled", !!mData->mACPIEnabled); 630 } 631 632 /* IOAPIC */ 633 { 634 Key ioapicNode = biosNode.createKey ("IOAPIC"); 635 ioapicNode.setValue <bool> ("enabled", !!mData->mIOAPICEnabled); 636 } 637 638 /* BIOS logo (optional) **/ 639 { 640 Key logoNode = biosNode.createKey ("Logo"); 641 logoNode.setValue <bool> ("fadeIn", !!mData->mLogoFadeIn); 642 logoNode.setValue <bool> ("fadeOut", !!mData->mLogoFadeOut); 643 logoNode.setValue <ULONG> ("displayTime", mData->mLogoDisplayTime); 644 logoNode.setValueOr <Bstr> ("imagePath", mData->mLogoImagePath, Bstr::Null); 645 } 646 647 /* boot menu (optional) */ 648 { 649 Key bootMenuNode = biosNode.createKey ("BootMenu"); 650 const char *modeStr = NULL; 651 switch (mData->mBootMenuMode) 652 { 653 case BIOSBootMenuMode_Disabled: 654 modeStr = "disabled"; 655 break; 656 case BIOSBootMenuMode_MenuOnly: 657 modeStr = "menuonly"; 658 break; 659 case BIOSBootMenuMode_MessageAndMenu: 660 modeStr = "messageandmenu"; 661 break; 662 default: 663 ComAssertMsgFailedRet (("Invalid boot menu type: %d\n", 664 mData->mBootMenuMode), 665 E_FAIL); 666 } 667 bootMenuNode.setStringValue ("mode", modeStr); 668 } 669 670 /* time offset (optional) */ 671 { 672 Key timeOffsetNode = biosNode.createKey ("TimeOffset"); 673 timeOffsetNode.setValue <LONG64> ("value", mData->mTimeOffset); 674 } 675 676 /* PXE debug flag (optional) */ 677 { 678 Key pxedebugNode = biosNode.createKey ("PXEDebug"); 679 pxedebugNode.setValue <bool> ("enabled", !!mData->mPXEDebugEnabled); 680 } 681 682 /* IDE controller type */ 683 { 684 Key ideControllerNode = biosNode.createKey ("IDEController"); 685 const char *ideControllerTypeStr = NULL; 686 switch (mData->mIDEControllerType) 687 { 688 case IDEControllerType_IDEControllerPIIX3: 689 ideControllerTypeStr = "PIIX3"; 690 break; 691 case IDEControllerType_IDEControllerPIIX4: 692 ideControllerTypeStr = "PIIX4"; 693 break; 694 default: 695 ComAssertMsgFailedRet (("Invalid IDE Controller type: %d\n", 696 mData->mIDEControllerType), 697 E_FAIL); 698 } 699 ideControllerNode.setStringValue ("type", ideControllerTypeStr); 700 } 701 702 return S_OK; 703 } 704 491 705 void BIOSSettings::commit() 492 706 { -
trunk/src/VBox/Main/DVDDriveImpl.cpp
r5999 r6076 18 18 #include "DVDDriveImpl.h" 19 19 #include "MachineImpl.h" 20 #include "HostImpl.h" 21 #include "HostDVDDriveImpl.h" 20 22 #include "VirtualBoxImpl.h" 23 21 24 #include "Logging.h" 22 25 … … 347 350 // public methods only for internal purposes 348 351 //////////////////////////////////////////////////////////////////////////////// 352 353 /** 354 * Loads settings from the given machine node. 355 * May be called once right after this object creation. 356 * 357 * @param aMachineNode <Machine> node. 358 * 359 * @note Locks this object for writing. 360 */ 361 HRESULT DVDDrive::loadSettings (const settings::Key &aMachineNode) 362 { 363 using namespace settings; 364 365 AssertReturn (!aMachineNode.isNull(), E_FAIL); 366 367 AutoCaller autoCaller (this); 368 AssertComRCReturnRC (autoCaller.rc()); 369 370 AutoLock alock (this); 371 372 /* Note: we assume that the default values for attributes of optional 373 * nodes are assigned in the Data::Data() constructor and don't do it 374 * here. It implies that this method may only be called after constructing 375 * a new BIOSSettings object while all its data fields are in the default 376 * values. Exceptions are fields whose creation time defaults don't match 377 * values that should be applied when these fields are not explicitly set 378 * in the settings file (for backwards compatibility reasons). This takes 379 * place when a setting of a newly created object must default to A while 380 * the same setting of an object loaded from the old settings file must 381 * default to B. */ 382 383 HRESULT rc = S_OK; 384 385 /* DVD drive (required, contains either Image or HostDrive or nothing) */ 386 Key dvdDriveNode = aMachineNode.key ("DVDDrive"); 387 388 /* optional, defaults to false */ 389 mData->mPassthrough = dvdDriveNode.value <bool> ("passthrough"); 390 391 Key typeNode; 392 393 if (!(typeNode = dvdDriveNode.findKey ("Image")).isNull()) 394 { 395 Guid uuid = typeNode.value <Guid> ("uuid"); 396 rc = MountImage (uuid); 397 CheckComRCReturnRC (rc); 398 } 399 else if (!(typeNode = dvdDriveNode.findKey ("HostDrive")).isNull()) 400 { 401 402 Bstr src = typeNode.stringValue ("src"); 403 404 /* find the correspoding object */ 405 ComObjPtr <Host> host = mParent->virtualBox()->host(); 406 407 ComPtr <IHostDVDDriveCollection> coll; 408 rc = host->COMGETTER(DVDDrives) (coll.asOutParam()); 409 AssertComRC (rc); 410 411 ComPtr <IHostDVDDrive> drive; 412 rc = coll->FindByName (src, drive.asOutParam()); 413 if (SUCCEEDED (rc)) 414 { 415 rc = CaptureHostDrive (drive); 416 CheckComRCReturnRC (rc); 417 } 418 else if (rc == E_INVALIDARG) 419 { 420 /* the host DVD drive is not currently available. we 421 * assume it will be available later and create an 422 * extra object now */ 423 ComObjPtr <HostDVDDrive> hostDrive; 424 hostDrive.createObject(); 425 rc = hostDrive->init (src); 426 AssertComRC (rc); 427 rc = CaptureHostDrive (hostDrive); 428 CheckComRCReturnRC (rc); 429 } 430 else 431 AssertComRC (rc); 432 } 433 434 return S_OK; 435 } 436 437 /** 438 * Saves settings to the given machine node. 439 * 440 * @param aMachineNode <Machine> node. 441 * 442 * @note Locks this object for reading. 443 */ 444 HRESULT DVDDrive::saveSettings (settings::Key &aMachineNode) 445 { 446 using namespace settings; 447 448 AssertReturn (!aMachineNode.isNull(), E_FAIL); 449 450 AutoCaller autoCaller (this); 451 AssertComRCReturnRC (autoCaller.rc()); 452 453 AutoReaderLock alock (this); 454 455 Key node = aMachineNode.createKey ("DVDDrive"); 456 457 node.setValue <bool> ("passthrough", !!mData->mPassthrough); 458 459 switch (mData->mDriveState) 460 { 461 case DriveState_ImageMounted: 462 { 463 Assert (!mData->mDVDImage.isNull()); 464 465 Guid id; 466 HRESULT rc = mData->mDVDImage->COMGETTER(Id) (id.asOutParam()); 467 AssertComRC (rc); 468 Assert (!id.isEmpty()); 469 470 Key imageNode = node.createKey ("Image"); 471 imageNode.setValue <Guid> ("uuid", id); 472 break; 473 } 474 case DriveState_HostDriveCaptured: 475 { 476 Assert (!mData->mHostDrive.isNull()); 477 478 Bstr name; 479 HRESULT rc = mData->mHostDrive->COMGETTER(Name) (name.asOutParam()); 480 AssertComRC (rc); 481 Assert (!name.isEmpty()); 482 483 Key hostDriveNode = node.createKey ("HostDrive"); 484 hostDriveNode.setValue <Bstr> ("src", name); 485 break; 486 } 487 case DriveState_NotMounted: 488 /* do nothing, i.e.leave the drive node empty */ 489 break; 490 default: 491 ComAssertMsgFailedRet (("Invalid drive state: %d\n", 492 mData->mDriveState), 493 E_FAIL); 494 } 495 496 return S_OK; 497 } 349 498 350 499 /** -
trunk/src/VBox/Main/Doxyfile.Main
r1 r6076 982 982 CFGMGCDECL \ 983 983 CFGMDECL \ 984 CFGLDRR3DECL \985 984 EMR3DECL \ 986 985 EMR0DECL \ -
trunk/src/VBox/Main/FloppyDriveImpl.cpp
r5999 r6076 18 18 #include "FloppyDriveImpl.h" 19 19 #include "MachineImpl.h" 20 #include "HostImpl.h" 21 #include "HostFloppyDriveImpl.h" 20 22 #include "VirtualBoxImpl.h" 23 21 24 #include "Logging.h" 22 25 … … 354 357 // public methods only for internal purposes 355 358 ///////////////////////////////////////////////////////////////////////////// 359 360 /** 361 * Loads settings from the given machine node. 362 * May be called once right after this object creation. 363 * 364 * @param aMachineNode <Machine> node. 365 * 366 * @note Locks this object for writing. 367 */ 368 HRESULT FloppyDrive::loadSettings (const settings::Key &aMachineNode) 369 { 370 using namespace settings; 371 372 AssertReturn (!aMachineNode.isNull(), E_FAIL); 373 374 AutoCaller autoCaller (this); 375 AssertComRCReturnRC (autoCaller.rc()); 376 377 AutoLock alock (this); 378 379 /* Note: we assume that the default values for attributes of optional 380 * nodes are assigned in the Data::Data() constructor and don't do it 381 * here. It implies that this method may only be called after constructing 382 * a new BIOSSettings object while all its data fields are in the default 383 * values. Exceptions are fields whose creation time defaults don't match 384 * values that should be applied when these fields are not explicitly set 385 * in the settings file (for backwards compatibility reasons). This takes 386 * place when a setting of a newly created object must default to A while 387 * the same setting of an object loaded from the old settings file must 388 * default to B. */ 389 390 HRESULT rc = S_OK; 391 392 /* Floppy drive (required, contains either Image or HostDrive or nothing) */ 393 Key floppyDriveNode = aMachineNode.key ("FloppyDrive"); 394 395 /* optional, defaults to true */ 396 mData->mEnabled = floppyDriveNode.value <bool> ("enabled"); 397 398 Key typeNode; 399 400 if (!(typeNode = floppyDriveNode.findKey ("Image")).isNull()) 401 { 402 Guid uuid = typeNode.value <Guid> ("uuid"); 403 rc = MountImage (uuid); 404 CheckComRCReturnRC (rc); 405 } 406 else if (!(typeNode = floppyDriveNode.findKey ("HostDrive")).isNull()) 407 { 408 409 Bstr src = typeNode.stringValue ("src"); 410 411 /* find the correspoding object */ 412 ComObjPtr <Host> host = mParent->virtualBox()->host(); 413 414 ComPtr <IHostFloppyDriveCollection> coll; 415 rc = host->COMGETTER(FloppyDrives) (coll.asOutParam()); 416 AssertComRC (rc); 417 418 ComPtr <IHostFloppyDrive> drive; 419 rc = coll->FindByName (src, drive.asOutParam()); 420 if (SUCCEEDED (rc)) 421 { 422 rc = CaptureHostDrive (drive); 423 CheckComRCReturnRC (rc); 424 } 425 else if (rc == E_INVALIDARG) 426 { 427 /* the host DVD drive is not currently available. we 428 * assume it will be available later and create an 429 * extra object now */ 430 ComObjPtr <HostFloppyDrive> hostDrive; 431 hostDrive.createObject(); 432 rc = hostDrive->init (src); 433 AssertComRC (rc); 434 rc = CaptureHostDrive (hostDrive); 435 CheckComRCReturnRC (rc); 436 } 437 else 438 AssertComRC (rc); 439 } 440 441 return S_OK; 442 } 443 444 /** 445 * Saves settings to the given machine node. 446 * 447 * @param aMachineNode <Machine> node. 448 * 449 * @note Locks this object for reading. 450 */ 451 HRESULT FloppyDrive::saveSettings (settings::Key &aMachineNode) 452 { 453 using namespace settings; 454 455 AssertReturn (!aMachineNode.isNull(), E_FAIL); 456 457 AutoCaller autoCaller (this); 458 AssertComRCReturnRC (autoCaller.rc()); 459 460 AutoReaderLock alock (this); 461 462 Key node = aMachineNode.createKey ("FloppyDrive"); 463 464 node.setValue <bool> ("enabled", !!mData->mEnabled); 465 466 switch (mData->mDriveState) 467 { 468 case DriveState_ImageMounted: 469 { 470 Assert (!mData->mFloppyImage.isNull()); 471 472 Guid id; 473 HRESULT rc = mData->mFloppyImage->COMGETTER(Id) (id.asOutParam()); 474 AssertComRC (rc); 475 Assert (!id.isEmpty()); 476 477 Key imageNode = node.createKey ("Image"); 478 imageNode.setValue <Guid> ("uuid", id); 479 break; 480 } 481 case DriveState_HostDriveCaptured: 482 { 483 Assert (!mData->mHostDrive.isNull()); 484 485 Bstr name; 486 HRESULT rc = mData->mHostDrive->COMGETTER(Name) (name.asOutParam()); 487 AssertComRC (rc); 488 Assert (!name.isEmpty()); 489 490 Key hostDriveNode = node.createKey ("HostDrive"); 491 hostDriveNode.setValue <Bstr> ("src", name); 492 break; 493 } 494 case DriveState_NotMounted: 495 /* do nothing, i.e.leave the drive node empty */ 496 break; 497 default: 498 ComAssertMsgFailedRet (("Invalid drive state: %d\n", 499 mData->mDriveState), 500 E_FAIL); 501 } 502 503 return S_OK; 504 } 356 505 357 506 /** -
trunk/src/VBox/Main/HardDiskImpl.cpp
r5999 r6076 1187 1187 * 1188 1188 * @param aHDNode <HardDisk> node when #isDifferencing() = false, or 1189 * <DiffHardDisk> node otherwise 1189 * <DiffHardDisk> node otherwise. 1190 1190 * 1191 1191 * @note 1192 1192 * Must be called from under the object's lock 1193 1193 */ 1194 HRESULT HardDisk::loadSettings (CFGNODE aHDNode) 1195 { 1196 AssertReturn (aHDNode, E_FAIL); 1197 1198 Guid uuid; /* uuid (required) */ 1199 CFGLDRQueryUUID (aHDNode, "uuid", uuid.ptr()); 1200 mId = uuid; 1194 HRESULT HardDisk::loadSettings (const settings::Key &aHDNode) 1195 { 1196 using namespace settings; 1197 1198 AssertReturn (!aHDNode.isNull(), E_FAIL); 1199 1200 /* required */ 1201 mId = aHDNode.value <Guid> ("uuid"); 1201 1202 1202 1203 if (!isDifferencing()) 1203 1204 { 1204 Bstr type; /* type (required for <HardDisk> nodes only)*/1205 CFGLDRQueryBSTR (aHDNode, "type", type.asOutParam());1206 if ( type == L"normal")1205 /* type required for <HardDisk> nodes only */ 1206 const char *type = aHDNode.stringValue ("type"); 1207 if (strcmp (type, "normal") == 0) 1207 1208 mType = HardDiskType_NormalHardDisk; 1208 else if ( type == L"immutable")1209 else if (strcmp (type, "immutable") == 0) 1209 1210 mType = HardDiskType_ImmutableHardDisk; 1210 else if ( type == L"writethrough")1211 else if (strcmp (type, "writethrough") == 0) 1211 1212 mType = HardDiskType_WritethroughHardDisk; 1212 1213 else 1213 ComAssertMsgFailedRet (("Invalid hard disk type '% ls'\n", type.raw()),1214 ComAssertMsgFailedRet (("Invalid hard disk type '%s'\n", type), 1214 1215 E_FAIL); 1215 1216 } … … 1218 1219 1219 1220 HRESULT rc = mVirtualBox->registerHardDisk (this, VirtualBox::RHD_OnStartUp); 1220 if (FAILED (rc)) 1221 return rc; 1221 CheckComRCReturnRC (rc); 1222 1222 1223 1223 /* load all children */ 1224 unsigned count = 0; 1225 CFGLDRCountChildren (aHDNode, "DiffHardDisk", &count); 1226 for (unsigned i = 0; i < count && SUCCEEDED (rc); ++ i) 1227 { 1228 CFGNODE hdNode = 0; 1229 1230 CFGLDRGetChildNode (aHDNode, "DiffHardDisk", i, &hdNode); 1231 ComAssertBreak (hdNode, rc = E_FAIL); 1232 1233 do 1234 { 1235 CFGNODE vdiNode = 0; 1236 CFGLDRGetChildNode (hdNode, "VirtualDiskImage", 0, &vdiNode); 1237 ComAssertBreak (vdiNode, rc = E_FAIL); 1238 1239 ComObjPtr <HVirtualDiskImage> vdi; 1240 vdi.createObject(); 1241 rc = vdi->init (mVirtualBox, this, hdNode, vdiNode); 1242 1243 CFGLDRReleaseNode (vdiNode); 1244 } 1245 while (0); 1246 1247 CFGLDRReleaseNode (hdNode); 1224 Key::List children = aHDNode.keys ("DiffHardDisk"); 1225 for (Key::List::const_iterator it = children.begin(); 1226 it != children.end(); ++ it) 1227 { 1228 Key vdiNode = (*it).key ("VirtualDiskImage"); 1229 1230 ComObjPtr <HVirtualDiskImage> vdi; 1231 vdi.createObject(); 1232 rc = vdi->init (mVirtualBox, this, (*it), vdiNode); 1233 CheckComRCBreakRC (rc); 1248 1234 } 1249 1235 … … 1259 1245 * 1260 1246 * @param aHDNode <HardDisk> node when #isDifferencing() = false, or 1261 * <DiffHardDisk> node otherwise 1247 * <DiffHardDisk> node otherwise. 1262 1248 * 1263 1249 * @note 1264 1250 * Must be called from under the object's lock 1265 1251 */ 1266 HRESULT HardDisk::saveSettings (CFGNODE aHDNode) 1267 { 1268 AssertReturn (aHDNode, E_FAIL); 1252 HRESULT HardDisk::saveSettings (settings::Key &aHDNode) 1253 { 1254 using namespace settings; 1255 1256 AssertReturn (!aHDNode.isNull(), E_FAIL); 1269 1257 1270 1258 /* uuid (required) */ 1271 CFGLDRSetUUID (aHDNode, "uuid", mId.ptr());1259 aHDNode.setValue <Guid> ("uuid", mId); 1272 1260 1273 1261 if (!isDifferencing()) … … 1287 1275 break; 1288 1276 } 1289 CFGLDRSetString (aHDNode, "type", type); 1290 } 1291 1292 HRESULT rc = S_OK; 1277 aHDNode.setStringValue ("type", type); 1278 } 1293 1279 1294 1280 /* save all children */ 1295 1281 AutoLock chLock (childrenLock()); 1296 1282 for (HardDiskList::const_iterator it = children().begin(); 1297 it != children().end() && SUCCEEDED (rc);1283 it != children().end(); 1298 1284 ++ it) 1299 1285 { … … 1301 1287 AutoLock childLock (child); 1302 1288 1303 CFGNODE hdNode = 0; 1304 CFGLDRAppendChildNode (aHDNode, "DiffHardDisk", &hdNode); 1305 ComAssertBreak (hdNode, rc = E_FAIL); 1306 1307 do 1308 { 1309 CFGNODE vdiNode = 0; 1310 CFGLDRAppendChildNode (hdNode, "VirtualDiskImage", &vdiNode); 1311 ComAssertBreak (vdiNode, rc = E_FAIL); 1312 1313 rc = child->saveSettings (hdNode, vdiNode); 1314 1315 CFGLDRReleaseNode (vdiNode); 1316 } 1317 while (0); 1318 1319 CFGLDRReleaseNode (hdNode); 1320 } 1321 1322 return rc; 1289 Key hdNode = aHDNode.appendKey ("DiffHardDisk"); 1290 1291 { 1292 Key vdiNode = hdNode.createKey ("VirtualDiskImage"); 1293 HRESULT rc = child->saveSettings (hdNode, vdiNode); 1294 CheckComRCReturnRC (rc); 1295 } 1296 } 1297 1298 return S_OK; 1323 1299 } 1324 1300 … … 1363 1339 * registered on success. 1364 1340 * 1365 * @param aHDNode <HardDisk> node1366 * @param aVDINode <VirtualDiskImage> node 1341 * @param aHDNode <HardDisk> or <DiffHardDisk> node. 1342 * @param aVDINode <VirtualDiskImage> node. 1367 1343 */ 1368 1344 HRESULT HVirtualDiskImage::init (VirtualBox *aVirtualBox, HardDisk *aParent, 1369 CFGNODE aHDNode, CFGNODE aVDINode) 1370 { 1371 LogFlowThisFunc (("aHDNode=%p, aVDINode=%p\n", aHDNode, aVDINode)); 1372 1373 AssertReturn (aHDNode && aVDINode, E_FAIL); 1345 const settings::Key &aHDNode, 1346 const settings::Key &aVDINode) 1347 { 1348 using namespace settings; 1349 1350 LogFlowThisFunc (("\n")); 1351 1352 AssertReturn (!aHDNode.isNull() && !aVDINode.isNull(), E_FAIL); 1374 1353 1375 1354 AutoLock alock (this); … … 1389 1368 1390 1369 /* filePath (required) */ 1391 Bstr filePath; 1392 CFGLDRQueryBSTR (aVDINode, "filePath", filePath.asOutParam()); 1393 1370 Bstr filePath = aVDINode.stringValue ("filePath"); 1394 1371 rc = setFilePath (filePath); 1395 1372 CheckComRCBreakRC (rc); … … 1768 1745 * all children to the specified hard disk node 1769 1746 * 1770 * @param aHDNode <HardDisk> or <DiffHardDisk> node 1771 * @param aStorageNode <VirtualDiskImage> node 1772 */ 1773 HRESULT HVirtualDiskImage::saveSettings (CFGNODE aHDNode, CFGNODE aStorageNode) 1774 { 1775 AssertReturn (aHDNode && aStorageNode, E_FAIL); 1776 1777 AutoLock alock (this); 1778 CHECK_READY(); 1779 1780 // filePath (required) 1781 CFGLDRSetBSTR (aStorageNode, "filePath", mFilePath); 1782 1783 // save basic settings and children 1747 * @param aHDNode <HardDisk> or <DiffHardDisk> node. 1748 * @param aStorageNode <VirtualDiskImage> node. 1749 */ 1750 HRESULT HVirtualDiskImage::saveSettings (settings::Key &aHDNode, 1751 settings::Key &aStorageNode) 1752 { 1753 AssertReturn (!aHDNode.isNull() && !aStorageNode.isNull(), E_FAIL); 1754 1755 AutoLock alock (this); 1756 CHECK_READY(); 1757 1758 /* filePath (required) */ 1759 aStorageNode.setValue <Bstr> ("filePath", mFilePath); 1760 1761 /* save basic settings and children */ 1784 1762 return HardDisk::saveSettings (aHDNode); 1785 1763 } … … 2834 2812 * registered on success. 2835 2813 * 2836 * @param aHDNode <HardDisk> node 2837 * @param aVDINod <ISCSIHardDisk> node 2814 * @param aHDNode <HardDisk> node. 2815 * @param aVDINod <ISCSIHardDisk> node. 2838 2816 */ 2839 2817 HRESULT HISCSIHardDisk::init (VirtualBox *aVirtualBox, 2840 CFGNODE aHDNode, CFGNODE aISCSINode) 2841 { 2842 LogFlowThisFunc (("aHDNode=%p, aISCSINode=%p\n", aHDNode, aISCSINode)); 2843 2844 AssertReturn (aHDNode && aISCSINode, E_FAIL); 2818 const settings::Key &aHDNode, 2819 const settings::Key &aISCSINode) 2820 { 2821 using namespace settings; 2822 2823 LogFlowThisFunc (("\n")); 2824 2825 AssertReturn (!aHDNode.isNull() && !aISCSINode.isNull(), E_FAIL); 2845 2826 2846 2827 AutoLock alock (this); … … 2860 2841 2861 2842 /* server (required) */ 2862 CFGLDRQueryBSTR (aISCSINode, "server", mServer.asOutParam());2843 mServer = aISCSINode.stringValue ("server"); 2863 2844 /* target (required) */ 2864 CFGLDRQueryBSTR (aISCSINode, "target", mTarget.asOutParam());2845 mTarget = aISCSINode.stringValue ("target"); 2865 2846 2866 2847 /* port (optional) */ 2867 CFGLDRQueryUInt16 (aISCSINode, "port", &mPort);2848 mPort = aISCSINode.value <USHORT> ("port"); 2868 2849 /* lun (optional) */ 2869 CFGLDRQueryUInt64 (aISCSINode, "lun", &mLun);2850 mLun = aISCSINode.value <ULONG64> ("lun"); 2870 2851 /* userName (optional) */ 2871 CFGLDRQueryBSTR (aISCSINode, "userName", mUserName.asOutParam());2852 mUserName = aISCSINode.stringValue ("userName"); 2872 2853 /* password (optional) */ 2873 CFGLDRQueryBSTR (aISCSINode, "password", mPassword.asOutParam());2854 mPassword = aISCSINode.stringValue ("password"); 2874 2855 2875 2856 LogFlowThisFunc (("'iscsi:%ls:%hu@%ls/%ls:%llu'\n", … … 3237 3218 * all children to the specified hard disk node 3238 3219 * 3239 * @param aHDNode <HardDisk> 3240 * @param aStorageNode <ISCSIHardDisk> node 3241 */ 3242 HRESULT HISCSIHardDisk::saveSettings (CFGNODE aHDNode, CFGNODE aStorageNode) 3243 { 3244 AssertReturn (aHDNode && aStorageNode, E_FAIL); 3220 * @param aHDNode <HardDisk>. 3221 * @param aStorageNode <ISCSIHardDisk> node. 3222 */ 3223 HRESULT HISCSIHardDisk::saveSettings (settings::Key &aHDNode, 3224 settings::Key &aStorageNode) 3225 { 3226 AssertReturn (!aHDNode.isNull() && !aStorageNode.isNull(), E_FAIL); 3245 3227 3246 3228 AutoLock alock (this); … … 3248 3230 3249 3231 /* server (required) */ 3250 CFGLDRSetBSTR (aStorageNode,"server", mServer);3232 aStorageNode.setValue <Bstr> ("server", mServer); 3251 3233 /* target (required) */ 3252 CFGLDRSetBSTR (aStorageNode, "target", mTarget); 3253 3254 /* port (optional) */ 3255 if (mPort != 0) 3256 CFGLDRSetUInt16 (aStorageNode, "port", mPort); 3257 else 3258 CFGLDRDeleteAttribute (aStorageNode, "port"); 3234 aStorageNode.setValue <Bstr> ("target", mTarget); 3235 3236 /* port (optional, defaults to 0) */ 3237 aStorageNode.setValueOr <USHORT> ("port", mPort, 0); 3259 3238 /* lun (optional, force 0x format to coform to XML Schema!) */ 3260 if (mLun != 0) 3261 CFGLDRSetUInt64Ex (aStorageNode, "lun", mLun, 16); 3262 else 3263 CFGLDRDeleteAttribute (aStorageNode, "lun"); 3239 aStorageNode.setValueOr <ULONG64> ("lun", mLun, 0, 16); 3264 3240 /* userName (optional) */ 3265 if (!mUserName.isNull()) 3266 CFGLDRSetBSTR (aStorageNode, "userName", mUserName); 3267 else 3268 CFGLDRDeleteAttribute (aStorageNode, "userName"); 3241 aStorageNode.setValueOr <Bstr> ("userName", mUserName, Bstr::Null); 3269 3242 /* password (optional) */ 3270 if (!mPassword.isNull()) 3271 CFGLDRSetBSTR (aStorageNode, "password", mPassword); 3272 else 3273 CFGLDRDeleteAttribute (aStorageNode, "password"); 3243 aStorageNode.setValueOr <Bstr> ("password", mPassword, Bstr::Null); 3274 3244 3275 3245 /* save basic settings and children */ … … 3422 3392 * registered on success. 3423 3393 * 3424 * @param aHDNode <HardDisk> node 3425 * @param aVMDKNode <VirtualDiskImage> node 3394 * @param aHDNode <HardDisk> node. 3395 * @param aVMDKNode <VirtualDiskImage> node. 3426 3396 */ 3427 3397 HRESULT HVMDKImage::init (VirtualBox *aVirtualBox, HardDisk *aParent, 3428 CFGNODE aHDNode, CFGNODE aVMDKNode) 3429 { 3430 LogFlowThisFunc (("aHDNode=%p, aVMDKNode=%p\n", aHDNode, aVMDKNode)); 3431 3432 AssertReturn (aHDNode && aVMDKNode, E_FAIL); 3398 const settings::Key &aHDNode, 3399 const settings::Key &aVMDKNode) 3400 { 3401 using namespace settings; 3402 3403 LogFlowThisFunc (("\n")); 3404 3405 AssertReturn (!aHDNode.isNull() && !aVMDKNode.isNull(), E_FAIL); 3433 3406 3434 3407 AutoLock alock (this); … … 3448 3421 3449 3422 /* filePath (required) */ 3450 Bstr filePath; 3451 CFGLDRQueryBSTR (aVMDKNode, "filePath", filePath.asOutParam()); 3452 3423 Bstr filePath = aVMDKNode.stringValue ("filePath"); 3453 3424 rc = setFilePath (filePath); 3454 3425 CheckComRCBreakRC (rc); … … 3858 3829 * all children to the specified hard disk node 3859 3830 * 3860 * @param aHDNode <HardDisk> or <DiffHardDisk> node 3861 * @param aStorageNode <VirtualDiskImage> node 3862 */ 3863 HRESULT HVMDKImage::saveSettings (CFGNODE aHDNode, CFGNODE aStorageNode) 3864 { 3865 AssertReturn (aHDNode && aStorageNode, E_FAIL); 3831 * @param aHDNode <HardDisk> or <DiffHardDisk> node. 3832 * @param aStorageNode <VirtualDiskImage> node. 3833 */ 3834 HRESULT HVMDKImage::saveSettings (settings::Key &aHDNode, 3835 settings::Key &aStorageNode) 3836 { 3837 AssertReturn (!aHDNode.isNull() && !aStorageNode.isNull(), E_FAIL); 3866 3838 3867 3839 AutoLock alock (this); … … 3869 3841 3870 3842 /* filePath (required) */ 3871 CFGLDRSetBSTR (aStorageNode,"filePath", mFilePath);3843 aStorageNode.setValue <Bstr> ("filePath", mFilePath); 3872 3844 3873 3845 /* save basic settings and children */ … … 4291 4263 * registered on success. 4292 4264 * 4293 * @param aHDNode <HardDisk> node 4294 * @param aCustomNode <VirtualDiskImage> node 4265 * @param aHDNode <HardDisk> node. 4266 * @param aCustomNode <VirtualDiskImage> node. 4295 4267 */ 4296 4268 HRESULT HCustomHardDisk::init (VirtualBox *aVirtualBox, HardDisk *aParent, 4297 CFGNODE aHDNode, CFGNODE aCustomNode) 4298 { 4299 LogFlowThisFunc (("aHDNode=%p, aCustomNode=%p\n", aHDNode, aCustomNode)); 4300 4301 AssertReturn (aHDNode && aCustomNode, E_FAIL); 4269 const settings::Key &aHDNode, 4270 const settings::Key &aCustomNode) 4271 { 4272 using namespace settings; 4273 4274 LogFlowThisFunc (("\n")); 4275 4276 AssertReturn (!aHDNode.isNull() && !aCustomNode.isNull(), E_FAIL); 4302 4277 4303 4278 AutoLock alock (this); … … 4317 4292 4318 4293 /* location (required) */ 4319 Bstr location; 4320 CFGLDRQueryBSTR (aCustomNode, "location", location.asOutParam()); 4321 4294 Bstr location = aCustomNode.stringValue ("location"); 4322 4295 rc = setLocation (location); 4323 4296 CheckComRCBreakRC (rc); … … 4326 4299 4327 4300 /* format (required) */ 4328 CFGLDRQueryBSTR (aCustomNode, "format", mFormat.asOutParam());4301 mFormat = aCustomNode.stringValue ("format"); 4329 4302 4330 4303 /* initialize the container */ … … 4732 4705 * all children to the specified hard disk node 4733 4706 * 4734 * @param aHDNode <HardDisk> or <DiffHardDisk> node 4735 * @param aStorageNode <VirtualDiskImage> node 4736 */ 4737 HRESULT HCustomHardDisk::saveSettings (CFGNODE aHDNode, CFGNODE aStorageNode) 4738 { 4739 AssertReturn (aHDNode && aStorageNode, E_FAIL); 4707 * @param aHDNode <HardDisk> or <DiffHardDisk> node. 4708 * @param aStorageNode <VirtualDiskImage> node. 4709 */ 4710 HRESULT HCustomHardDisk::saveSettings (settings::Key &aHDNode, 4711 settings::Key &aStorageNode) 4712 { 4713 AssertReturn (!aHDNode.isNull() && !aStorageNode.isNull(), E_FAIL); 4740 4714 4741 4715 AutoLock alock (this); … … 4743 4717 4744 4718 /* location (required) */ 4745 CFGLDRSetBSTR (aStorageNode,"location", mLocationFull);4719 aStorageNode.setValue <Bstr> ("location", mLocationFull); 4746 4720 4747 4721 /* format (required) */ 4748 CFGLDRSetBSTR (aStorageNode,"format", mFormat);4722 aStorageNode.setValue <Bstr> ("format", mFormat); 4749 4723 4750 4724 /* save basic settings and children */ -
trunk/src/VBox/Main/HostImpl.cpp
r5999 r6076 1133 1133 } 1134 1134 1135 HRESULT Host::loadSettings (CFGNODE aGlobal) 1136 { 1135 HRESULT Host::loadSettings (const settings::Key &aGlobal) 1136 { 1137 using namespace settings; 1138 1137 1139 AutoLock lock (this); 1138 1140 CHECK_READY(); 1139 1141 1140 ComAssertRet (aGlobal, E_FAIL); 1141 1142 CFGNODE filters = NULL; 1143 CFGLDRGetChildNode (aGlobal, "USBDeviceFilters", 0, &filters); 1144 Assert (filters); 1142 AssertReturn (!aGlobal.isNull(), E_FAIL); 1145 1143 1146 1144 HRESULT rc = S_OK; 1147 1145 1148 unsigned filterCount = 0; 1149 CFGLDRCountChildren (filters, "DeviceFilter", &filterCount); 1150 for (unsigned i = 0; i < filterCount && SUCCEEDED (rc); i++) 1151 { 1152 CFGNODE filter = NULL; 1153 CFGLDRGetChildNode (filters, "DeviceFilter", i, &filter); 1154 Assert (filter); 1155 1156 Bstr name; 1157 CFGLDRQueryBSTR (filter, "name", name.asOutParam()); 1158 bool active; 1159 CFGLDRQueryBool (filter, "active", &active); 1160 1161 Bstr vendorId; 1162 CFGLDRQueryBSTR (filter, "vendorid", vendorId.asOutParam()); 1163 Bstr productId; 1164 CFGLDRQueryBSTR (filter, "productid", productId.asOutParam()); 1165 Bstr revision; 1166 CFGLDRQueryBSTR (filter, "revision", revision.asOutParam()); 1167 Bstr manufacturer; 1168 CFGLDRQueryBSTR (filter, "manufacturer", manufacturer.asOutParam()); 1169 Bstr product; 1170 CFGLDRQueryBSTR (filter, "product", product.asOutParam()); 1171 Bstr serialNumber; 1172 CFGLDRQueryBSTR (filter, "serialnumber", serialNumber.asOutParam()); 1173 Bstr port; 1174 CFGLDRQueryBSTR (filter, "port", port.asOutParam()); 1146 Key::List filters = aGlobal.key ("USBDeviceFilters").keys ("DeviceFilter"); 1147 for (Key::List::const_iterator it = filters.begin(); 1148 it != filters.end(); ++ it) 1149 { 1150 Bstr name = (*it).stringValue ("name"); 1151 bool active = (*it).value <bool> ("active"); 1152 1153 Bstr vendorId = (*it).stringValue ("vendorid"); 1154 Bstr productId = (*it).stringValue ("productid"); 1155 Bstr revision = (*it).stringValue ("revision"); 1156 Bstr manufacturer = (*it).stringValue ("manufacturer"); 1157 Bstr product = (*it).stringValue ("product"); 1158 Bstr serialNumber = (*it).stringValue ("serialnumber"); 1159 Bstr port = (*it).stringValue ("port"); 1175 1160 1176 1161 USBDeviceFilterAction_T action; 1177 1162 action = USBDeviceFilterAction_USBDeviceFilterIgnore; 1178 Bstr actionStr; 1179 CFGLDRQueryBSTR (filter, "action", actionStr.asOutParam()); 1180 if (actionStr == L"Ignore") 1163 const char *actionStr = (*it).stringValue ("action"); 1164 if (strcmp (actionStr, "Ignore") == 0) 1181 1165 action = USBDeviceFilterAction_USBDeviceFilterIgnore; 1182 1166 else 1183 if ( actionStr == L"Hold")1167 if (strcmp (actionStr, "Hold") == 0) 1184 1168 action = USBDeviceFilterAction_USBDeviceFilterHold; 1185 1169 else 1186 AssertMsgFailed (("Invalid action: %ls\n", actionStr.raw()));1170 AssertMsgFailed (("Invalid action: '%s'\n", actionStr)); 1187 1171 1188 1172 ComObjPtr <HostUSBDeviceFilter> filterObj; … … 1192 1176 manufacturer, product, serialNumber, port, 1193 1177 action); 1194 / / error info is set by init() when appropriate1195 if (SUCCEEDED (rc))1196 { 1197 1198 1199 1200 // notify the proxy (only when the filter is active)1201 1202 1203 HostUSBDeviceFilter *flt = filterObj; // resolve ambiguity1178 /* error info is set by init() when appropriate */ 1179 CheckComRCBreakRC (rc); 1180 1181 mUSBDeviceFilters.push_back (filterObj); 1182 filterObj->mInList = true; 1183 1184 /* notify the proxy (only when the filter is active) */ 1185 if (filterObj->data().mActive) 1186 { 1187 HostUSBDeviceFilter *flt = filterObj; /* resolve ambiguity */ 1204 1188 #ifndef VBOX_WITH_USBFILTER 1205 1206 1189 flt->id() = 1190 mUSBProxyService->insertFilter (ComPtr <IUSBDeviceFilter> (flt)); 1207 1191 #else 1208 1192 flt->id() = mUSBProxyService->insertFilter (&filterObj->data().mUSBFilter); 1209 1193 #endif 1210 } 1211 } 1212 1213 CFGLDRReleaseNode (filter); 1214 } 1215 1216 CFGLDRReleaseNode (filters); 1194 } 1195 } 1217 1196 1218 1197 return rc; 1219 1198 } 1220 1199 1221 HRESULT Host::saveSettings (CFGNODE aGlobal) 1222 { 1200 HRESULT Host::saveSettings (settings::Key &aGlobal) 1201 { 1202 using namespace settings; 1203 1223 1204 AutoLock lock (this); 1224 1205 CHECK_READY(); 1225 1206 1226 ComAssertRet (aGlobal, E_FAIL); 1227 1228 // first, delete the entry 1229 CFGNODE filters = NULL; 1230 int vrc = CFGLDRGetChildNode (aGlobal, "USBDeviceFilters", 0, &filters); 1231 if (VBOX_SUCCESS (vrc)) 1232 { 1233 vrc = CFGLDRDeleteNode (filters); 1234 ComAssertRCRet (vrc, E_FAIL); 1235 } 1236 // then, recreate it 1237 vrc = CFGLDRCreateChildNode (aGlobal, "USBDeviceFilters", &filters); 1238 ComAssertRCRet (vrc, E_FAIL); 1207 ComAssertRet (!aGlobal.isNull(), E_FAIL); 1208 1209 /* first, delete the entry */ 1210 Key filters = aGlobal.findKey ("USBDeviceFilters"); 1211 if (!filters.isNull()) 1212 filters.zap(); 1213 /* then, recreate it */ 1214 filters = aGlobal.createKey ("USBDeviceFilters"); 1239 1215 1240 1216 USBDeviceFilterList::const_iterator it = mUSBDeviceFilters.begin(); … … 1244 1220 const HostUSBDeviceFilter::Data &data = (*it)->data(); 1245 1221 1246 CFGNODE filter = NULL; 1247 CFGLDRAppendChildNode (filters, "DeviceFilter", &filter); 1248 1249 CFGLDRSetBSTR (filter, "name", data.mName); 1250 CFGLDRSetBool (filter, "active", !!data.mActive); 1222 Key filter = filters.appendKey ("DeviceFilter"); 1223 1224 filter.setValue <Bstr> ("name", data.mName); 1225 filter.setValue <bool> ("active", !!data.mActive); 1251 1226 1252 1227 #ifndef VBOX_WITH_USBFILTER 1253 // all are optional 1228 1229 /* all are optional */ 1254 1230 if (data.mVendorId.string()) 1255 CFGLDRSetBSTR (filter,"vendorid", data.mVendorId.string());1231 filter.setValue <Bstr> ("vendorid", data.mVendorId.string()); 1256 1232 if (data.mProductId.string()) 1257 CFGLDRSetBSTR (filter,"productid", data.mProductId.string());1233 filter.setValue <Bstr> ("productid", data.mProductId.string()); 1258 1234 if (data.mRevision.string()) 1259 CFGLDRSetBSTR (filter,"revision", data.mRevision.string());1235 filter.setValue <Bstr> ("revision", data.mRevision.string()); 1260 1236 if (data.mManufacturer.string()) 1261 CFGLDRSetBSTR (filter,"manufacturer", data.mManufacturer.string());1237 filter.setValue <Bstr> ("manufacturer", data.mManufacturer.string()); 1262 1238 if (data.mProduct.string()) 1263 CFGLDRSetBSTR (filter,"product", data.mProduct.string());1239 filter.setValue <Bstr> ("product", data.mProduct.string()); 1264 1240 if (data.mSerialNumber.string()) 1265 CFGLDRSetBSTR (filter,"serialnumber", data.mSerialNumber.string());1241 filter.setValue <Bstr> ("serialnumber", data.mSerialNumber.string()); 1266 1242 if (data.mPort.string()) 1267 CFGLDRSetBSTR (filter,"port", data.mPort.string());1268 1269 / / action is mandatory1243 filter.setValue <Bstr> ("port", data.mPort.string()); 1244 1245 /* action is mandatory */ 1270 1246 if (data.mAction == USBDeviceFilterAction_USBDeviceFilterIgnore) 1271 CFGLDRSetString (filter,"action", "Ignore");1247 filter.setStringValue ("action", "Ignore"); 1272 1248 else 1273 1249 if (data.mAction == USBDeviceFilterAction_USBDeviceFilterHold) 1274 CFGLDRSetString (filter,"action", "Hold");1250 filter.setStringValue ("action", "Hold"); 1275 1251 else 1276 1252 AssertMsgFailed (("Invalid action: %d\n", data.mAction)); 1277 1253 1278 1254 #else /* VBOX_WITH_USBFILTER */ 1279 // all are optional 1255 1256 /* all are optional */ 1280 1257 Bstr str; 1281 1258 (*it)->COMGETTER (VendorId) (str.asOutParam()); 1282 1259 if (!str.isNull()) 1283 CFGLDRSetBSTR (filter,"vendorid", str);1260 filter.setValue <Bstr> ("vendorid", str); 1284 1261 1285 1262 (*it)->COMGETTER (ProductId) (str.asOutParam()); 1286 1263 if (!str.isNull()) 1287 CFGLDRSetBSTR (filter,"productid", str);1264 filter.setValue <Bstr> ("productid", str); 1288 1265 1289 1266 (*it)->COMGETTER (Revision) (str.asOutParam()); 1290 1267 if (!str.isNull()) 1291 CFGLDRSetBSTR (filter,"revision", str);1268 filter.setValue <Bstr> ("revision", str); 1292 1269 1293 1270 (*it)->COMGETTER (Manufacturer) (str.asOutParam()); 1294 1271 if (!str.isNull()) 1295 CFGLDRSetBSTR (filter,"manufacturer", str);1272 filter.setValue <Bstr> ("manufacturer", str); 1296 1273 1297 1274 (*it)->COMGETTER (Product) (str.asOutParam()); 1298 1275 if (!str.isNull()) 1299 CFGLDRSetBSTR (filter,"product", str);1276 filter.setValue <Bstr> ("product", str); 1300 1277 1301 1278 (*it)->COMGETTER (SerialNumber) (str.asOutParam()); 1302 1279 if (!str.isNull()) 1303 CFGLDRSetBSTR (filter,"serialnumber", str);1280 filter.setValue <Bstr> ("serialnumber", str); 1304 1281 1305 1282 (*it)->COMGETTER (Port) (str.asOutParam()); 1306 1283 if (!str.isNull()) 1307 CFGLDRSetBSTR (filter,"port", str);1308 1309 / / action is mandatory1284 filter.setValue <Bstr> ("port", str); 1285 1286 /* action is mandatory */ 1310 1287 ULONG action = USBDeviceFilterAction_InvalidUSBDeviceFilterAction; 1311 1288 (*it)->COMGETTER (Action) (&action); 1312 1289 if (action == USBDeviceFilterAction_USBDeviceFilterIgnore) 1313 CFGLDRSetString (filter,"action", "Ignore");1290 filter.setStringValue ("action", "Ignore"); 1314 1291 else if (action == USBDeviceFilterAction_USBDeviceFilterHold) 1315 CFGLDRSetString (filter,"action", "Hold");1292 filter.setStringValue ("action", "Hold"); 1316 1293 else 1317 1294 AssertMsgFailed (("Invalid action: %d\n", action)); 1295 1318 1296 #endif /* VBOX_WITH_USBFILTER */ 1319 1297 1320 CFGLDRReleaseNode (filter);1321 1322 1298 ++ it; 1323 1299 } 1324 1325 CFGLDRReleaseNode (filters);1326 1300 1327 1301 return S_OK; -
trunk/src/VBox/Main/MachineDebuggerImpl.cpp
r5999 r6076 173 173 174 174 char *pszSnapshot; 175 int vrc = STAMR3Snapshot(pVM, Utf8Str(aPattern).raw(), &pszSnapshot, NULL, aWithDescriptions); 175 int vrc = STAMR3Snapshot(pVM, Utf8Str(aPattern).raw(), &pszSnapshot, NULL, 176 !!aWithDescriptions); 176 177 if (RT_FAILURE(vrc)) 177 178 return vrc == VERR_NO_MEMORY ? E_OUTOFMEMORY : E_FAIL; -
trunk/src/VBox/Main/MachineImpl.cpp
r6056 r6076 31 31 #include "MachineImpl.h" 32 32 #include "HardDiskImpl.h" 33 #include "HostDVDDriveImpl.h"34 #include "HostFloppyDriveImpl.h"35 33 #include "ProgressImpl.h" 36 34 #include "HardDiskAttachmentImpl.h" … … 45 43 #include "USBProxyService.h" 46 44 45 #include "VirtualBoxXMLUtil.h" 46 47 47 #include "Logging.h" 48 48 … … 58 58 59 59 #include <VBox/err.h> 60 #include <VBox/cfgldr.h>61 60 #include <VBox/param.h> 62 61 63 62 #include <algorithm> 63 64 #include <typeinfo> 64 65 65 66 #if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2) … … 116 117 117 118 mMachineState = MachineState_PoweredOff; 118 RTTIMESPEC time; 119 mLastStateChange = RTTimeSpecGetMilli (RTTimeNow (&time)); 119 RTTimeNow (&mLastStateChange); 120 120 121 121 mMachineStateDeps = 0; … … 1399 1399 AutoReaderLock alock (this); 1400 1400 1401 *aLastStateChange = mData->mLastStateChange;1401 *aLastStateChange = RTTimeSpecGetMilli (&mData->mLastStateChange); 1402 1402 1403 1403 return S_OK; … … 1930 1930 } 1931 1931 1932 /** 1933 * @note Locks this object for reading. 1934 */ 1932 1935 STDMETHODIMP Machine::GetNextExtraDataKey (INPTR BSTR aKey, BSTR *aNextKey, BSTR *aNextValue) 1933 1936 { … … 1942 1945 /* start with nothing found */ 1943 1946 *aNextKey = NULL; 1944 1945 /*1946 * if we're ready and isConfigLocked() is FALSE then it means 1947 * that no config file exists yet, so return shortly1948 * /1947 if (aNextValue) 1948 *aNextValue = NULL; 1949 1950 /* if we're ready and isConfigLocked() is FALSE then it means 1951 * that no config file exists yet, so return shortly */ 1949 1952 if (!isConfigLocked()) 1950 1953 return S_OK; … … 1952 1955 HRESULT rc = S_OK; 1953 1956 1954 /* load the config file */ 1955 CFGHANDLE configLoader = 0; 1956 rc = openConfigLoader (&configLoader); 1957 if (FAILED (rc)) 1958 return E_FAIL; 1959 1960 CFGNODE machineNode; 1961 CFGNODE extraDataNode; 1962 1963 /* navigate to the right position */ 1964 if (VBOX_SUCCESS(CFGLDRGetNode(configLoader, "VirtualBox/Machine", 0, &machineNode)) && 1965 VBOX_SUCCESS(CFGLDRGetChildNode(machineNode, "ExtraData", 0, &extraDataNode))) 1966 { 1967 /* check if it exists */ 1968 bool found = false; 1969 unsigned count; 1970 CFGNODE extraDataItemNode; 1971 CFGLDRCountChildren(extraDataNode, "ExtraDataItem", &count); 1972 for (unsigned i = 0; (i < count) && (found == false); i++) 1973 { 1974 Bstr name; 1975 CFGLDRGetChildNode(extraDataNode, "ExtraDataItem", i, &extraDataItemNode); 1976 CFGLDRQueryBSTR(extraDataItemNode, "name", name.asOutParam()); 1977 1978 /* if we're supposed to return the first one */ 1979 if (aKey == NULL) 1957 try 1958 { 1959 using namespace settings; 1960 1961 /* load the config file */ 1962 File file (File::ReadWrite, mData->mHandleCfgFile, 1963 Utf8Str (mData->mConfigFileFull)); 1964 XmlTreeBackend tree; 1965 1966 rc = VirtualBox::loadSettingsTree_Again (tree, file); 1967 CheckComRCReturnRC (rc); 1968 1969 Key machineNode = tree.rootKey().key ("Machine"); 1970 Key extraDataNode = machineNode.findKey ("ExtraData"); 1971 1972 if (!extraDataNode.isNull()) 1973 { 1974 Key::List items = extraDataNode.keys ("ExtraDataItem"); 1975 if (items.size()) 1980 1976 { 1981 name.cloneTo(aNextKey); 1982 if (aNextValue) 1983 CFGLDRQueryBSTR(extraDataItemNode, "value", aNextValue); 1984 found = true; 1985 } 1986 /* did we find the key we're looking for? */ 1987 else if (name == aKey) 1988 { 1989 found = true; 1990 /* is there another item? */ 1991 if (i + 1 < count) 1977 for (Key::List::const_iterator it = items.begin(); 1978 it != items.end(); ++ it) 1992 1979 { 1993 CFGLDRGetChildNode(extraDataNode, "ExtraDataItem", i + 1, &extraDataItemNode); 1994 CFGLDRQueryBSTR(extraDataItemNode, "name", name.asOutParam()); 1995 name.cloneTo(aNextKey); 1996 if (aNextValue) 1997 CFGLDRQueryBSTR(extraDataItemNode, "value", aNextValue); 1998 found = true; 1999 } 2000 else 2001 { 2002 /* it's the last one */ 2003 *aNextKey = NULL; 1980 Bstr key = (*it).stringValue ("name"); 1981 1982 /* if we're supposed to return the first one */ 1983 if (aKey == NULL) 1984 { 1985 key.cloneTo (aNextKey); 1986 if (aNextValue) 1987 { 1988 Bstr val = (*it).stringValue ("value"); 1989 val.cloneTo (aNextValue); 1990 } 1991 return S_OK; 1992 } 1993 1994 /* did we find the key we're looking for? */ 1995 if (key == aKey) 1996 { 1997 ++ it; 1998 /* is there another item? */ 1999 if (it != items.end()) 2000 { 2001 Bstr key = (*it).stringValue ("name"); 2002 key.cloneTo (aNextKey); 2003 if (aNextValue) 2004 { 2005 Bstr val = (*it).stringValue ("value"); 2006 val.cloneTo (aNextValue); 2007 } 2008 } 2009 /* else it's the last one, arguments are already NULL */ 2010 return S_OK; 2011 } 2004 2012 } 2005 2013 } 2006 CFGLDRReleaseNode(extraDataItemNode); 2007 } 2008 2009 /* if we haven't found the key, it's an error */ 2010 if (!found) 2011 rc = setError(E_FAIL, tr("Could not find extra data key")); 2012 2013 CFGLDRReleaseNode(extraDataNode); 2014 CFGLDRReleaseNode(machineNode); 2015 } 2016 2017 closeConfigLoader (configLoader, false /* aSaveBeforeClose */); 2014 } 2015 2016 /* Here we are when a) there are no items at all or b) there are items 2017 * but none of them equals to the requested non-NULL key. b) is an 2018 * error as well as a) if the key is non-NULL. When the key is NULL 2019 * (which is the case only when there are no items), we just fall 2020 * through to return NULLs and S_OK. */ 2021 2022 if (aKey != NULL) 2023 return setError (E_FAIL, 2024 tr ("Could not find the extra data key '%ls'"), aKey); 2025 } 2026 catch (...) 2027 { 2028 rc = VirtualBox::handleUnexpectedExceptions (RT_SRC_POS); 2029 } 2018 2030 2019 2031 return rc; 2020 2032 } 2021 2033 2034 /** 2035 * @note Locks this object for reading. 2036 */ 2022 2037 STDMETHODIMP Machine::GetExtraData (INPTR BSTR aKey, BSTR *aValue) 2023 2038 { … … 2035 2050 *aValue = NULL; 2036 2051 2037 /* 2038 * if we're ready and isConfigLocked() is FALSE then it means 2039 * that no config file exists yet, so return shortly 2040 */ 2052 /* if we're ready and isConfigLocked() is FALSE then it means 2053 * that no config file exists yet, so return shortly */ 2041 2054 if (!isConfigLocked()) 2042 2055 return S_OK; … … 2044 2057 HRESULT rc = S_OK; 2045 2058 2046 /* load the config file */ 2047 CFGHANDLE configLoader = 0; 2048 rc = openConfigLoader (&configLoader); 2049 if (FAILED (rc)) 2050 return E_FAIL; 2051 2052 CFGNODE machineNode; 2053 CFGNODE extraDataNode; 2054 2055 /* navigate to the right position */ 2056 if (VBOX_SUCCESS(CFGLDRGetNode(configLoader, "VirtualBox/Machine", 0, &machineNode)) && 2057 VBOX_SUCCESS(CFGLDRGetChildNode(machineNode, "ExtraData", 0, &extraDataNode))) 2058 { 2059 /* check if it exists */ 2060 bool found = false; 2061 unsigned count; 2062 CFGNODE extraDataItemNode; 2063 CFGLDRCountChildren(extraDataNode, "ExtraDataItem", &count); 2064 for (unsigned i = 0; (i < count) && (found == false); i++) 2065 { 2066 Bstr name; 2067 CFGLDRGetChildNode(extraDataNode, "ExtraDataItem", i, &extraDataItemNode); 2068 CFGLDRQueryBSTR(extraDataItemNode, "name", name.asOutParam()); 2069 if (name == aKey) 2059 try 2060 { 2061 using namespace settings; 2062 2063 /* load the config file */ 2064 File file (File::ReadWrite, mData->mHandleCfgFile, 2065 Utf8Str (mData->mConfigFileFull)); 2066 XmlTreeBackend tree; 2067 2068 rc = VirtualBox::loadSettingsTree_Again (tree, file); 2069 CheckComRCReturnRC (rc); 2070 2071 const Utf8Str key = aKey; 2072 2073 Key machineNode = tree.rootKey().key ("Machine"); 2074 Key extraDataNode = machineNode.findKey ("ExtraData"); 2075 2076 if (!extraDataNode.isNull()) 2077 { 2078 /* check if the key exists */ 2079 Key::List items = extraDataNode.keys ("ExtraDataItem"); 2080 for (Key::List::const_iterator it = items.begin(); 2081 it != items.end(); ++ it) 2070 2082 { 2071 found = true; 2072 CFGLDRQueryBSTR(extraDataItemNode, "value", aValue); 2083 if (key == (*it).stringValue ("name")) 2084 { 2085 Bstr val = (*it).stringValue ("value"); 2086 val.cloneTo (aValue); 2087 break; 2088 } 2073 2089 } 2074 CFGLDRReleaseNode(extraDataItemNode); 2075 } 2076 2077 CFGLDRReleaseNode(extraDataNode); 2078 CFGLDRReleaseNode(machineNode); 2079 } 2080 2081 rc = closeConfigLoader (configLoader, false /* aSaveBeforeClose */); 2090 } 2091 } 2092 catch (...) 2093 { 2094 rc = VirtualBox::handleUnexpectedExceptions (RT_SRC_POS); 2095 } 2082 2096 2083 2097 return rc; … … 2085 2099 2086 2100 /** 2087 * @note Locks mParent for reading + this object for writing.2101 * @note Locks mParent for writing + this object for writing. 2088 2102 */ 2089 2103 STDMETHODIMP Machine::SetExtraData (INPTR BSTR aKey, INPTR BSTR aValue) … … 2095 2109 CheckComRCReturnRC (autoCaller.rc()); 2096 2110 2097 /* VirtualBox::onExtraDataCanChange() needs mParent lock */ 2098 AutoMultiLock <2> alock (mParent->rlock(), this->wlock()); 2111 /* VirtualBox::onExtraDataCanChange() and saveSettings() need mParent 2112 * lock (saveSettings() needs a write one) */ 2113 AutoMultiLock <2> alock (mParent->wlock(), this->wlock()); 2099 2114 2100 2115 if (mType == IsSnapshotMachine) … … 2107 2122 HRESULT rc = S_OK; 2108 2123 2109 /* 2110 * if we're ready and isConfigLocked() is FALSE then it means 2111 * that no config file exists yet, so call saveSettings() to create one 2112 */ 2124 /* If we're ready and isConfigLocked() is FALSE then it means that no 2125 * config file exists yet, so call saveSettings() to create one. */ 2113 2126 if (!isConfigLocked()) 2114 2127 { 2115 2128 rc = saveSettings (false /* aMarkCurStateAsModified */); 2116 if (FAILED (rc)) 2117 return rc; 2118 } 2119 2120 /* load the config file */ 2121 CFGHANDLE configLoader = 0; 2122 rc = openConfigLoader (&configLoader); 2123 if (FAILED (rc)) 2124 return rc; 2125 2126 CFGNODE machineNode = 0; 2127 CFGNODE extraDataNode = 0; 2128 2129 int vrc = CFGLDRGetNode (configLoader, "VirtualBox/Machine", 0, &machineNode); 2130 if (VBOX_FAILURE (vrc)) 2131 vrc = CFGLDRCreateNode (configLoader, "VirtualBox/Machine", &machineNode); 2132 2133 vrc = CFGLDRGetChildNode (machineNode, "ExtraData", 0, &extraDataNode); 2134 if (VBOX_FAILURE (vrc) && aValue) 2135 vrc = CFGLDRCreateChildNode (machineNode, "ExtraData", &extraDataNode); 2136 2137 if (extraDataNode) 2138 { 2139 CFGNODE extraDataItemNode = 0; 2129 CheckComRCReturnRC (rc); 2130 } 2131 2132 try 2133 { 2134 using namespace settings; 2135 2136 /* load the config file */ 2137 File file (File::ReadWrite, mData->mHandleCfgFile, 2138 Utf8Str (mData->mConfigFileFull)); 2139 XmlTreeBackend tree; 2140 2141 rc = VirtualBox::loadSettingsTree_ForUpdate (tree, file); 2142 CheckComRCReturnRC (rc); 2143 2144 const Utf8Str key = aKey; 2140 2145 Bstr oldVal; 2141 2146 2142 unsigned count;2143 CFGLDRCountChildren (extraDataNode, "ExtraDataItem", &count);2144 2145 for (unsigned i = 0; i < count; i++) 2146 {2147 CFGLDRGetChildNode (extraDataNode, "ExtraDataItem", i, &extraDataItemNode);2148 Bstr name;2149 CFGLDRQueryBSTR (extraDataItemNode, "name", name.asOutParam());2150 if ( name == aKey)2147 Key machineNode = tree.rootKey().key ("Machine"); 2148 Key extraDataNode = machineNode.createKey ("ExtraData"); 2149 Key extraDataItemNode; 2150 2151 Key::List items = extraDataNode.keys ("ExtraDataItem"); 2152 for (Key::List::const_iterator it = items.begin(); 2153 it != items.end(); ++ it) 2154 { 2155 if (key == (*it).stringValue ("name")) 2151 2156 { 2152 CFGLDRQueryBSTR (extraDataItemNode, "value", oldVal.asOutParam()); 2157 extraDataItemNode = *it; 2158 oldVal = (*it).stringValue ("value"); 2153 2159 break; 2154 2160 } 2155 CFGLDRReleaseNode (extraDataItemNode); 2156 extraDataItemNode = 0; 2157 } 2158 2159 /* 2160 * When no key is found, oldVal is null 2161 * Note: 2162 * 1. when oldVal is null, |oldVal == (BSTR) NULL| is true 2163 * 2. we cannot do |oldVal != aValue| because it will compare 2164 * BSTR pointers instead of strings (due to type conversion ops) 2165 */ 2166 changed = !(oldVal == aValue); 2161 } 2162 2163 /* When no key is found, oldVal is null */ 2164 changed = oldVal != aValue; 2167 2165 2168 2166 if (changed) … … 2176 2174 LogWarningFunc (("Someone vetoed! Change refused%s%ls\n", 2177 2175 sep, err)); 2178 r c =setError (E_ACCESSDENIED,2176 return setError (E_ACCESSDENIED, 2179 2177 tr ("Could not set extra data because someone refused " 2180 2178 "the requested change of '%ls' to '%ls'%s%ls"), 2181 2179 aKey, aValue, sep, err); 2182 2180 } 2181 2182 if (aValue != NULL) 2183 { 2184 if (extraDataItemNode.isNull()) 2185 { 2186 extraDataItemNode = extraDataNode.appendKey ("ExtraDataItem"); 2187 extraDataItemNode.setStringValue ("name", key); 2188 } 2189 extraDataItemNode.setStringValue ("value", Utf8Str (aValue)); 2190 } 2183 2191 else 2184 2192 { 2185 if (aValue) 2186 { 2187 if (!extraDataItemNode) 2188 { 2189 /* create a new item */ 2190 CFGLDRAppendChildNode (extraDataNode, "ExtraDataItem", 2191 &extraDataItemNode); 2192 CFGLDRSetBSTR (extraDataItemNode, "name", aKey); 2193 } 2194 CFGLDRSetBSTR (extraDataItemNode, "value", aValue); 2195 } 2196 else 2197 { 2198 /* an old value does for sure exist here */ 2199 CFGLDRDeleteNode (extraDataItemNode); 2200 extraDataItemNode = 0; 2201 } 2193 /* an old value does for sure exist here (XML schema 2194 * guarantees that "value" may not absent in the 2195 * <ExtraDataItem> element) */ 2196 Assert (!extraDataItemNode.isNull()); 2197 extraDataItemNode.zap(); 2202 2198 } 2203 } 2204 2205 if (extraDataItemNode) 2206 CFGLDRReleaseNode (extraDataItemNode); 2207 2208 CFGLDRReleaseNode (extraDataNode); 2209 } 2210 2211 CFGLDRReleaseNode (machineNode); 2212 2199 2200 /* save settings on success */ 2201 rc = VirtualBox::saveSettingsTree (tree, file); 2202 CheckComRCReturnRC (rc); 2203 } 2204 } 2205 catch (...) 2206 { 2207 rc = VirtualBox::handleUnexpectedExceptions (RT_SRC_POS); 2208 } 2209 2210 /* fire a notification */ 2213 2211 if (SUCCEEDED (rc) && changed) 2214 rc = closeConfigLoader (configLoader, true /* aSaveBeforeClose */);2215 else2216 closeConfigLoader (configLoader, false /* aSaveBeforeClose */);2217 2218 /* fire an event */2219 if (SUCCEEDED (rc) && changed)2220 {2221 2212 mParent->onExtraDataChange (mData->mUuid, aKey, aValue); 2222 }2223 2213 2224 2214 return rc; … … 2230 2220 CheckComRCReturnRC (autoCaller.rc()); 2231 2221 2232 /* Under some circumstancies,saveSettings() needs mParent lock */2222 /* saveSettings() needs mParent lock */ 2233 2223 AutoMultiLock <2> alock (mParent->wlock(), this->wlock()); 2234 2224 … … 2323 2313 /* delete the directory that contains the settings file, but only 2324 2314 * if it matches the VM name (i.e. a structure created by default in 2325 * openConfigLoader()) */2315 * prepareSaveSettings()) */ 2326 2316 { 2327 2317 Utf8Str settingsDir; … … 2545 2535 * @note locks this object for reading. 2546 2536 */ 2547 HRESULT Machine::saveRegistryEntry ( CFGNODEaEntryNode)2548 { 2549 AssertReturn ( aEntryNode, E_FAIL);2537 HRESULT Machine::saveRegistryEntry (settings::Key &aEntryNode) 2538 { 2539 AssertReturn (!aEntryNode.isNull(), E_FAIL); 2550 2540 2551 2541 AutoLimitedCaller autoCaller (this); … … 2555 2545 2556 2546 /* UUID */ 2557 CFGLDRSetUUID (aEntryNode, "uuid", mData->mUuid.raw());2547 aEntryNode.setValue <Guid> ("uuid", mData->mUuid); 2558 2548 /* settings file name (possibly, relative) */ 2559 CFGLDRSetBSTR (aEntryNode,"src", mData->mConfigFile);2549 aEntryNode.setValue <Bstr> ("src", mData->mConfigFile); 2560 2550 2561 2551 return S_OK; … … 3290 3280 * on the current thread because this will block Machine::uninit(). 3291 3281 * 3292 * @note Locks this object and children for writing! 3282 * @note Must be called from mParent's write lock. Locks this object and 3283 * children for writing. 3293 3284 */ 3294 3285 HRESULT Machine::trySetRegistered (BOOL aRegistered) 3295 3286 { 3287 AssertReturn (mParent->isLockedOnCurrentThread(), E_FAIL); 3288 3296 3289 AutoLimitedCaller autoCaller (this); 3297 3290 AssertComRCReturnRC (autoCaller.rc()); … … 3783 3776 mData->mMachineState = aMachineState; 3784 3777 3785 RTTIMESPEC time; 3786 mData->mLastStateChange = RTTimeSpecGetMilli(RTTimeNow(&time)); 3778 RTTimeNow (&mData->mLastStateChange); 3787 3779 3788 3780 mParent->onMachineStateChange (mData->mUuid, aMachineState); … … 3851 3843 HRESULT rc = S_OK; 3852 3844 3853 CFGHANDLE configLoader = NULL; 3854 char *loaderError = NULL; 3855 int vrc = CFGLDRLoad (&configLoader, 3856 Utf8Str (mData->mConfigFileFull), mData->mHandleCfgFile, 3857 XmlSchemaNS, true, cfgLdrEntityResolver, 3858 &loaderError); 3859 if (VBOX_FAILURE (vrc)) 3860 { 3861 rc = setError (E_FAIL, 3862 tr ("Could not load the settings file '%ls' (%Vrc)%s%s"), 3863 mData->mConfigFileFull.raw(), vrc, 3864 loaderError ? ".\n" : "", loaderError ? loaderError : ""); 3865 3866 if (loaderError) 3867 RTMemTmpFree (loaderError); 3868 3869 LogFlowThisFuncLeave(); 3870 return rc; 3871 } 3872 3873 /* 3874 * When reading the XML, we assume it has been validated, so we don't 3875 * do any structural checks here, Just Assert() some things. 3876 */ 3877 3878 CFGNODE machineNode = 0; 3879 CFGLDRGetNode (configLoader, "VirtualBox/Machine", 0, &machineNode); 3880 3881 do 3882 { 3883 ComAssertBreak (machineNode, rc = E_FAIL); 3845 try 3846 { 3847 using namespace settings; 3848 3849 File file (File::Read, mData->mHandleCfgFile, 3850 Utf8Str (mData->mConfigFileFull)); 3851 XmlTreeBackend tree; 3852 3853 rc = VirtualBox::loadSettingsTree_FirstTime (tree, file); 3854 CheckComRCThrowRC (rc); 3855 3856 Key machineNode = tree.rootKey().key ("Machine"); 3884 3857 3885 3858 /* uuid (required) */ 3886 Guid id; 3887 CFGLDRQueryUUID (machineNode, "uuid", id.ptr()); 3859 Guid id = machineNode.value <Guid> ("uuid"); 3888 3860 3889 3861 /* If the stored UUID is not empty, it means the registered machine … … 3894 3866 if (mData->mUuid != id) 3895 3867 { 3896 rc =setError (E_FAIL,3868 throw setError (E_FAIL, 3897 3869 tr ("Machine UUID {%Vuuid} in '%ls' doesn't match its " 3898 3870 "UUID {%s} in the registry file '%ls'"), … … 3900 3872 mData->mUuid.toString().raw(), 3901 3873 mParent->settingsFileName().raw()); 3902 break;3903 3874 } 3904 3875 } … … 3907 3878 3908 3879 /* name (required) */ 3909 CFGLDRQueryBSTR (machineNode, "name", mUserData->mName.asOutParam());3880 mUserData->mName = machineNode.stringValue ("name"); 3910 3881 3911 3882 /* nameSync (optional, default is true) */ 3912 { 3913 bool nameSync = true; 3914 CFGLDRQueryBool (machineNode, "nameSync", &nameSync); 3915 mUserData->mNameSync = nameSync; 3916 } 3883 mUserData->mNameSync = machineNode.value <bool> ("nameSync"); 3917 3884 3918 3885 /* Description (optional, default is null) */ 3919 3886 { 3920 CFGNODE descNode = 0; 3921 CFGLDRGetChildNode (machineNode, "Description", 0, &descNode); 3922 if (descNode) 3923 { 3924 CFGLDRQueryBSTR (descNode, NULL, 3925 mUserData->mDescription.asOutParam()); 3926 CFGLDRReleaseNode (descNode); 3927 } 3887 Key descNode = machineNode.findKey ("Description"); 3888 if (!descNode.isNull()) 3889 mUserData->mDescription = descNode.keyStringValue(); 3928 3890 else 3929 3891 mUserData->mDescription.setNull(); … … 3932 3894 /* OSType (required) */ 3933 3895 { 3934 CFGLDRQueryBSTR (machineNode, "OSType", 3935 mUserData->mOSTypeId.asOutParam()); 3896 mUserData->mOSTypeId = machineNode.stringValue ("OSType"); 3936 3897 3937 3898 /* look up the object by Id to check it is valid */ … … 3939 3900 rc = mParent->GetGuestOSType (mUserData->mOSTypeId, 3940 3901 guestOSType.asOutParam()); 3941 if (FAILED (rc)) 3942 break; 3902 CheckComRCThrowRC (rc); 3943 3903 } 3944 3904 3945 3905 /* stateFile (optional) */ 3946 3906 { 3947 Bstr stateFilePath; 3948 CFGLDRQueryBSTR (machineNode, "stateFile", stateFilePath.asOutParam()); 3907 Bstr stateFilePath = machineNode.stringValue ("stateFile"); 3949 3908 if (stateFilePath) 3950 3909 { … … 3953 3912 if (VBOX_FAILURE (vrc)) 3954 3913 { 3955 rc =setError (E_FAIL,3914 throw setError (E_FAIL, 3956 3915 tr ("Invalid saved state file path: '%ls' (%Vrc)"), 3957 3916 stateFilePath.raw(), vrc); 3958 break;3959 3917 } 3960 3918 mSSData->mStateFilePath = stateFilePathFull; … … 3966 3924 /* 3967 3925 * currentSnapshot ID (optional) 3968 * Note that due to XML Schema constaraints this attribute, when present, 3969 * will guaranteedly refer to an existing snapshot definition in XML 3926 * 3927 * Note that due to XML Schema constaraints, this attribute, when 3928 * present, will guaranteedly refer to an existing snapshot 3929 * definition in XML 3970 3930 */ 3971 Guid currentSnapshotId ;3972 CFGLDRQueryUUID (machineNode, "currentSnapshot", currentSnapshotId.ptr());3931 Guid currentSnapshotId = machineNode.valueOr <Guid> ("currentSnapshot", 3932 Guid()); 3973 3933 3974 3934 /* snapshotFolder (optional) */ 3975 3935 { 3976 Bstr folder; 3977 CFGLDRQueryBSTR (machineNode, "snapshotFolder", folder.asOutParam()); 3936 Bstr folder = machineNode.stringValue ("snapshotFolder"); 3978 3937 rc = COMSETTER(SnapshotFolder) (folder); 3979 if (FAILED (rc)) 3980 break; 3981 } 3938 CheckComRCThrowRC (rc); 3939 } 3940 3941 /* currentStateModified (optional, default is true) */ 3942 mData->mCurrentStateModified = machineNode.value <bool> ("currentStateModified"); 3982 3943 3983 3944 /* lastStateChange (optional, for compatiblity) */ 3984 3945 { 3985 int64_t lastStateChange = 0; 3986 CFGLDRQueryDateTime (machineNode, "lastStateChange", &lastStateChange); 3987 if (lastStateChange == 0) 3988 { 3989 /// @todo (dmik) until lastStateChange is the required attribute, 3990 // we simply set it to the current time if missing in the config 3991 RTTIMESPEC time; 3992 lastStateChange = RTTimeSpecGetMilli (RTTimeNow (&time)); 3993 } 3994 mData->mLastStateChange = lastStateChange; 3995 } 3996 3997 /* aborted (optional) */ 3998 bool aborted = false; 3999 CFGLDRQueryBool (machineNode, "aborted", &aborted); 4000 4001 /* currentStateModified (optional, default is true) */ 4002 mData->mCurrentStateModified = TRUE; 4003 { 4004 bool val = true; 4005 CFGLDRQueryBool (machineNode, "currentStateModified", &val); 4006 mData->mCurrentStateModified = val; 4007 } 3946 /// @todo (dmik) until lastStateChange is the required attribute, 3947 // we simply set it to the current time if missing in the config 3948 RTTIMESPEC now; 3949 RTTimeNow (&now); 3950 mData->mLastStateChange = 3951 machineNode.valueOr <RTTIMESPEC> ("lastStateChange", now); 3952 } 3953 3954 /* aborted (optional, default is false) */ 3955 bool aborted = machineNode.value <bool> ("aborted"); 4008 3956 4009 3957 /* … … 4016 3964 /* Snapshot node (optional) */ 4017 3965 { 4018 CFGNODE snapshotNode = 0; 4019 CFGLDRGetChildNode (machineNode, "Snapshot", 0, &snapshotNode); 4020 if (snapshotNode) 3966 Key snapshotNode = machineNode.findKey ("Snapshot"); 3967 if (!snapshotNode.isNull()) 4021 3968 { 4022 3969 /* read all snapshots recursively */ 4023 3970 rc = loadSnapshot (snapshotNode, currentSnapshotId, NULL); 4024 CFGLDRReleaseNode (snapshotNode); 4025 if (FAILED (rc)) 4026 break; 3971 CheckComRCThrowRC (rc); 4027 3972 } 4028 3973 } 4029 3974 4030 3975 /* Hardware node (required) */ 4031 { 4032 CFGNODE hardwareNode = 0; 4033 CFGLDRGetChildNode (machineNode, "Hardware", 0, &hardwareNode); 4034 ComAssertBreak (hardwareNode, rc = E_FAIL); 4035 rc = loadHardware (hardwareNode); 4036 CFGLDRReleaseNode (hardwareNode); 4037 if (FAILED (rc)) 4038 break; 4039 } 3976 rc = loadHardware (machineNode.key ("Hardware")); 3977 CheckComRCThrowRC (rc); 4040 3978 4041 3979 /* HardDiskAttachments node (required) */ 4042 { 4043 CFGNODE hdasNode = 0; 4044 CFGLDRGetChildNode (machineNode, "HardDiskAttachments", 0, &hdasNode); 4045 ComAssertBreak (hdasNode, rc = E_FAIL); 4046 4047 rc = loadHardDisks (hdasNode, aRegistered); 4048 CFGLDRReleaseNode (hdasNode); 4049 if (FAILED (rc)) 4050 break; 4051 } 3980 rc = loadHardDisks (machineNode.key ("HardDiskAttachments"), aRegistered); 3981 CheckComRCThrowRC (rc); 4052 3982 4053 3983 /* … … 4073 4003 } 4074 4004 } 4075 while (0); 4076 4077 if (machineNode) 4078 CFGLDRReleaseNode (machineNode); 4079 4080 CFGLDRFree (configLoader); 4005 catch (HRESULT err) 4006 { 4007 /* we assume that error info is set by the thrower */ 4008 rc = err; 4009 } 4010 catch (...) 4011 { 4012 rc = VirtualBox::handleUnexpectedExceptions (RT_SRC_POS); 4013 } 4081 4014 4082 4015 LogFlowThisFuncLeave(); … … 4087 4020 * Recursively loads all snapshots starting from the given. 4088 4021 * 4089 * @param aNode <Snapshot> node 4090 * @param aCurSnapshotId current snapshot ID from the settings file4091 * @param aParentSnapshot parent snapshot4022 * @param aNode <Snapshot> node. 4023 * @param aCurSnapshotId Current snapshot ID from the settings file. 4024 * @param aParentSnapshot Parent snapshot. 4092 4025 */ 4093 HRESULT Machine::loadSnapshot (CFGNODE aNode, const Guid &aCurSnapshotId, 4026 HRESULT Machine::loadSnapshot (const settings::Key &aNode, 4027 const Guid &aCurSnapshotId, 4094 4028 Snapshot *aParentSnapshot) 4095 4029 { 4096 AssertReturn (aNode, E_INVALIDARG); 4030 using namespace settings; 4031 4032 AssertReturn (!aNode.isNull(), E_INVALIDARG); 4097 4033 AssertReturn (mType == IsMachine, E_FAIL); 4098 4034 4099 / / create a snapshot machine object4035 /* create a snapshot machine object */ 4100 4036 ComObjPtr <SnapshotMachine> snapshotMachine; 4101 4037 snapshotMachine.createObject(); … … 4103 4039 HRESULT rc = S_OK; 4104 4040 4105 Guid uuid; // required 4106 CFGLDRQueryUUID (aNode, "uuid", uuid.ptr()); 4107 4108 Bstr stateFilePath; // optional 4109 CFGLDRQueryBSTR (aNode, "stateFile", stateFilePath.asOutParam()); 4110 if (stateFilePath) 4111 { 4112 Utf8Str stateFilePathFull = stateFilePath; 4113 int vrc = calculateFullPath (stateFilePathFull, stateFilePathFull); 4114 if (VBOX_FAILURE (vrc)) 4115 return setError (E_FAIL, 4116 tr ("Invalid saved state file path: '%ls' (%Vrc)"), 4117 stateFilePath.raw(), vrc); 4118 4119 stateFilePath = stateFilePathFull; 4120 } 4121 4122 do 4123 { 4124 // Hardware node (required) 4125 CFGNODE hardwareNode = 0; 4126 CFGLDRGetChildNode (aNode, "Hardware", 0, &hardwareNode); 4127 ComAssertBreak (hardwareNode, rc = E_FAIL); 4128 4129 do 4130 { 4131 // HardDiskAttachments node (required) 4132 CFGNODE hdasNode = 0; 4133 CFGLDRGetChildNode (aNode, "HardDiskAttachments", 0, &hdasNode); 4134 ComAssertBreak (hdasNode, rc = E_FAIL); 4135 4136 // initialize the snapshot machine 4137 rc = snapshotMachine->init (this, hardwareNode, hdasNode, 4138 uuid, stateFilePath); 4139 4140 CFGLDRReleaseNode (hdasNode); 4141 } 4142 while (0); 4143 4144 CFGLDRReleaseNode (hardwareNode); 4145 } 4146 while (0); 4147 4148 if (FAILED (rc)) 4149 return rc; 4150 4151 // create a snapshot object 4041 /* required */ 4042 Guid uuid = aNode.value <Guid> ("uuid"); 4043 4044 { 4045 /* optional */ 4046 Bstr stateFilePath = aNode.stringValue ("stateFile"); 4047 if (stateFilePath) 4048 { 4049 Utf8Str stateFilePathFull = stateFilePath; 4050 int vrc = calculateFullPath (stateFilePathFull, stateFilePathFull); 4051 if (VBOX_FAILURE (vrc)) 4052 return setError (E_FAIL, 4053 tr ("Invalid saved state file path: '%ls' (%Vrc)"), 4054 stateFilePath.raw(), vrc); 4055 4056 stateFilePath = stateFilePathFull; 4057 } 4058 4059 /* Hardware node (required) */ 4060 Key hardwareNode = aNode.key ("Hardware"); 4061 4062 /* HardDiskAttachments node (required) */ 4063 Key hdasNode = aNode.key ("HardDiskAttachments"); 4064 4065 /* initialize the snapshot machine */ 4066 rc = snapshotMachine->init (this, hardwareNode, hdasNode, 4067 uuid, stateFilePath); 4068 CheckComRCReturnRC (rc); 4069 } 4070 4071 /* create a snapshot object */ 4152 4072 ComObjPtr <Snapshot> snapshot; 4153 4073 snapshot.createObject(); 4154 4074 4155 4075 { 4156 Bstr name; // required 4157 CFGLDRQueryBSTR (aNode, "name", name.asOutParam()); 4158 4159 LONG64 timeStamp = 0; // required 4160 CFGLDRQueryDateTime (aNode, "timeStamp", &timeStamp); 4161 4162 Bstr description; // optional 4163 { 4164 CFGNODE descNode = 0; 4165 CFGLDRGetChildNode (aNode, "Description", 0, &descNode); 4166 if (descNode) 4167 { 4168 CFGLDRQueryBSTR (descNode, NULL, description.asOutParam()); 4169 CFGLDRReleaseNode (descNode); 4170 } 4171 } 4172 4173 // initialize the snapshot 4076 /* required */ 4077 Bstr name = aNode.stringValue ("name"); 4078 4079 /* required */ 4080 RTTIMESPEC timeStamp = aNode.value <RTTIMESPEC> ("timeStamp"); 4081 4082 /* optional */ 4083 Bstr description; 4084 { 4085 Key descNode = aNode.findKey ("Description"); 4086 if (!descNode.isNull()) 4087 description = descNode.keyStringValue(); 4088 } 4089 4090 /* initialize the snapshot */ 4174 4091 rc = snapshot->init (uuid, name, description, timeStamp, 4175 4092 snapshotMachine, aParentSnapshot); 4176 if (FAILED (rc)) 4177 return rc; 4178 } 4179 4180 // memorize the first snapshot if necessary 4093 CheckComRCReturnRC (rc); 4094 } 4095 4096 /* memorize the first snapshot if necessary */ 4181 4097 if (!mData->mFirstSnapshot) 4182 4098 mData->mFirstSnapshot = snapshot; 4183 4099 4184 / / memorize the current snapshot when appropriate4100 /* memorize the current snapshot when appropriate */ 4185 4101 if (!mData->mCurrentSnapshot && snapshot->data().mId == aCurSnapshotId) 4186 4102 mData->mCurrentSnapshot = snapshot; 4187 4103 4188 // Snapshots node (optional) 4189 { 4190 CFGNODE snapshotsNode = 0; 4191 CFGLDRGetChildNode (aNode, "Snapshots", 0, &snapshotsNode); 4192 if (snapshotsNode) 4193 { 4194 unsigned cbDisks = 0; 4195 CFGLDRCountChildren (snapshotsNode, "Snapshot", &cbDisks); 4196 for (unsigned i = 0; i < cbDisks && SUCCEEDED (rc); i++) 4104 /* Snapshots node (optional) */ 4105 { 4106 Key snapshotsNode = aNode.findKey ("Snapshots"); 4107 if (!snapshotsNode.isNull()) 4108 { 4109 Key::List children = snapshotsNode.keys ("Snapshot"); 4110 for (Key::List::const_iterator it = children.begin(); 4111 it != children.end(); ++ it) 4197 4112 { 4198 CFGNODE snapshotNode; 4199 CFGLDRGetChildNode (snapshotsNode, "Snapshot", i, &snapshotNode); 4200 ComAssertBreak (snapshotNode, rc = E_FAIL); 4201 4202 rc = loadSnapshot (snapshotNode, aCurSnapshotId, snapshot); 4203 4204 CFGLDRReleaseNode (snapshotNode); 4113 rc = loadSnapshot ((*it), aCurSnapshotId, snapshot); 4114 CheckComRCBreakRC (rc); 4205 4115 } 4206 4207 CFGLDRReleaseNode (snapshotsNode);4208 4116 } 4209 4117 } … … 4213 4121 4214 4122 /** 4215 * @param aNode <Hardware> node 4123 * @param aNode <Hardware> node. 4216 4124 */ 4217 HRESULT Machine::loadHardware (CFGNODE aNode) 4218 { 4219 AssertReturn (aNode, E_INVALIDARG); 4125 HRESULT Machine::loadHardware (const settings::Key &aNode) 4126 { 4127 using namespace settings; 4128 4129 AssertReturn (!aNode.isNull(), E_INVALIDARG); 4220 4130 AssertReturn (mType == IsMachine || mType == IsSnapshotMachine, E_FAIL); 4131 4132 HRESULT rc = S_OK; 4221 4133 4222 4134 /* CPU node (currently not required) */ … … 4225 4137 mHWData->mHWVirtExEnabled = TriStateBool_Default; 4226 4138 4227 CFGNODE cpuNode = 0; 4228 CFGLDRGetChildNode (aNode, "CPU", 0, &cpuNode); 4229 if (cpuNode) 4230 { 4231 CFGNODE hwVirtExNode = 0; 4232 CFGLDRGetChildNode (cpuNode, "HardwareVirtEx", 0, &hwVirtExNode); 4233 if (hwVirtExNode) 4139 Key cpuNode = aNode.findKey ("CPU"); 4140 if (!cpuNode.isNull()) 4141 { 4142 Key hwVirtExNode = cpuNode.key ("HardwareVirtEx"); 4143 if (!hwVirtExNode.isNull()) 4234 4144 { 4235 Bstr hwVirtExEnabled; 4236 CFGLDRQueryBSTR (hwVirtExNode, "enabled", hwVirtExEnabled.asOutParam()); 4237 if (hwVirtExEnabled == L"false") 4145 const char *enabled = hwVirtExNode.stringValue ("enabled"); 4146 if (strcmp (enabled, "false") == 0) 4238 4147 mHWData->mHWVirtExEnabled = TriStateBool_False; 4239 else if ( hwVirtExEnabled == L"true")4148 else if (strcmp (enabled, "true") == 0) 4240 4149 mHWData->mHWVirtExEnabled = TriStateBool_True; 4241 4150 else 4242 4151 mHWData->mHWVirtExEnabled = TriStateBool_Default; 4243 CFGLDRReleaseNode (hwVirtExNode);4244 4152 } 4245 CFGLDRReleaseNode (cpuNode);4246 4153 } 4247 4154 } … … 4249 4156 /* Memory node (required) */ 4250 4157 { 4251 CFGNODE memoryNode = 0; 4252 CFGLDRGetChildNode (aNode, "Memory", 0, &memoryNode); 4253 ComAssertRet (memoryNode, E_FAIL); 4254 4255 uint32_t RAMSize; 4256 CFGLDRQueryUInt32 (memoryNode, "RAMSize", &RAMSize); 4257 mHWData->mMemorySize = RAMSize; 4258 CFGLDRReleaseNode (memoryNode); 4158 Key memoryNode = aNode.key ("Memory"); 4159 4160 mHWData->mMemorySize = memoryNode.value <ULONG> ("RAMSize"); 4259 4161 } 4260 4162 … … 4265 4167 mHWData->mBootOrder [i] = DeviceType_NoDevice; 4266 4168 4267 CFGNODE bootNode = 0; 4268 CFGLDRGetChildNode (aNode, "Boot", 0, &bootNode); 4269 ComAssertRet (bootNode, E_FAIL); 4270 4271 HRESULT rc = S_OK; 4272 4273 unsigned cOrder; 4274 CFGLDRCountChildren (bootNode, "Order", &cOrder); 4275 for (unsigned i = 0; i < cOrder; i++) 4276 { 4277 CFGNODE orderNode = 0; 4278 CFGLDRGetChildNode (bootNode, "Order", i, &orderNode); 4279 ComAssertBreak (orderNode, rc = E_FAIL); 4280 4169 Key bootNode = aNode.key ("Boot"); 4170 4171 Key::List orderNodes = bootNode.keys ("Order"); 4172 for (Key::List::const_iterator it = orderNodes.begin(); 4173 it != orderNodes.end(); ++ it) 4174 { 4281 4175 /* position (required) */ 4282 4176 /* position unicity is guaranteed by XML Schema */ 4283 uint32_t position = 0; 4284 CFGLDRQueryUInt32 (orderNode, "position", &position); 4177 uint32_t position = (*it).value <uint32_t> ("position"); 4285 4178 -- position; 4286 4179 Assert (position < ELEMENTS (mHWData->mBootOrder)); 4287 4180 4288 4181 /* device (required) */ 4289 Bstr device; 4290 CFGLDRQueryBSTR (orderNode, "device", device.asOutParam()); 4291 if (device == L"None") 4182 const char *device = (*it).stringValue ("device"); 4183 if (strcmp (device, "None") == 0) 4292 4184 mHWData->mBootOrder [position] = DeviceType_NoDevice; 4293 else if ( device == L"Floppy")4185 else if (strcmp (device, "Floppy") == 0) 4294 4186 mHWData->mBootOrder [position] = DeviceType_FloppyDevice; 4295 else if ( device == L"DVD")4187 else if (strcmp (device, "DVD") == 0) 4296 4188 mHWData->mBootOrder [position] = DeviceType_DVDDevice; 4297 else if ( device == L"HardDisk")4189 else if (strcmp (device, "HardDisk") == 0) 4298 4190 mHWData->mBootOrder [position] = DeviceType_HardDiskDevice; 4299 else if ( device == L"Network")4191 else if (strcmp (device, "Network") == 0) 4300 4192 mHWData->mBootOrder [position] = DeviceType_NetworkDevice; 4301 4193 else 4302 ComAssertMsgFailed (("Invalid device: %ls\n", device.raw())); 4303 4304 CFGLDRReleaseNode (orderNode); 4305 } 4306 4307 CFGLDRReleaseNode (bootNode); 4308 if (FAILED (rc)) 4309 return rc; 4194 ComAssertMsgFailed (("Invalid device: %s\n", device)); 4195 } 4310 4196 } 4311 4197 4312 4198 /* Display node (required) */ 4313 4199 { 4314 CFGNODE displayNode = 0; 4315 CFGLDRGetChildNode (aNode, "Display", 0, &displayNode); 4316 ComAssertRet (displayNode, E_FAIL); 4317 4318 uint32_t VRAMSize; 4319 CFGLDRQueryUInt32 (displayNode, "VRAMSize", &VRAMSize); 4320 mHWData->mVRAMSize = VRAMSize; 4321 4322 uint32_t MonitorCount; 4323 CFGLDRQueryUInt32 (displayNode, "MonitorCount", &MonitorCount); 4324 mHWData->mMonitorCount = MonitorCount; 4325 4326 CFGLDRReleaseNode (displayNode); 4200 Key displayNode = aNode.key ("Display"); 4201 4202 mHWData->mVRAMSize = displayNode.value <ULONG> ("VRAMSize"); 4203 mHWData->mMonitorCount = displayNode.value <ULONG> ("MonitorCount"); 4327 4204 } 4328 4205 4329 4206 #ifdef VBOX_VRDP 4330 /* RemoteDisplay node (optional) */ 4331 { 4332 CFGNODE remoteDisplayNode = 0; 4333 CFGLDRGetChildNode (aNode, "RemoteDisplay", 0, &remoteDisplayNode); 4334 if (remoteDisplayNode) 4335 { 4336 HRESULT rc = mVRDPServer->loadSettings (remoteDisplayNode); 4337 CFGLDRReleaseNode (remoteDisplayNode); 4338 CheckComRCReturnRC (rc); 4339 } 4340 } 4207 /* RemoteDisplay */ 4208 rc = mVRDPServer->loadSettings (aNode); 4209 CheckComRCReturnRC (rc); 4341 4210 #endif 4342 4211 4343 /* BIOS node (required) */ 4344 { 4345 CFGNODE biosNode = 0; 4346 CFGLDRGetChildNode (aNode, "BIOS", 0, &biosNode); 4347 ComAssertRet (biosNode, E_FAIL); 4348 4349 HRESULT rc = S_OK; 4350 4351 do 4352 { 4353 /* ACPI */ 4354 { 4355 CFGNODE acpiNode = 0; 4356 CFGLDRGetChildNode (biosNode, "ACPI", 0, &acpiNode); 4357 ComAssertBreak (acpiNode, rc = E_FAIL); 4358 4359 bool enabled; 4360 CFGLDRQueryBool (acpiNode, "enabled", &enabled); 4361 mBIOSSettings->COMSETTER(ACPIEnabled)(enabled); 4362 CFGLDRReleaseNode (acpiNode); 4363 } 4364 4365 /* IOAPIC */ 4366 { 4367 CFGNODE ioapicNode = 0; 4368 CFGLDRGetChildNode (biosNode, "IOAPIC", 0, &ioapicNode); 4369 if (ioapicNode) 4370 { 4371 bool enabled; 4372 CFGLDRQueryBool (ioapicNode, "enabled", &enabled); 4373 mBIOSSettings->COMSETTER(IOAPICEnabled)(enabled); 4374 CFGLDRReleaseNode (ioapicNode); 4375 } 4376 } 4377 4378 /* Logo (optional) */ 4379 { 4380 CFGNODE logoNode = 0; 4381 CFGLDRGetChildNode (biosNode, "Logo", 0, &logoNode); 4382 if (logoNode) 4383 { 4384 bool enabled = false; 4385 CFGLDRQueryBool (logoNode, "fadeIn", &enabled); 4386 mBIOSSettings->COMSETTER(LogoFadeIn)(enabled); 4387 CFGLDRQueryBool (logoNode, "fadeOut", &enabled); 4388 mBIOSSettings->COMSETTER(LogoFadeOut)(enabled); 4389 4390 uint32_t BIOSLogoDisplayTime; 4391 CFGLDRQueryUInt32 (logoNode, "displayTime", &BIOSLogoDisplayTime); 4392 mBIOSSettings->COMSETTER(LogoDisplayTime)(BIOSLogoDisplayTime); 4393 4394 Bstr logoPath; 4395 CFGLDRQueryBSTR (logoNode, "imagePath", logoPath.asOutParam()); 4396 mBIOSSettings->COMSETTER(LogoImagePath)(logoPath); 4397 4398 CFGLDRReleaseNode (logoNode); 4399 } 4400 } 4401 4402 /* boot menu (optional) */ 4403 { 4404 CFGNODE bootMenuNode = 0; 4405 CFGLDRGetChildNode (biosNode, "BootMenu", 0, &bootMenuNode); 4406 if (bootMenuNode) 4407 { 4408 Bstr modeStr; 4409 BIOSBootMenuMode_T mode; 4410 CFGLDRQueryBSTR (bootMenuNode, "mode", modeStr.asOutParam()); 4411 if (modeStr == L"disabled") 4412 mode = BIOSBootMenuMode_Disabled; 4413 else if (modeStr == L"menuonly") 4414 mode = BIOSBootMenuMode_MenuOnly; 4415 else 4416 mode = BIOSBootMenuMode_MessageAndMenu; 4417 mBIOSSettings->COMSETTER(BootMenuMode)(mode); 4418 4419 CFGLDRReleaseNode (bootMenuNode); 4420 } 4421 } 4422 4423 /* PXE debug logging (optional) */ 4424 { 4425 CFGNODE pxedebugNode = 0; 4426 CFGLDRGetChildNode (biosNode, "PXEDebug", 0, &pxedebugNode); 4427 if (pxedebugNode) 4428 { 4429 bool enabled; 4430 CFGLDRQueryBool (pxedebugNode, "enabled", &enabled); 4431 mBIOSSettings->COMSETTER(PXEDebugEnabled)(enabled); 4432 CFGLDRReleaseNode (pxedebugNode); 4433 } 4434 } 4435 4436 /* time offset (optional) */ 4437 { 4438 CFGNODE timeOffsetNode = 0; 4439 CFGLDRGetChildNode (biosNode, "TimeOffset", 0, &timeOffsetNode); 4440 if (timeOffsetNode) 4441 { 4442 LONG64 timeOffset; 4443 CFGLDRQueryInt64 (timeOffsetNode, "value", &timeOffset); 4444 mBIOSSettings->COMSETTER(TimeOffset)(timeOffset); 4445 CFGLDRReleaseNode (timeOffsetNode); 4446 } 4447 } 4448 4449 /* IDE controller type (optional, defaults to PIIX3) */ 4450 { 4451 CFGNODE ideControllerNode = 0; 4452 IDEControllerType_T controllerType = IDEControllerType_IDEControllerPIIX3; 4453 CFGLDRGetChildNode (biosNode, "IDEController", 0, &ideControllerNode); 4454 if (ideControllerNode) 4455 { 4456 Bstr IDEControllerType; 4457 4458 CFGLDRQueryBSTR (ideControllerNode, "type", IDEControllerType.asOutParam()); 4459 ComAssertBreak (IDEControllerType, rc = E_FAIL); 4460 4461 if (IDEControllerType.compare(Bstr("PIIX3")) == 0) 4462 controllerType = IDEControllerType_IDEControllerPIIX3; 4463 else if (IDEControllerType.compare(Bstr("PIIX4")) == 0) 4464 controllerType = IDEControllerType_IDEControllerPIIX4; 4465 else 4466 ComAssertBreak (0, rc = E_FAIL); 4467 4468 CFGLDRReleaseNode (ideControllerNode); 4469 } 4470 mBIOSSettings->COMSETTER(IDEControllerType)(controllerType); 4471 } 4472 4473 } 4474 while (0); 4475 4476 CFGLDRReleaseNode (biosNode); 4477 if (FAILED (rc)) 4478 return rc; 4479 } 4480 4481 /* DVD drive (contains either Image or HostDrive or nothing) */ 4482 /// @todo (dmik) move the code to DVDDrive 4483 { 4484 HRESULT rc = S_OK; 4485 4486 CFGNODE dvdDriveNode = 0; 4487 CFGLDRGetChildNode (aNode, "DVDDrive", 0, &dvdDriveNode); 4488 ComAssertRet (dvdDriveNode, E_FAIL); 4489 4490 bool fPassthrough; 4491 CFGLDRQueryBool(dvdDriveNode, "passthrough", &fPassthrough); 4492 mDVDDrive->COMSETTER(Passthrough)(fPassthrough); 4493 4494 CFGNODE typeNode = 0; 4495 4496 do 4497 { 4498 CFGLDRGetChildNode (dvdDriveNode, "Image", 0, &typeNode); 4499 if (typeNode) 4500 { 4501 Guid uuid; 4502 CFGLDRQueryUUID (typeNode, "uuid", uuid.ptr()); 4503 rc = mDVDDrive->MountImage (uuid); 4504 } 4505 else 4506 { 4507 CFGLDRGetChildNode (dvdDriveNode, "HostDrive", 0, &typeNode); 4508 if (typeNode) 4509 { 4510 Bstr src; 4511 CFGLDRQueryBSTR (typeNode, "src", src.asOutParam()); 4512 4513 /* find the correspoding object */ 4514 ComPtr <IHost> host; 4515 rc = mParent->COMGETTER(Host) (host.asOutParam()); 4516 ComAssertComRCBreak (rc, rc = rc); 4517 4518 ComPtr <IHostDVDDriveCollection> coll; 4519 rc = host->COMGETTER(DVDDrives) (coll.asOutParam()); 4520 ComAssertComRCBreak (rc, rc = rc); 4521 4522 ComPtr <IHostDVDDrive> drive; 4523 rc = coll->FindByName (src, drive.asOutParam()); 4524 if (SUCCEEDED (rc)) 4525 rc = mDVDDrive->CaptureHostDrive (drive); 4526 else if (rc == E_INVALIDARG) 4527 { 4528 /* the host DVD drive is not currently available. we 4529 * assume it will be available later and create an 4530 * extra object now */ 4531 ComObjPtr <HostDVDDrive> hostDrive; 4532 hostDrive.createObject(); 4533 rc = hostDrive->init (src); 4534 ComAssertComRCBreak (rc, rc = rc); 4535 rc = mDVDDrive->CaptureHostDrive (hostDrive); 4536 } 4537 else 4538 ComAssertComRCBreakRC (rc); 4539 } 4540 } 4541 } 4542 while (0); 4543 4544 if (typeNode) 4545 CFGLDRReleaseNode (typeNode); 4546 CFGLDRReleaseNode (dvdDriveNode); 4547 4548 if (FAILED (rc)) 4549 return rc; 4550 } 4551 4552 /* Floppy drive (contains either Image or HostDrive or nothing) */ 4553 /// @todo (dmik) move the code to FloppyDrive 4554 { 4555 HRESULT rc = S_OK; 4556 4557 CFGNODE driveNode = 0; 4558 CFGLDRGetChildNode (aNode, "FloppyDrive", 0, &driveNode); 4559 ComAssertRet (driveNode, E_FAIL); 4560 4561 BOOL fFloppyEnabled = TRUE; 4562 CFGLDRQueryBool (driveNode, "enabled", (bool*)&fFloppyEnabled); 4563 rc = mFloppyDrive->COMSETTER(Enabled)(fFloppyEnabled); 4564 4565 CFGNODE typeNode = 0; 4566 do 4567 { 4568 CFGLDRGetChildNode (driveNode, "Image", 0, &typeNode); 4569 if (typeNode) 4570 { 4571 Guid uuid; 4572 CFGLDRQueryUUID (typeNode, "uuid", uuid.ptr()); 4573 rc = mFloppyDrive->MountImage (uuid); 4574 } 4575 else 4576 { 4577 CFGLDRGetChildNode (driveNode, "HostDrive", 0, &typeNode); 4578 if (typeNode) 4579 { 4580 Bstr src; 4581 CFGLDRQueryBSTR (typeNode, "src", src.asOutParam()); 4582 4583 /* find the correspoding object */ 4584 ComPtr <IHost> host; 4585 rc = mParent->COMGETTER(Host) (host.asOutParam()); 4586 ComAssertComRCBreak (rc, rc = rc); 4587 4588 ComPtr <IHostFloppyDriveCollection> coll; 4589 rc = host->COMGETTER(FloppyDrives) (coll.asOutParam()); 4590 ComAssertComRCBreak (rc, rc = rc); 4591 4592 ComPtr <IHostFloppyDrive> drive; 4593 rc = coll->FindByName (src, drive.asOutParam()); 4594 if (SUCCEEDED (rc)) 4595 rc = mFloppyDrive->CaptureHostDrive (drive); 4596 else if (rc == E_INVALIDARG) 4597 { 4598 /* the host Floppy drive is not currently available. we 4599 * assume it will be available later and create an 4600 * extra object now */ 4601 ComObjPtr <HostFloppyDrive> hostDrive; 4602 hostDrive.createObject(); 4603 rc = hostDrive->init (src); 4604 ComAssertComRCBreak (rc, rc = rc); 4605 rc = mFloppyDrive->CaptureHostDrive (hostDrive); 4606 } 4607 else 4608 ComAssertComRCBreakRC (rc); 4609 } 4610 } 4611 } 4612 while (0); 4613 4614 if (typeNode) 4615 CFGLDRReleaseNode (typeNode); 4616 CFGLDRReleaseNode (driveNode); 4617 4618 CheckComRCReturnRC (rc); 4619 } 4212 /* BIOS */ 4213 rc = mBIOSSettings->loadSettings (aNode); 4214 CheckComRCReturnRC (rc); 4215 4216 /* DVD drive */ 4217 rc = mDVDDrive->loadSettings (aNode); 4218 CheckComRCReturnRC (rc); 4219 4220 /* Floppy drive */ 4221 rc = mFloppyDrive->loadSettings (aNode); 4222 CheckComRCReturnRC (rc); 4620 4223 4621 4224 /* USB Controller */ 4622 { 4623 HRESULT rc = mUSBController->loadSettings (aNode); 4624 CheckComRCReturnRC (rc); 4625 } 4225 rc = mUSBController->loadSettings (aNode); 4226 CheckComRCReturnRC (rc); 4626 4227 4627 4228 /* Network node (required) */ 4628 /// @todo (dmik) move the code to NetworkAdapter4629 4229 { 4630 4230 /* we assume that all network adapters are initially disabled 4631 4231 * and detached */ 4632 4232 4633 CFGNODE networkNode = 0; 4634 CFGLDRGetChildNode (aNode, "Network", 0, &networkNode); 4635 ComAssertRet (networkNode, E_FAIL); 4636 4637 HRESULT rc = S_OK; 4638 4639 unsigned cAdapters = 0; 4640 CFGLDRCountChildren (networkNode, "Adapter", &cAdapters); 4641 for (unsigned i = 0; i < cAdapters; i++) 4642 { 4643 CFGNODE adapterNode = 0; 4644 CFGLDRGetChildNode (networkNode, "Adapter", i, &adapterNode); 4645 ComAssertBreak (adapterNode, rc = E_FAIL); 4646 4233 Key networkNode = aNode.key ("Network"); 4234 4235 rc = S_OK; 4236 4237 Key::List adapters = networkNode.keys ("Adapter"); 4238 for (Key::List::const_iterator it = adapters.begin(); 4239 it != adapters.end(); ++ it) 4240 { 4647 4241 /* slot number (required) */ 4648 4242 /* slot unicity is guaranteed by XML Schema */ 4649 uint32_t slot = 0; 4650 CFGLDRQueryUInt32 (adapterNode, "slot", &slot); 4651 Assert (slot < ELEMENTS (mNetworkAdapters)); 4652 4653 /* type */ 4654 Bstr adapterType; 4655 CFGLDRQueryBSTR (adapterNode, "type", adapterType.asOutParam()); 4656 ComAssertBreak (adapterType, rc = E_FAIL); 4657 4658 /* enabled (required) */ 4659 bool enabled = false; 4660 CFGLDRQueryBool (adapterNode, "enabled", &enabled); 4661 /* MAC address (can be null) */ 4662 Bstr macAddr; 4663 CFGLDRQueryBSTR (adapterNode, "MACAddress", macAddr.asOutParam()); 4664 /* cable (required) */ 4665 bool cableConnected; 4666 CFGLDRQueryBool (adapterNode, "cable", &cableConnected); 4667 /* line speed (defaults to 100 Mbps) */ 4668 uint32_t lineSpeed = 100000; 4669 CFGLDRQueryUInt32 (adapterNode, "speed", &lineSpeed); 4670 /* tracing (defaults to false) */ 4671 bool traceEnabled; 4672 CFGLDRQueryBool (adapterNode, "trace", &traceEnabled); 4673 Bstr traceFile; 4674 CFGLDRQueryBSTR (adapterNode, "tracefile", traceFile.asOutParam()); 4675 4676 rc = mNetworkAdapters [slot]->COMSETTER(Enabled) (enabled); 4677 CheckComRCBreakRC (rc); 4678 rc = mNetworkAdapters [slot]->COMSETTER(MACAddress) (macAddr); 4679 CheckComRCBreakRC (rc); 4680 rc = mNetworkAdapters [slot]->COMSETTER(CableConnected) (cableConnected); 4681 CheckComRCBreakRC (rc); 4682 rc = mNetworkAdapters [slot]->COMSETTER(LineSpeed) (lineSpeed); 4683 CheckComRCBreakRC (rc); 4684 rc = mNetworkAdapters [slot]->COMSETTER(TraceEnabled) (traceEnabled); 4685 CheckComRCBreakRC (rc); 4686 rc = mNetworkAdapters [slot]->COMSETTER(TraceFile) (traceFile); 4687 CheckComRCBreakRC (rc); 4688 4689 if (adapterType.compare(Bstr("Am79C970A")) == 0) 4690 mNetworkAdapters [slot]->COMSETTER(AdapterType)(NetworkAdapterType_NetworkAdapterAm79C970A); 4691 else if (adapterType.compare(Bstr("Am79C973")) == 0) 4692 mNetworkAdapters [slot]->COMSETTER(AdapterType)(NetworkAdapterType_NetworkAdapterAm79C973); 4693 #ifdef VBOX_WITH_E1000 4694 else if (adapterType.compare(Bstr("82540EM")) == 0) 4695 mNetworkAdapters [slot]->COMSETTER(AdapterType)(NetworkAdapterType_NetworkAdapter82540EM); 4696 #endif 4697 else 4698 ComAssertBreak (0, rc = E_FAIL); 4699 4700 CFGNODE attachmentNode = 0; 4701 if (CFGLDRGetChildNode (adapterNode, "NAT", 0, &attachmentNode), attachmentNode) 4243 uint32_t slot = (*it).value <uint32_t> ("slot"); 4244 AssertBreakVoid (slot < ELEMENTS (mNetworkAdapters)); 4245 4246 rc = mNetworkAdapters [slot]->loadSettings (*it); 4247 CheckComRCReturnRC (rc); 4248 } 4249 } 4250 4251 /* Serial node (optional) */ 4252 { 4253 Key serialNode = aNode.findKey ("Uart"); 4254 if (!serialNode.isNull()) 4255 { 4256 rc = S_OK; 4257 4258 Key::List ports = serialNode.keys ("Port"); 4259 for (Key::List::const_iterator it = ports.begin(); 4260 it != ports.end(); ++ it) 4702 4261 { 4703 rc = mNetworkAdapters [slot]->AttachToNAT(); 4704 CheckComRCBreakRC (rc); 4262 /* slot number (required) */ 4263 /* slot unicity is guaranteed by XML Schema */ 4264 uint32_t slot = (*it).value <uint32_t> ("slot"); 4265 AssertBreakVoid (slot < ELEMENTS (mSerialPorts)); 4266 4267 rc = mSerialPorts [slot]->loadSettings (*it); 4268 CheckComRCReturnRC (rc); 4705 4269 } 4706 else 4707 if (CFGLDRGetChildNode (adapterNode, "HostInterface", 0, &attachmentNode), attachmentNode) 4270 } 4271 } 4272 4273 /* Parallel node (optional) */ 4274 { 4275 Key parallelNode = aNode.findKey ("Lpt"); 4276 if (!parallelNode.isNull()) 4277 { 4278 rc = S_OK; 4279 4280 Key::List ports = parallelNode.keys ("Port"); 4281 for (Key::List::const_iterator it = ports.begin(); 4282 it != ports.end(); ++ it) 4708 4283 { 4709 /* Host Interface Networking */ 4710 Bstr name; 4711 CFGLDRQueryBSTR (attachmentNode, "name", name.asOutParam()); 4712 #ifdef RT_OS_WINDOWS 4713 /* @name can be empty on Win32, but not null */ 4714 ComAssertBreak (!name.isNull(), rc = E_FAIL); 4715 #endif 4716 rc = mNetworkAdapters [slot]->COMSETTER(HostInterface) (name); 4717 CheckComRCBreakRC (rc); 4718 #ifdef VBOX_WITH_UNIXY_TAP_NETWORKING 4719 Bstr tapSetupApp; 4720 CFGLDRQueryBSTR (attachmentNode, "TAPSetup", tapSetupApp.asOutParam()); 4721 Bstr tapTerminateApp; 4722 CFGLDRQueryBSTR (attachmentNode, "TAPTerminate", tapTerminateApp.asOutParam()); 4723 4724 rc = mNetworkAdapters [slot]->COMSETTER(TAPSetupApplication) (tapSetupApp); 4725 CheckComRCBreakRC (rc); 4726 rc = mNetworkAdapters [slot]->COMSETTER(TAPTerminateApplication) (tapTerminateApp); 4727 CheckComRCBreakRC (rc); 4728 #endif // VBOX_WITH_UNIXY_TAP_NETWORKING 4729 rc = mNetworkAdapters [slot]->AttachToHostInterface(); 4730 CheckComRCBreakRC (rc); 4284 /* slot number (required) */ 4285 /* slot unicity is guaranteed by XML Schema */ 4286 uint32_t slot = (*it).value <uint32_t> ("slot"); 4287 AssertBreakVoid (slot < ELEMENTS (mSerialPorts)); 4288 4289 rc = mParallelPorts [slot]->loadSettings (*it); 4290 CheckComRCReturnRC (rc); 4731 4291 } 4732 else 4733 if (CFGLDRGetChildNode(adapterNode, "InternalNetwork", 0, &attachmentNode), attachmentNode) 4734 { 4735 /* Internal Networking */ 4736 Bstr name; 4737 CFGLDRQueryBSTR (attachmentNode, "name", name.asOutParam()); 4738 ComAssertBreak (!name.isNull(), rc = E_FAIL); 4739 rc = mNetworkAdapters[slot]->AttachToInternalNetwork(); 4740 CheckComRCBreakRC (rc); 4741 rc = mNetworkAdapters[slot]->COMSETTER(InternalNetwork) (name); 4742 CheckComRCBreakRC (rc); 4743 } 4744 else 4745 { 4746 /* Adapter has no children */ 4747 rc = mNetworkAdapters [slot]->Detach(); 4748 CheckComRCBreakRC (rc); 4749 } 4750 if (attachmentNode) 4751 CFGLDRReleaseNode (attachmentNode); 4752 4753 CFGLDRReleaseNode (adapterNode); 4754 } 4755 4756 CFGLDRReleaseNode (networkNode); 4757 CheckComRCReturnRC (rc); 4758 } 4759 4760 /* Serial node (optional) */ 4761 CFGNODE serialNode = 0; 4762 CFGLDRGetChildNode (aNode, "Uart", 0, &serialNode); 4763 if (serialNode) 4764 { 4765 HRESULT rc = S_OK; 4766 unsigned cPorts = 0; 4767 CFGLDRCountChildren (serialNode, "Port", &cPorts); 4768 for (unsigned slot = 0; slot < cPorts; slot++) 4769 { 4770 rc = mSerialPorts [slot]->loadSettings (serialNode, slot); 4771 CheckComRCBreakRC (rc); 4772 } 4773 4774 CFGLDRReleaseNode (serialNode); 4775 CheckComRCReturnRC (rc); 4776 } 4777 4778 /* Parallel node (optional) */ 4779 CFGNODE parallelNode = 0; 4780 CFGLDRGetChildNode (aNode, "Lpt", 0, ¶llelNode); 4781 if (parallelNode) 4782 { 4783 HRESULT rc = S_OK; 4784 unsigned cPorts = 0; 4785 CFGLDRCountChildren (parallelNode, "Port", &cPorts); 4786 for (unsigned slot = 0; slot < cPorts; slot++) 4787 { 4788 rc = mParallelPorts [slot]->loadSettings (parallelNode, slot); 4789 CheckComRCBreakRC (rc); 4790 } 4791 4792 CFGLDRReleaseNode (parallelNode); 4793 CheckComRCReturnRC (rc); 4794 } 4795 4796 /* AudioAdapter node (required) */ 4797 /// @todo (dmik) move the code to AudioAdapter 4798 { 4799 CFGNODE audioAdapterNode = 0; 4800 CFGLDRGetChildNode (aNode, "AudioAdapter", 0, &audioAdapterNode); 4801 ComAssertRet (audioAdapterNode, E_FAIL); 4802 4803 /* is the adapter enabled? */ 4804 bool enabled = false; 4805 CFGLDRQueryBool (audioAdapterNode, "enabled", &enabled); 4806 mAudioAdapter->COMSETTER(Enabled) (enabled); 4807 /* now check the audio driver */ 4808 Bstr driver; 4809 CFGLDRQueryBSTR (audioAdapterNode, "driver", driver.asOutParam()); 4810 AudioDriverType_T audioDriver; 4811 audioDriver = AudioDriverType_NullAudioDriver; 4812 if (driver == L"null") 4813 ; /* Null has been set above */ 4814 #ifdef RT_OS_WINDOWS 4815 else if (driver == L"winmm") 4816 #ifdef VBOX_WITH_WINMM 4817 audioDriver = AudioDriverType_WINMMAudioDriver; 4818 #else 4819 /* fall back to dsound */ 4820 audioDriver = AudioDriverType_DSOUNDAudioDriver; 4821 #endif 4822 else if (driver == L"dsound") 4823 audioDriver = AudioDriverType_DSOUNDAudioDriver; 4824 #endif // RT_OS_WINDOWS 4825 #ifdef RT_OS_LINUX 4826 else if (driver == L"oss") 4827 audioDriver = AudioDriverType_OSSAudioDriver; 4828 else if (driver == L"alsa") 4829 # ifdef VBOX_WITH_ALSA 4830 audioDriver = AudioDriverType_ALSAAudioDriver; 4831 # else 4832 /* fall back to OSS */ 4833 audioDriver = AudioDriverType_OSSAudioDriver; 4834 # endif 4835 else if (driver == L"pulse") 4836 # ifdef VBOX_WITH_PULSE 4837 audioDriver = AudioDriverType_PulseAudioDriver; 4838 # else 4839 /* fall back to OSS */ 4840 audioDriver = AudioDriverType_OSSAudioDriver; 4841 # endif 4842 #endif // RT_OS_LINUX 4843 #ifdef RT_OS_DARWIN 4844 else if (driver == L"coreaudio") 4845 audioDriver = AudioDriverType_CoreAudioDriver; 4846 #endif 4847 #ifdef RT_OS_OS2 4848 else if (driver == L"mmpm") 4849 audioDriver = AudioDriverType_MMPMAudioDriver; 4850 #endif 4851 else 4852 AssertMsgFailed (("Invalid driver: %ls\n", driver.raw())); 4853 4854 HRESULT rc = mAudioAdapter->COMSETTER(AudioDriver) (audioDriver); 4855 4856 CFGLDRReleaseNode (audioAdapterNode); 4857 CheckComRCReturnRC (rc); 4858 } 4292 } 4293 } 4294 4295 /* AudioAdapter */ 4296 rc = mAudioAdapter->loadSettings (aNode); 4297 CheckComRCReturnRC (rc); 4859 4298 4860 4299 /* Shared folders (optional) */ 4861 4300 /// @todo (dmik) make required on next format change! 4862 do 4863 { 4864 CFGNODE sharedFoldersNode = 0; 4865 CFGLDRGetChildNode (aNode, "SharedFolders", 0, &sharedFoldersNode); 4866 4867 if (!sharedFoldersNode) 4868 break; 4869 4870 HRESULT rc = S_OK; 4871 4872 unsigned cFolders = 0; 4873 CFGLDRCountChildren (sharedFoldersNode, "SharedFolder", &cFolders); 4874 4875 for (unsigned i = 0; i < cFolders; i++) 4876 { 4877 CFGNODE folderNode = 0; 4878 CFGLDRGetChildNode (sharedFoldersNode, "SharedFolder", i, &folderNode); 4879 ComAssertBreak (folderNode, rc = E_FAIL); 4880 4881 // folder logical name (required) 4882 Bstr name; 4883 CFGLDRQueryBSTR (folderNode, "name", name.asOutParam()); 4884 4885 // folder host path (required) 4886 Bstr hostPath; 4887 CFGLDRQueryBSTR (folderNode, "hostPath", hostPath.asOutParam()); 4888 4889 rc = CreateSharedFolder (name, hostPath); 4890 CheckComRCBreakRC (rc); 4891 4892 CFGLDRReleaseNode (folderNode); 4893 } 4894 4895 CFGLDRReleaseNode (sharedFoldersNode); 4896 CheckComRCReturnRC (rc); 4897 } 4898 while (0); 4301 { 4302 Key sharedFoldersNode = aNode.findKey ("SharedFolders"); 4303 if (!sharedFoldersNode.isNull()) 4304 { 4305 rc = S_OK; 4306 4307 Key::List folders = sharedFoldersNode.keys ("SharedFolder"); 4308 for (Key::List::const_iterator it = folders.begin(); 4309 it != folders.end(); ++ it) 4310 { 4311 /* folder logical name (required) */ 4312 Bstr name = (*it).stringValue ("name"); 4313 /* folder host path (required) */ 4314 Bstr hostPath = (*it).stringValue ("hostPath"); 4315 4316 rc = CreateSharedFolder (name, hostPath); 4317 CheckComRCReturnRC (rc); 4318 } 4319 } 4320 } 4899 4321 4900 4322 /* Clipboard node (currently not required) */ 4901 4323 /// @todo (dmik) make required on next format change! 4902 4324 { 4903 /* default value in case the node is not there */4325 /* default value in case if the node is not there */ 4904 4326 mHWData->mClipboardMode = ClipboardMode_ClipDisabled; 4905 4327 4906 CFGNODE clipNode = 0; 4907 CFGLDRGetChildNode (aNode, "Clipboard", 0, &clipNode); 4908 if (clipNode) 4909 { 4910 Bstr mode; 4911 CFGLDRQueryBSTR (clipNode, "mode", mode.asOutParam()); 4912 if (mode == L"Disabled") 4328 Key clipNode = aNode.findKey ("Clipboard"); 4329 if (!clipNode.isNull()) 4330 { 4331 const char *mode = clipNode.stringValue ("mode"); 4332 if (strcmp (mode, "Disabled") == 0) 4913 4333 mHWData->mClipboardMode = ClipboardMode_ClipDisabled; 4914 else if ( mode == L"HostToGuest")4334 else if (strcmp (mode, "HostToGuest") == 0) 4915 4335 mHWData->mClipboardMode = ClipboardMode_ClipHostToGuest; 4916 else if ( mode == L"GuestToHost")4336 else if (strcmp (mode, "GuestToHost") == 0) 4917 4337 mHWData->mClipboardMode = ClipboardMode_ClipGuestToHost; 4918 else if ( mode == L"Bidirectional")4338 else if (strcmp (mode, "Bidirectional") == 0) 4919 4339 mHWData->mClipboardMode = ClipboardMode_ClipBidirectional; 4920 4340 else 4921 AssertMsgFailed (("%ls clipboard mode is invalid\n", mode.raw())); 4922 CFGLDRReleaseNode (clipNode); 4341 AssertMsgFailed (("Invalid clipboard mode '%s'\n", mode)); 4923 4342 } 4924 4343 } 4925 4344 4926 4345 /* Guest node (optional) */ 4927 /// @todo (dmik) make required on next format change! 4928 { 4929 CFGNODE guestNode = 0; 4930 CFGLDRGetChildNode (aNode, "Guest", 0, &guestNode); 4931 if (guestNode) 4932 { 4933 uint32_t memoryBalloonSize = 0; 4934 CFGLDRQueryUInt32 (guestNode, "MemoryBalloonSize", 4935 &memoryBalloonSize); 4936 mHWData->mMemoryBalloonSize = memoryBalloonSize; 4937 4938 uint32_t statisticsUpdateInterval = 0; 4939 CFGLDRQueryUInt32 (guestNode, "StatisticsUpdateInterval", 4940 &statisticsUpdateInterval); 4941 mHWData->mStatisticsUpdateInterval = statisticsUpdateInterval; 4942 4943 CFGLDRReleaseNode (guestNode); 4944 } 4945 } 4946 4947 return S_OK; 4346 /// @todo (dmik) make required on next format change and change attribute 4347 /// naming! 4348 { 4349 Key guestNode = aNode.findKey ("Guest"); 4350 if (!guestNode.isNull()) 4351 { 4352 /* optional, defaults to 0) */ 4353 mHWData->mMemoryBalloonSize = 4354 guestNode.value <ULONG> ("MemoryBalloonSize"); 4355 /* optional, defaults to 0) */ 4356 mHWData->mStatisticsUpdateInterval = 4357 guestNode.value <ULONG> ("StatisticsUpdateInterval"); 4358 } 4359 } 4360 4361 AssertComRC (rc); 4362 return rc; 4948 4363 } 4949 4364 4950 4365 /** 4951 * @param aNode <HardDiskAttachments> node 4366 * @param aNode <HardDiskAttachments> node. 4952 4367 * @param aRegistered true when the machine is being loaded on VirtualBox 4953 4368 * startup, or when a snapshot is being loaded (wchich … … 4955 4370 * @param aSnapshotId pointer to the snapshot ID if this is a snapshot machine 4956 4371 */ 4957 HRESULT Machine::loadHardDisks ( CFGNODEaNode, bool aRegistered,4372 HRESULT Machine::loadHardDisks (const settings::Key &aNode, bool aRegistered, 4958 4373 const Guid *aSnapshotId /* = NULL */) 4959 4374 { 4960 AssertReturn (aNode, E_INVALIDARG); 4375 using namespace settings; 4376 4377 AssertReturn (!aNode.isNull(), E_INVALIDARG); 4961 4378 AssertReturn ((mType == IsMachine && aSnapshotId == NULL) || 4962 4379 (mType == IsSnapshotMachine && aSnapshotId != NULL), E_FAIL); … … 4964 4381 HRESULT rc = S_OK; 4965 4382 4966 unsigned cbDisks = 0; 4967 CFGLDRCountChildren (aNode, "HardDiskAttachment", &cbDisks); 4968 4969 if (!aRegistered && cbDisks > 0) 4383 Key::List children = aNode.keys ("HardDiskAttachment"); 4384 4385 if (!aRegistered && children.size() > 0) 4970 4386 { 4971 4387 /* when the machine is being loaded (opened) from a file, it cannot … … 4976 4392 tr ("Unregistered machine '%ls' cannot have hard disks attached " 4977 4393 "(found %d hard disk attachments)"), 4978 mUserData->mName.raw(), cbDisks); 4979 } 4980 4981 for (unsigned i = 0; i < cbDisks && SUCCEEDED (rc); ++ i) 4982 { 4983 CFGNODE hdNode; 4984 CFGLDRGetChildNode (aNode, "HardDiskAttachment", i, &hdNode); 4985 ComAssertRet (hdNode, E_FAIL); 4986 4987 do 4988 { 4989 /* hardDisk uuid (required) */ 4990 Guid uuid; 4991 CFGLDRQueryUUID (hdNode, "hardDisk", uuid.ptr()); 4992 /* bus (controller) type (required) */ 4993 Bstr bus; 4994 CFGLDRQueryBSTR (hdNode, "bus", bus.asOutParam()); 4995 /* device (required) */ 4996 Bstr device; 4997 CFGLDRQueryBSTR (hdNode, "device", device.asOutParam()); 4998 4999 /* find a hard disk by UUID */ 5000 ComObjPtr <HardDisk> hd; 5001 rc = mParent->getHardDisk (uuid, hd); 5002 if (FAILED (rc)) 5003 break; 5004 5005 AutoLock hdLock (hd); 5006 5007 if (!hd->machineId().isEmpty()) 5008 { 5009 rc = setError (E_FAIL, 5010 tr ("Hard disk '%ls' with UUID {%s} is already " 5011 "attached to a machine with UUID {%s} (see '%ls')"), 5012 hd->toString().raw(), uuid.toString().raw(), 5013 hd->machineId().toString().raw(), 5014 mData->mConfigFileFull.raw()); 5015 break; 5016 } 5017 5018 if (hd->type() == HardDiskType_ImmutableHardDisk) 5019 { 5020 rc = setError (E_FAIL, 5021 tr ("Immutable hard disk '%ls' with UUID {%s} cannot be " 5022 "directly attached to a machine (see '%ls')"), 5023 hd->toString().raw(), uuid.toString().raw(), 5024 mData->mConfigFileFull.raw()); 5025 break; 5026 } 5027 5028 /* attach the device */ 5029 DiskControllerType_T ctl = DiskControllerType_InvalidController; 5030 LONG dev = -1; 5031 5032 if (bus == L"ide0") 5033 { 5034 ctl = DiskControllerType_IDE0Controller; 5035 if (device == L"master") 5036 dev = 0; 5037 else if (device == L"slave") 5038 dev = 1; 5039 else 5040 ComAssertMsgFailedBreak (("Invalid device: %ls\n", device.raw()), 5041 rc = E_FAIL); 5042 } 5043 else if (bus == L"ide1") 5044 { 5045 ctl = DiskControllerType_IDE1Controller; 5046 if (device == L"master") 5047 rc = setError (E_FAIL, tr("Could not attach a disk as a master " 5048 "device on the secondary controller")); 5049 else if (device == L"slave") 5050 dev = 1; 5051 else 5052 ComAssertMsgFailedBreak (("Invalid device: %ls\n", device.raw()), 5053 rc = E_FAIL); 5054 } 4394 mUserData->mName.raw(), children.size()); 4395 } 4396 4397 4398 for (Key::List::const_iterator it = children.begin(); 4399 it != children.end(); ++ it) 4400 { 4401 /* hardDisk uuid (required) */ 4402 Guid uuid = (*it).value <Guid> ("hardDisk"); 4403 /* bus (controller) type (required) */ 4404 const char *bus = (*it).stringValue ("bus"); 4405 /* device (required) */ 4406 const char *device = (*it).stringValue ("device"); 4407 4408 /* find a hard disk by UUID */ 4409 ComObjPtr <HardDisk> hd; 4410 rc = mParent->getHardDisk (uuid, hd); 4411 CheckComRCReturnRC (rc); 4412 4413 AutoLock hdLock (hd); 4414 4415 if (!hd->machineId().isEmpty()) 4416 { 4417 return setError (E_FAIL, 4418 tr ("Hard disk '%ls' with UUID {%s} is already " 4419 "attached to a machine with UUID {%s} (see '%ls')"), 4420 hd->toString().raw(), uuid.toString().raw(), 4421 hd->machineId().toString().raw(), 4422 mData->mConfigFileFull.raw()); 4423 } 4424 4425 if (hd->type() == HardDiskType_ImmutableHardDisk) 4426 { 4427 return setError (E_FAIL, 4428 tr ("Immutable hard disk '%ls' with UUID {%s} cannot be " 4429 "directly attached to a machine (see '%ls')"), 4430 hd->toString().raw(), uuid.toString().raw(), 4431 mData->mConfigFileFull.raw()); 4432 } 4433 4434 /* attach the device */ 4435 DiskControllerType_T ctl = DiskControllerType_InvalidController; 4436 LONG dev = -1; 4437 4438 if (strcmp (bus, "ide0") == 0) 4439 { 4440 ctl = DiskControllerType_IDE0Controller; 4441 if (strcmp (device, "master") == 0) 4442 dev = 0; 4443 else if (strcmp (device, "slave") == 0) 4444 dev = 1; 5055 4445 else 5056 ComAssertMsgFailedBreak (("Invalid bus: %ls\n", bus.raw()), 5057 rc = E_FAIL); 5058 5059 ComObjPtr <HardDiskAttachment> attachment; 5060 attachment.createObject(); 5061 rc = attachment->init (hd, ctl, dev, false /* aDirty */); 5062 if (FAILED (rc)) 5063 break; 5064 5065 /* associate the hard disk with this machine */ 5066 hd->setMachineId (mData->mUuid); 5067 5068 /* associate the hard disk with the given snapshot ID */ 5069 if (mType == IsSnapshotMachine) 5070 hd->setSnapshotId (*aSnapshotId); 5071 5072 mHDData->mHDAttachments.push_back (attachment); 5073 } 5074 while (0); 5075 5076 CFGLDRReleaseNode (hdNode); 5077 } 5078 5079 return rc; 5080 } 5081 5082 /** 5083 * Creates a config loader and loads the settings file. 5084 * 5085 * @param aIsNew |true| if a newly created settings file is to be opened 5086 * (must be the case only when called from #saveSettings()) 5087 * 5088 * @note 5089 * XML Schema errors are not detected by this method because 5090 * it assumes that it will load settings from an exclusively locked 5091 * file (using a file handle) that was previously validated when opened 5092 * for the first time. Thus, this method should be used only when 5093 * it's necessary to modify (save) the settings file. 5094 * 5095 * @note The object must be locked at least for reading before calling 5096 * this method. 5097 */ 5098 HRESULT Machine::openConfigLoader (CFGHANDLE *aLoader, bool aIsNew /* = false */) 5099 { 5100 AssertReturn (aLoader, E_FAIL); 5101 5102 /* The settings file must be created and locked at this point */ 5103 ComAssertRet (isConfigLocked(), E_FAIL); 5104 5105 /* load the config file */ 5106 int vrc = CFGLDRLoad (aLoader, 5107 Utf8Str (mData->mConfigFileFull), mData->mHandleCfgFile, 5108 aIsNew ? NULL : XmlSchemaNS, true, cfgLdrEntityResolver, 5109 NULL); 5110 ComAssertRCRet (vrc, E_FAIL); 4446 ComAssertMsgFailedRet (("Invalid device '%s'\n", device), 4447 E_FAIL); 4448 } 4449 else if (strcmp (bus, "ide1") == 0) 4450 { 4451 ctl = DiskControllerType_IDE1Controller; 4452 if (strcmp (device, "master") == 0) 4453 rc = setError (E_FAIL, tr("Could not attach a disk as a master " 4454 "device on the secondary controller")); 4455 else if (strcmp (device, "slave") == 0) 4456 dev = 1; 4457 else 4458 ComAssertMsgFailedRet (("Invalid device '%s'\n", device), 4459 E_FAIL); 4460 } 4461 else 4462 ComAssertMsgFailedRet (("Invalid bus '%s'\n", bus), 4463 E_FAIL); 4464 4465 ComObjPtr <HardDiskAttachment> attachment; 4466 attachment.createObject(); 4467 rc = attachment->init (hd, ctl, dev, false /* aDirty */); 4468 CheckComRCBreakRC (rc); 4469 4470 /* associate the hard disk with this machine */ 4471 hd->setMachineId (mData->mUuid); 4472 4473 /* associate the hard disk with the given snapshot ID */ 4474 if (mType == IsSnapshotMachine) 4475 hd->setSnapshotId (*aSnapshotId); 4476 4477 mHDData->mHDAttachments.push_back (attachment); 4478 } 5111 4479 5112 4480 return S_OK; 5113 }5114 5115 /**5116 * Closes the config loader previously created by #openConfigLoader().5117 * If \a aSaveBeforeClose is true, then the config is saved to the settings file5118 * before closing. If saving fails, a proper error message is set.5119 *5120 * @param aSaveBeforeClose whether to save the config before closing or not5121 */5122 HRESULT Machine::closeConfigLoader (CFGHANDLE aLoader, bool aSaveBeforeClose)5123 {5124 HRESULT rc = S_OK;5125 5126 if (aSaveBeforeClose)5127 {5128 char *loaderError = NULL;5129 int vrc = CFGLDRSave (aLoader, &loaderError);5130 if (VBOX_FAILURE (vrc))5131 {5132 rc = setError (E_FAIL,5133 tr ("Could not save the settings file '%ls' (%Vrc)%s%s"),5134 mData->mConfigFileFull.raw(), vrc,5135 loaderError ? ".\n" : "", loaderError ? loaderError : "");5136 if (loaderError)5137 RTMemTmpFree (loaderError);5138 }5139 }5140 5141 CFGLDRFree (aLoader);5142 5143 return rc;5144 4481 } 5145 4482 … … 5153 4490 * \a aSnapshotNode are set to 0. 5154 4491 * 5155 * @param aSnapshot snapshot to search for5156 * @param aMachineNode <Machine> node to start from 4492 * @param aSnapshot Snapshot to search for. 4493 * @param aMachineNode <Machine> node to start from. 5157 4494 * @param aSnapshotsNode <Snapshots> node containing the found <Snapshot> node 5158 * (may be NULL if the caller is not interested) 5159 * @param aSnapshotNode found <Snapshot> node4495 * (may be NULL if the caller is not interested). 4496 * @param aSnapshotNode Found <Snapshot> node. 5160 4497 */ 5161 HRESULT Machine::findSnapshotNode (Snapshot *aSnapshot, CFGNODE aMachineNode, 5162 CFGNODE *aSnapshotsNode, CFGNODE *aSnapshotNode) 5163 { 5164 AssertReturn (aSnapshot && aMachineNode && aSnapshotNode, E_FAIL); 4498 HRESULT Machine::findSnapshotNode (Snapshot *aSnapshot, settings::Key &aMachineNode, 4499 settings::Key *aSnapshotsNode, 4500 settings::Key *aSnapshotNode) 4501 { 4502 using namespace settings; 4503 4504 AssertReturn (aSnapshot && !aMachineNode.isNull() 4505 && aSnapshotNode != NULL, E_FAIL); 5165 4506 5166 4507 if (aSnapshotsNode) 5167 *aSnapshotsNode = 0;5168 *aSnapshotNode = 0;5169 5170 // build the full uuid path (from the fistparent to the given snapshot)4508 aSnapshotsNode->setNull(); 4509 aSnapshotNode->setNull(); 4510 4511 // build the full uuid path (from the top parent to the given snapshot) 5171 4512 std::list <Guid> path; 5172 4513 { … … 5179 4520 } 5180 4521 5181 CFGNODEsnapshotsNode = aMachineNode;5182 CFGNODE snapshotNode = 0;4522 Key snapshotsNode = aMachineNode; 4523 Key snapshotNode; 5183 4524 5184 4525 for (std::list <Guid>::const_iterator it = path.begin(); … … 5186 4527 ++ it) 5187 4528 { 5188 if (snapshotNode) 5189 { 5190 // proceed to the nested <Snapshots> node 5191 Assert (snapshotsNode); 5192 if (snapshotsNode != aMachineNode) 5193 { 5194 CFGLDRReleaseNode (snapshotsNode); 5195 snapshotsNode = 0; 5196 } 5197 CFGLDRGetChildNode (snapshotNode, "Snapshots", 0, &snapshotsNode); 5198 CFGLDRReleaseNode (snapshotNode); 5199 snapshotNode = 0; 5200 } 5201 5202 AssertReturn (snapshotsNode, E_FAIL); 5203 5204 unsigned count = 0, i = 0; 5205 CFGLDRCountChildren (snapshotsNode, "Snapshot", &count); 5206 for (; i < count; ++ i) 5207 { 5208 snapshotNode = 0; 5209 CFGLDRGetChildNode (snapshotsNode, "Snapshot", i, &snapshotNode); 5210 Guid id; 5211 CFGLDRQueryUUID (snapshotNode, "uuid", id.ptr()); 4529 if (!snapshotNode.isNull()) 4530 { 4531 /* proceed to the nested <Snapshots> node */ 4532 snapshotsNode = snapshotNode.key ("Snapshots"); 4533 snapshotNode.setNull(); 4534 } 4535 4536 AssertReturn (!snapshotsNode.isNull(), E_FAIL); 4537 4538 Key::List children = snapshotsNode.keys ("Snapshot"); 4539 for (Key::List::const_iterator ch = children.begin(); 4540 ch != children.end(); 4541 ++ ch) 4542 { 4543 Guid id = (*ch).value <Guid> ("uuid"); 5212 4544 if (id == (*it)) 5213 4545 { 5214 // we keep (don't release) snapshotNode and snapshotsNode 4546 /* pass over to the outer loop */ 4547 snapshotNode = *ch; 5215 4548 break; 5216 4549 } 5217 CFGLDRReleaseNode (snapshotNode); 5218 snapshotNode = 0; 5219 } 5220 5221 if (i == count) 5222 { 5223 // the next uuid is not found, no need to continue... 5224 AssertFailed(); 5225 if (snapshotsNode != aMachineNode) 5226 { 5227 CFGLDRReleaseNode (snapshotsNode); 5228 snapshotsNode = 0; 5229 } 5230 break; 5231 } 4550 } 4551 4552 if (!snapshotNode.isNull()) 4553 continue; 4554 4555 /* the next uuid is not found, no need to continue... */ 4556 AssertFailedBreakVoid(); 5232 4557 } 5233 4558 5234 4559 // we must always succesfully find the node 5235 AssertReturn ( snapshotNode, E_FAIL);5236 AssertReturn ( snapshotsNode, E_FAIL);5237 5238 if (aSnapshotsNode )5239 *aSnapshotsNode = snapshotsNode != aMachineNode ? snapshotsNode : 0;4560 AssertReturn (!snapshotNode.isNull(), E_FAIL); 4561 AssertReturn (!snapshotsNode.isNull(), E_FAIL); 4562 4563 if (aSnapshotsNode && (snapshotsNode != aMachineNode)) 4564 *aSnapshotsNode = snapshotsNode; 5240 4565 *aSnapshotNode = snapshotNode; 5241 4566 … … 5382 4707 * if this is a new machine. 5383 4708 * 5384 * @note Must be never called directly .4709 * @note Must be never called directly but only from #saveSettings(). 5385 4710 * 5386 4711 * @param aRenamed receives |true| if the name was changed and the settings … … 5391 4716 HRESULT Machine::prepareSaveSettings (bool &aRenamed, bool &aNew) 5392 4717 { 4718 /* Note: tecnhically, mParent needs to be locked only when the machine is 4719 * registered (see prepareSaveSettings() for details) but we don't 4720 * currently differentiate it in callers of saveSettings() so we don't 4721 * make difference here too. */ 4722 AssertReturn (mParent->isLockedOnCurrentThread(), E_FAIL); 4723 AssertReturn (isLockedOnCurrentThread(), E_FAIL); 4724 5393 4725 HRESULT rc = S_OK; 5394 4726 … … 5573 4905 } 5574 4906 5575 /* Note: open flags must correlate dwith RTFileOpen() in lockConfig() */4907 /* Note: open flags must correlate with RTFileOpen() in lockConfig() */ 5576 4908 path = Utf8Str (mData->mConfigFileFull); 5577 4909 vrc = RTFileOpen (&mData->mHandleCfgFile, path, … … 5601 4933 * 5602 4934 * @param aMarkCurStateAsModified 5603 * if true (default), mData->mCurrentStateModified will be set to4935 * If true (default), mData->mCurrentStateModified will be set to 5604 4936 * what #isReallyModified() returns prior to saving settings to a file, 5605 4937 * otherwise the current value of mData->mCurrentStateModified will be 5606 4938 * saved. 5607 4939 * @param aInformCallbacksAnyway 5608 * if true, callbacks will be informed even if #isReallyModified()4940 * If true, callbacks will be informed even if #isReallyModified() 5609 4941 * returns false. This is necessary for cases when we change machine data 5610 4942 * diectly, not through the backup()/commit() mechanism. 5611 4943 * 5612 * @note Locks mParent (only in some cases, and only when #isConfigLocked() is 5613 * |TRUE|, see the #prepareSaveSettings() code for details) + 5614 * this object + children for writing. 4944 * @note Must be called from under mParent write lock (sometimes needed by 4945 * #prepareSaveSettings()) and this object's write lock. Locks children for 4946 * writing. There is one exception when mParent is unused and therefore may 4947 * be left unlocked: if this machine is an unregistered one. 5615 4948 */ 5616 4949 HRESULT Machine::saveSettings (bool aMarkCurStateAsModified /* = true */, … … 5618 4951 { 5619 4952 LogFlowThisFuncEnter(); 4953 4954 /* Note: tecnhically, mParent needs to be locked only when the machine is 4955 * registered (see prepareSaveSettings() for details) but we don't 4956 * currently differentiate it in callers of saveSettings() so we don't 4957 * make difference here too. */ 4958 AssertReturn (mParent->isLockedOnCurrentThread(), E_FAIL); 4959 AssertReturn (isLockedOnCurrentThread(), E_FAIL); 5620 4960 5621 4961 /// @todo (dmik) I guess we should lock all our child objects here … … 5658 4998 CheckComRCReturnRC (rc); 5659 4999 5660 /* then, open the settings file */ 5661 CFGHANDLE configLoader = 0; 5662 rc = openConfigLoader (&configLoader, isNew); 5663 CheckComRCReturnRC (rc); 5664 5665 /* save all snapshots when the machine name was changed since 5666 * it may affect saved state file paths for online snapshots (see 5667 * #openConfigLoader() for details) */ 5668 bool updateAllSnapshots = isRenamed; 5669 5670 /* commit before saving, since it may change settings 5671 * (for example, perform fixup of lazy hard disk changes) */ 5672 rc = commit(); 5673 if (FAILED (rc)) 5674 { 5675 closeConfigLoader (configLoader, false /* aSaveBeforeClose */); 5676 return rc; 5677 } 5678 5679 /* include hard disk changes to the modified flag */ 5680 wasModified |= mHDData->mHDAttachmentsChanged; 5681 if (aMarkCurStateAsModified) 5682 mData->mCurrentStateModified |= BOOL (mHDData->mHDAttachmentsChanged); 5683 5684 5685 CFGNODE machineNode = 0; 5686 /* create if not exists */ 5687 CFGLDRCreateNode (configLoader, "VirtualBox/Machine", &machineNode); 5688 5689 do 5690 { 5691 ComAssertBreak (machineNode, rc = E_FAIL); 5000 try 5001 { 5002 using namespace settings; 5003 5004 File file (File::ReadWrite, mData->mHandleCfgFile, 5005 Utf8Str (mData->mConfigFileFull)); 5006 XmlTreeBackend tree; 5007 5008 /* The newly created settings file is incomplete therefore we turn off 5009 * validation. The rest is like in loadSettingsTree_ForUpdate().*/ 5010 rc = VirtualBox::loadSettingsTree (tree, file, 5011 !isNew /* aValidate */, 5012 false /* aCatchLoadErrors */, 5013 false /* aAddDefaults */); 5014 CheckComRCThrowRC (rc); 5015 5016 5017 /* ask to save all snapshots when the machine name was changed since 5018 * it may affect saved state file paths for online snapshots (see 5019 * #openConfigLoader() for details) */ 5020 bool updateAllSnapshots = isRenamed; 5021 5022 /* commit before saving, since it may change settings 5023 * (for example, perform fixup of lazy hard disk changes) */ 5024 rc = commit(); 5025 CheckComRCReturnRC (rc); 5026 5027 /* include hard disk changes to the modified flag */ 5028 wasModified |= mHDData->mHDAttachmentsChanged; 5029 if (aMarkCurStateAsModified) 5030 mData->mCurrentStateModified |= BOOL (mHDData->mHDAttachmentsChanged); 5031 5032 Key machineNode = tree.rootKey().createKey ("Machine"); 5692 5033 5693 5034 /* uuid (required) */ 5694 Assert ( mData->mUuid);5695 CFGLDRSetUUID (machineNode, "uuid", mData->mUuid.raw());5035 Assert (!mData->mUuid.isEmpty()); 5036 machineNode.setValue <Guid> ("uuid", mData->mUuid); 5696 5037 5697 5038 /* name (required) */ 5698 5039 Assert (!mUserData->mName.isEmpty()); 5699 CFGLDRSetBSTR (machineNode,"name", mUserData->mName);5040 machineNode.setValue <Bstr> ("name", mUserData->mName); 5700 5041 5701 5042 /* nameSync (optional, default is true) */ 5702 if (!mUserData->mNameSync) 5703 CFGLDRSetBool (machineNode, "nameSync", false); 5704 else 5705 CFGLDRDeleteAttribute (machineNode, "nameSync"); 5043 machineNode.setValueOr <bool> ("nameSync", !!mUserData->mNameSync, true); 5706 5044 5707 5045 /* Description node (optional) */ 5708 5046 if (!mUserData->mDescription.isNull()) 5709 5047 { 5710 CFGNODE descNode = 0; 5711 CFGLDRCreateChildNode (machineNode, "Description", &descNode); 5712 Assert (descNode); 5713 CFGLDRSetBSTR (descNode, NULL, mUserData->mDescription); 5714 CFGLDRReleaseNode (descNode); 5048 Key descNode = machineNode.createKey ("Description"); 5049 descNode.setKeyValue <Bstr> (mUserData->mDescription); 5715 5050 } 5716 5051 else 5717 5052 { 5718 CFGNODE descNode = 0; 5719 CFGLDRGetChildNode (machineNode, "Description", 0, &descNode); 5720 if (descNode) 5721 CFGLDRDeleteNode (descNode); 5053 Key descNode = machineNode.findKey ("Description"); 5054 if (!descNode.isNull()) 5055 descNode.zap(); 5722 5056 } 5723 5057 5724 5058 /* OSType (required) */ 5725 { 5726 CFGLDRSetBSTR (machineNode, "OSType", mUserData->mOSTypeId); 5727 } 5059 machineNode.setValue <Bstr> ("OSType", mUserData->mOSTypeId); 5728 5060 5729 5061 /* stateFile (optional) */ … … 5734 5066 Utf8Str stateFilePath = mSSData->mStateFilePath; 5735 5067 calculateRelativePath (stateFilePath, stateFilePath); 5736 CFGLDRSetString (machineNode,"stateFile", stateFilePath);5068 machineNode.setStringValue ("stateFile", stateFilePath); 5737 5069 } 5738 5070 else 5739 5071 { 5740 5072 Assert (mSSData->mStateFilePath.isNull()); 5741 CFGLDRDeleteAttribute (machineNode,"stateFile");5073 machineNode.zapValue ("stateFile"); 5742 5074 } 5743 5075 … … 5746 5078 { 5747 5079 Assert (!mData->mFirstSnapshot.isNull()); 5748 CFGLDRSetUUID (machineNode,"currentSnapshot",5749 mData->mCurrentSnapshot->data().mId);5080 machineNode.setValue <Guid> ("currentSnapshot", 5081 mData->mCurrentSnapshot->data().mId); 5750 5082 } 5751 5083 else 5752 5084 { 5753 5085 Assert (mData->mFirstSnapshot.isNull()); 5754 CFGLDRDeleteAttribute (machineNode,"currentSnapshot");5086 machineNode.zapValue ("currentSnapshot"); 5755 5087 } 5756 5088 5757 5089 /* snapshotFolder (optional) */ 5090 /// @todo use the Bstr::NullOrEmpty constant and setValueOr 5758 5091 if (!mUserData->mSnapshotFolder.isEmpty()) 5759 CFGLDRSetBSTR (machineNode,"snapshotFolder", mUserData->mSnapshotFolder);5092 machineNode.setValue <Bstr> ("snapshotFolder", mUserData->mSnapshotFolder); 5760 5093 else 5761 CFGLDRDeleteAttribute (machineNode, "snapshotFolder"); 5762 5763 /* currentStateModified (optional, default is yes) */ 5764 if (!mData->mCurrentStateModified) 5765 CFGLDRSetBool (machineNode, "currentStateModified", false); 5766 else 5767 CFGLDRDeleteAttribute (machineNode, "currentStateModified"); 5094 machineNode.zapValue ("snapshotFolder"); 5095 5096 /* currentStateModified (optional, default is true) */ 5097 machineNode.setValueOr <bool> ("currentStateModified", 5098 !!mData->mCurrentStateModified, true); 5768 5099 5769 5100 /* lastStateChange */ 5770 CFGLDRSetDateTime (machineNode, "lastStateChange", 5771 mData->mLastStateChange); 5101 machineNode.setValue <RTTIMESPEC> ("lastStateChange", 5102 mData->mLastStateChange); 5103 5104 /* set the aborted attribute when appropriate, defaults to false */ 5105 machineNode.setValueOr <bool> ("aborted", 5106 mData->mMachineState == MachineState_Aborted, 5107 false); 5772 5108 5773 5109 /* Hardware node (required) */ 5774 5110 { 5775 CFGNODE hwNode = 0;5776 CFGLDRGetChildNode (machineNode, "Hardware", 0, &hwNode);5777 5111 /* first, delete the entire node if exists */ 5778 if (hwNode) 5779 CFGLDRDeleteNode (hwNode); 5112 Key hwNode = machineNode.findKey ("Hardware"); 5113 if (!hwNode.isNull()) 5114 hwNode.zap(); 5780 5115 /* then recreate it */ 5781 hwNode = 0; 5782 CFGLDRCreateChildNode (machineNode, "Hardware", &hwNode); 5783 ComAssertBreak (hwNode, rc = E_FAIL); 5784 5116 hwNode = machineNode.createKey ("Hardware"); 5117 5785 5118 rc = saveHardware (hwNode); 5786 5787 CFGLDRReleaseNode (hwNode); 5788 if (FAILED (rc)) 5789 break; 5119 CheckComRCThrowRC (rc); 5790 5120 } 5791 5121 5792 5122 /* HardDiskAttachments node (required) */ 5793 5123 { 5794 CFGNODE hdasNode = 0;5795 CFGLDRGetChildNode (machineNode, "HardDiskAttachments", 0, &hdasNode);5796 5124 /* first, delete the entire node if exists */ 5797 if (hdasNode) 5798 CFGLDRDeleteNode (hdasNode); 5125 Key hdaNode = machineNode.findKey ("HardDiskAttachments"); 5126 if (!hdaNode.isNull()) 5127 hdaNode.zap(); 5799 5128 /* then recreate it */ 5800 hdasNode = 0; 5801 CFGLDRCreateChildNode (machineNode, "HardDiskAttachments", &hdasNode); 5802 ComAssertBreak (hdasNode, rc = E_FAIL); 5803 5804 rc = saveHardDisks (hdasNode); 5805 5806 CFGLDRReleaseNode (hdasNode); 5807 if (FAILED (rc)) 5808 break; 5129 hdaNode = machineNode.createKey ("HardDiskAttachments"); 5130 5131 rc = saveHardDisks (hdaNode); 5132 CheckComRCThrowRC (rc); 5809 5133 } 5810 5134 5811 5135 /* update all snapshots if requested */ 5812 5136 if (updateAllSnapshots) 5137 { 5813 5138 rc = saveSnapshotSettingsWorker (machineNode, NULL, 5814 5139 SaveSS_UpdateAllOp); 5815 } 5816 while (0); 5817 5818 if (machineNode) 5819 CFGLDRReleaseNode (machineNode); 5820 5821 if (SUCCEEDED (rc)) 5822 rc = closeConfigLoader (configLoader, true /* aSaveBeforeClose */); 5823 else 5824 closeConfigLoader (configLoader, false /* aSaveBeforeClose */); 5140 CheckComRCThrowRC (rc); 5141 } 5142 5143 /* save the settings on success */ 5144 rc = VirtualBox::saveSettingsTree (tree, file); 5145 CheckComRCThrowRC (rc); 5146 } 5147 catch (HRESULT err) 5148 { 5149 /* we assume that error info is set by the thrower */ 5150 rc = err; 5151 } 5152 catch (...) 5153 { 5154 rc = VirtualBox::handleUnexpectedExceptions (RT_SRC_POS); 5155 } 5825 5156 5826 5157 if (FAILED (rc)) 5827 5158 { 5828 /* 5829 * backup arbitrary data item to cause #isModified() to still return 5830 * true in case of any error 5831 */ 5159 /* backup arbitrary data item to cause #isModified() to still return 5160 * true in case of any error */ 5832 5161 mHWData.backup(); 5833 5162 } … … 5835 5164 if (wasModified || aInformCallbacksAnyway) 5836 5165 { 5837 /* 5838 * Fire the data change event, even on failure (since we've already 5839 * committed all data). This is done only for SessionMachines because 5840 * mutable Machine instances are always not registered (i.e. private 5841 * to the client process that creates them) and thus don't need to 5842 * inform callbacks. 5843 */ 5166 /* Fire the data change event, even on failure (since we've already 5167 * committed all data). This is done only for SessionMachines because 5168 * mutable Machine instances are always not registered (i.e. private 5169 * to the client process that creates them) and thus don't need to 5170 * inform callbacks. */ 5844 5171 if (mType == IsSessionMachine) 5845 5172 mParent->onMachineDataChange (mData->mUuid); … … 5876 5203 HRESULT rc = S_OK; 5877 5204 5878 /* load the config file */ 5879 CFGHANDLE configLoader = 0; 5880 rc = openConfigLoader (&configLoader); 5881 if (FAILED (rc)) 5882 return rc; 5883 5884 CFGNODE machineNode = 0; 5885 CFGLDRGetNode (configLoader, "VirtualBox/Machine", 0, &machineNode); 5886 5887 do 5888 { 5889 ComAssertBreak (machineNode, rc = E_FAIL); 5205 try 5206 { 5207 using namespace settings; 5208 5209 /* load the config file */ 5210 File file (File::ReadWrite, mData->mHandleCfgFile, 5211 Utf8Str (mData->mConfigFileFull)); 5212 XmlTreeBackend tree; 5213 5214 rc = VirtualBox::loadSettingsTree_ForUpdate (tree, file); 5215 CheckComRCReturnRC (rc); 5216 5217 Key machineNode = tree.rootKey().key ("Machine"); 5890 5218 5891 5219 rc = saveSnapshotSettingsWorker (machineNode, aSnapshot, aOpFlags); 5892 5893 CFGLDRReleaseNode (machineNode); 5894 } 5895 while (0); 5896 5897 if (SUCCEEDED (rc)) 5898 rc = closeConfigLoader (configLoader, true /* aSaveBeforeClose */); 5899 else 5900 closeConfigLoader (configLoader, false /* aSaveBeforeClose */); 5220 CheckComRCReturnRC (rc); 5221 5222 /* save settings on success */ 5223 rc = VirtualBox::saveSettingsTree (tree, file); 5224 CheckComRCReturnRC (rc); 5225 } 5226 catch (...) 5227 { 5228 rc = VirtualBox::handleUnexpectedExceptions (RT_SRC_POS); 5229 } 5901 5230 5902 5231 return rc; … … 5915 5244 * attribute of <Machine> needs to be updated. 5916 5245 * 5917 * @param aMachineNode <Machine> node in the opened settings file 5918 * @param aSnapshot Snapshot to operate on 5246 * @param aMachineNode <Machine> node in the opened settings file. 5247 * @param aSnapshot Snapshot to operate on. 5919 5248 * @param aOpFlags Operation to perform, one of SaveSS_NoOp, SaveSS_AddOp 5920 5249 * or SaveSS_UpdateAttrsOp possibly combined with … … 5924 5253 * Locks child objects. 5925 5254 */ 5926 HRESULT Machine::saveSnapshotSettingsWorker ( CFGNODEaMachineNode,5255 HRESULT Machine::saveSnapshotSettingsWorker (settings::Key &aMachineNode, 5927 5256 Snapshot *aSnapshot, int aOpFlags) 5928 5257 { 5929 AssertReturn (aMachineNode, E_FAIL); 5258 using namespace settings; 5259 5260 AssertReturn (!aMachineNode.isNull(), E_FAIL); 5930 5261 5931 5262 AssertReturn (isLockedOnCurrentThread(), E_FAIL); … … 5952 5283 { 5953 5284 /* first, delete the entire root snapshot node if it exists */ 5954 CFGNODE snapshotNode = 0; 5955 CFGLDRGetChildNode (aMachineNode, "Snapshot", 0, &snapshotNode); 5956 if (snapshotNode) 5957 CFGLDRDeleteNode (snapshotNode); 5958 5959 /* 5960 * second, if we have any snapshots left, substitute aSnapshot with 5961 * the first snapshot to recreate the whole tree, otherwise break 5962 */ 5285 Key snapshotNode = aMachineNode.findKey ("Snapshot"); 5286 if (!snapshotNode.isNull()) 5287 snapshotNode.zap(); 5288 5289 /* second, if we have any snapshots left, substitute aSnapshot 5290 * with the first snapshot to recreate the whole tree, otherwise 5291 * break */ 5963 5292 if (mData->mFirstSnapshot) 5964 5293 { … … 5975 5304 if (op == SaveSS_AddOp) 5976 5305 { 5977 CFGNODE parentNode = 0;5306 Key parentNode; 5978 5307 5979 5308 if (parent) 5980 5309 { 5981 5310 rc = findSnapshotNode (parent, aMachineNode, NULL, &parentNode); 5982 if (FAILED (rc))5983 break; 5984 ComAssertBreak ( parentNode, rc = E_FAIL);5311 CheckComRCBreakRC (rc); 5312 5313 ComAssertBreak (!parentNode.isNull(), rc = E_FAIL); 5985 5314 } 5986 5315 5987 5316 do 5988 5317 { 5989 CFGNODE snapshotsNode = 0; 5990 5991 if (parentNode) 5992 { 5993 CFGLDRCreateChildNode (parentNode, "Snapshots", &snapshotsNode); 5994 ComAssertBreak (snapshotsNode, rc = E_FAIL); 5995 } 5318 Key snapshotsNode; 5319 5320 if (!parentNode.isNull()) 5321 snapshotsNode = parentNode.createKey ("Snapshots"); 5996 5322 else 5997 5323 snapshotsNode = aMachineNode; 5998 5324 do 5999 5325 { 6000 CFGNODE snapshotNode = 0; 6001 CFGLDRAppendChildNode (snapshotsNode, "Snapshot", &snapshotNode); 6002 ComAssertBreak (snapshotNode, rc = E_FAIL); 5326 Key snapshotNode = snapshotsNode.appendKey ("Snapshot"); 6003 5327 rc = saveSnapshot (snapshotNode, aSnapshot, false /* aAttrsOnly */); 6004 CFGLDRReleaseNode (snapshotNode); 6005 6006 if (FAILED (rc)) 6007 break; 6008 6009 /* 6010 * when a new snapshot is added, this means diffs were created 6011 * for every normal/immutable hard disk of the VM, so we need to 6012 * save the current hard disk attachments 6013 */ 6014 6015 CFGNODE hdasNode = 0; 6016 CFGLDRGetChildNode (aMachineNode, "HardDiskAttachments", 0, &hdasNode); 6017 if (hdasNode) 6018 CFGLDRDeleteNode (hdasNode); 6019 CFGLDRCreateChildNode (aMachineNode, "HardDiskAttachments", &hdasNode); 6020 ComAssertBreak (hdasNode, rc = E_FAIL); 6021 6022 rc = saveHardDisks (hdasNode); 5328 CheckComRCBreakRC (rc); 5329 5330 /* when a new snapshot is added, this means diffs were created 5331 * for every normal/immutable hard disk of the VM, so we need to 5332 * save the current hard disk attachments */ 5333 5334 Key hdaNode = aMachineNode.findKey ("HardDiskAttachments"); 5335 if (!hdaNode.isNull()) 5336 hdaNode.zap(); 5337 hdaNode = aMachineNode.createKey ("HardDiskAttachments"); 5338 5339 rc = saveHardDisks (hdaNode); 5340 CheckComRCBreakRC (rc); 6023 5341 6024 5342 if (mHDData->mHDAttachments.size() != 0) 6025 5343 { 6026 /* 6027 * If we have one or more attachments then we definitely 6028 * created diffs for them and associated new diffs with 6029 * current settngs. So, since we don't use saveSettings(), 6030 * we need to inform callbacks manually. 6031 */ 5344 /* If we have one or more attachments then we definitely 5345 * created diffs for them and associated new diffs with 5346 * current settngs. So, since we don't use saveSettings(), 5347 * we need to inform callbacks manually. */ 6032 5348 if (mType == IsSessionMachine) 6033 5349 mParent->onMachineDataChange (mData->mUuid); 6034 5350 } 6035 6036 CFGLDRReleaseNode (hdasNode);6037 5351 } 6038 5352 while (0); 6039 6040 if (snapshotsNode != aMachineNode)6041 CFGLDRReleaseNode (snapshotsNode);6042 5353 } 6043 5354 while (0); 6044 5355 6045 if (parentNode)6046 CFGLDRReleaseNode (parentNode);6047 6048 5356 break; 6049 5357 } … … 6052 5360 op == SaveSS_UpdateAllOp); 6053 5361 6054 CFGNODE snapshotsNode = 0;6055 CFGNODE snapshotNode = 0;5362 Key snapshotsNode; 5363 Key snapshotNode; 6056 5364 6057 5365 if (!recreateWholeTree) … … 6059 5367 rc = findSnapshotNode (aSnapshot, aMachineNode, 6060 5368 &snapshotsNode, &snapshotNode); 6061 if (FAILED (rc)) 6062 break; 6063 ComAssertBreak (snapshotNode, rc = E_FAIL); 6064 } 6065 6066 if (!snapshotsNode) 5369 CheckComRCBreakRC (rc); 5370 } 5371 5372 if (snapshotsNode.isNull()) 6067 5373 snapshotsNode = aMachineNode; 6068 5374 6069 5375 if (op == SaveSS_UpdateAttrsOp) 6070 5376 rc = saveSnapshot (snapshotNode, aSnapshot, true /* aAttrsOnly */); 6071 else do 6072 { 6073 if (snapshotNode) 6074 { 6075 CFGLDRDeleteNode (snapshotNode); 6076 snapshotNode = 0; 6077 } 6078 CFGLDRAppendChildNode (snapshotsNode, "Snapshot", &snapshotNode); 6079 ComAssertBreak (snapshotNode, rc = E_FAIL); 5377 else 5378 { 5379 if (!snapshotNode.isNull()) 5380 snapshotNode.zap(); 5381 5382 snapshotNode = snapshotsNode.appendKey ("Snapshot"); 6080 5383 rc = saveSnapshot (snapshotNode, aSnapshot, false /* aAttrsOnly */); 6081 } 6082 while (0); 6083 6084 CFGLDRReleaseNode (snapshotNode); 6085 if (snapshotsNode != aMachineNode) 6086 CFGLDRReleaseNode (snapshotsNode); 5384 CheckComRCBreakRC (rc); 5385 } 6087 5386 } 6088 5387 while (0); … … 6094 5393 { 6095 5394 if (!mData->mCurrentSnapshot.isNull()) 6096 CFGLDRSetUUID (aMachineNode,"currentSnapshot",6097 mData->mCurrentSnapshot->data().mId);5395 aMachineNode.setValue <Guid> ("currentSnapshot", 5396 mData->mCurrentSnapshot->data().mId); 6098 5397 else 6099 CFGLDRDeleteAttribute (aMachineNode,"currentSnapshot");5398 aMachineNode.zapValue ("currentSnapshot"); 6100 5399 } 6101 5400 if (aOpFlags & SaveSS_UpdateCurStateModified) 6102 5401 { 6103 if (!mData->mCurrentStateModified) 6104 CFGLDRSetBool (aMachineNode, "currentStateModified", false); 6105 else 6106 CFGLDRDeleteAttribute (aMachineNode, "currentStateModified"); 5402 aMachineNode.setValue <bool> ("currentStateModified", true); 6107 5403 } 6108 5404 } … … 6115 5411 * It is assumed that the given node is empty (unless \a aAttrsOnly is true). 6116 5412 * 6117 * @param aNode <Snapshot> node to save the snapshot to 6118 * @param aSnapshot snapshot to save6119 * @param aAttrsOnly if true, only updatge user-changeable attrs5413 * @param aNode <Snapshot> node to save the snapshot to. 5414 * @param aSnapshot Snapshot to save. 5415 * @param aAttrsOnly If true, only updatge user-changeable attrs. 6120 5416 */ 6121 HRESULT Machine::saveSnapshot (CFGNODE aNode, Snapshot *aSnapshot, bool aAttrsOnly) 6122 { 6123 AssertReturn (aNode && aSnapshot, E_INVALIDARG); 5417 HRESULT Machine::saveSnapshot (settings::Key &aNode, Snapshot *aSnapshot, bool aAttrsOnly) 5418 { 5419 using namespace settings; 5420 5421 AssertReturn (!aNode.isNull() && aSnapshot, E_INVALIDARG); 6124 5422 AssertReturn (mType == IsMachine || mType == IsSessionMachine, E_FAIL); 6125 5423 6126 5424 /* uuid (required) */ 6127 5425 if (!aAttrsOnly) 6128 CFGLDRSetUUID (aNode,"uuid", aSnapshot->data().mId);5426 aNode.setValue <Guid> ("uuid", aSnapshot->data().mId); 6129 5427 6130 5428 /* name (required) */ 6131 CFGLDRSetBSTR (aNode,"name", aSnapshot->data().mName);5429 aNode.setValue <Bstr> ("name", aSnapshot->data().mName); 6132 5430 6133 5431 /* timeStamp (required) */ 6134 CFGLDRSetDateTime (aNode,"timeStamp", aSnapshot->data().mTimeStamp);5432 aNode.setValue <RTTIMESPEC> ("timeStamp", aSnapshot->data().mTimeStamp); 6135 5433 6136 5434 /* Description node (optional) */ 6137 5435 if (!aSnapshot->data().mDescription.isNull()) 6138 5436 { 6139 CFGNODE descNode = 0; 6140 CFGLDRCreateChildNode (aNode, "Description", &descNode); 6141 Assert (descNode); 6142 CFGLDRSetBSTR (descNode, NULL, aSnapshot->data().mDescription); 6143 CFGLDRReleaseNode (descNode); 5437 Key descNode = aNode.createKey ("Description"); 5438 descNode.setKeyValue <Bstr> (aSnapshot->data().mDescription); 6144 5439 } 6145 5440 else 6146 5441 { 6147 CFGNODE descNode = 0; 6148 CFGLDRGetChildNode (aNode, "Description", 0, &descNode); 6149 if (descNode) 6150 CFGLDRDeleteNode (descNode); 5442 Key descNode = aNode.findKey ("Description"); 5443 if (!descNode.isNull()) 5444 descNode.zap(); 6151 5445 } 6152 5446 … … 6160 5454 Utf8Str stateFilePath = aSnapshot->stateFilePath(); 6161 5455 calculateRelativePath (stateFilePath, stateFilePath); 6162 CFGLDRSetString (aNode,"stateFile", stateFilePath);5456 aNode.setStringValue ("stateFile", stateFilePath); 6163 5457 } 6164 5458 … … 6169 5463 /* save hardware */ 6170 5464 { 6171 CFGNODE hwNode = 0; 6172 CFGLDRCreateChildNode (aNode, "Hardware", &hwNode); 6173 5465 Key hwNode = aNode.createKey ("Hardware"); 6174 5466 HRESULT rc = snapshotMachine->saveHardware (hwNode); 6175 6176 CFGLDRReleaseNode (hwNode); 6177 if (FAILED (rc)) 6178 return rc; 5467 CheckComRCReturnRC (rc); 6179 5468 } 6180 5469 6181 5470 /* save hard disks */ 6182 5471 { 6183 CFGNODE hdasNode = 0; 6184 CFGLDRCreateChildNode (aNode, "HardDiskAttachments", &hdasNode); 6185 5472 Key hdasNode = aNode.createKey ("HardDiskAttachments"); 6186 5473 HRESULT rc = snapshotMachine->saveHardDisks (hdasNode); 6187 6188 CFGLDRReleaseNode (hdasNode); 6189 if (FAILED (rc)) 6190 return rc; 5474 CheckComRCReturnRC (rc); 6191 5475 } 6192 5476 } … … 6198 5482 if (aSnapshot->children().size()) 6199 5483 { 6200 CFGNODE snapshotsNode = 0; 6201 CFGLDRCreateChildNode (aNode, "Snapshots", &snapshotsNode); 5484 Key snapshotsNode = aNode.createKey ("Snapshots"); 6202 5485 6203 5486 HRESULT rc = S_OK; 6204 5487 6205 5488 for (Snapshot::SnapshotList::const_iterator it = aSnapshot->children().begin(); 6206 it != aSnapshot->children().end() && SUCCEEDED (rc);5489 it != aSnapshot->children().end(); 6207 5490 ++ it) 6208 5491 { 6209 CFGNODE snapshotNode = 0; 6210 CFGLDRCreateChildNode (snapshotsNode, "Snapshot", &snapshotNode); 6211 5492 Key snapshotNode = snapshotsNode.createKey ("Snapshot"); 6212 5493 rc = saveSnapshot (snapshotNode, (*it), aAttrsOnly); 6213 6214 CFGLDRReleaseNode (snapshotNode); 5494 CheckComRCReturnRC (rc); 6215 5495 } 6216 6217 CFGLDRReleaseNode (snapshotsNode);6218 if (FAILED (rc))6219 return rc;6220 5496 } 6221 5497 } … … 6228 5504 * It is assumed that the given node is empty. 6229 5505 * 6230 * @param aNode <Hardware> node to save the VM hardware confguration to 5506 * @param aNode <Hardware> node to save the VM hardware confguration to. 6231 5507 */ 6232 HRESULT Machine::saveHardware (CFGNODE aNode) 6233 { 6234 AssertReturn (aNode, E_INVALIDARG); 5508 HRESULT Machine::saveHardware (settings::Key &aNode) 5509 { 5510 using namespace settings; 5511 5512 AssertReturn (!aNode.isNull(), E_INVALIDARG); 6235 5513 6236 5514 HRESULT rc = S_OK; 6237 5515 6238 /* CPU */ 6239 { 6240 CFGNODE cpuNode = 0; 6241 CFGLDRCreateChildNode (aNode, "CPU", &cpuNode); 6242 CFGNODE hwVirtExNode = 0; 6243 CFGLDRCreateChildNode (cpuNode, "HardwareVirtEx", &hwVirtExNode); 5516 /* CPU (optional) */ 5517 { 5518 Key cpuNode = aNode.createKey ("CPU"); 5519 Key hwVirtExNode = cpuNode.createKey ("HardwareVirtEx"); 6244 5520 const char *value = NULL; 6245 5521 switch (mHWData->mHWVirtExEnabled) … … 6251 5527 value = "true"; 6252 5528 break; 6253 default:5529 case TriStateBool_Default: 6254 5530 value = "default"; 6255 5531 } 6256 CFGLDRSetString (hwVirtExNode, "enabled", value); 6257 CFGLDRReleaseNode (hwVirtExNode); 6258 CFGLDRReleaseNode (cpuNode); 5532 hwVirtExNode.setStringValue ("enabled", value); 6259 5533 } 6260 5534 6261 5535 /* memory (required) */ 6262 5536 { 6263 CFGNODE memoryNode = 0; 6264 CFGLDRCreateChildNode (aNode, "Memory", &memoryNode); 6265 CFGLDRSetUInt32 (memoryNode, "RAMSize", mHWData->mMemorySize); 6266 CFGLDRReleaseNode (memoryNode); 5537 Key memoryNode = aNode.createKey ("Memory"); 5538 memoryNode.setValue <ULONG> ("RAMSize", mHWData->mMemorySize); 6267 5539 } 6268 5540 6269 5541 /* boot (required) */ 6270 do 6271 { 6272 CFGNODE bootNode = 0; 6273 CFGLDRCreateChildNode (aNode, "Boot", &bootNode); 6274 6275 for (ULONG pos = 0; pos < ELEMENTS (mHWData->mBootOrder); pos ++) 5542 { 5543 Key bootNode = aNode.createKey ("Boot"); 5544 5545 for (ULONG pos = 0; pos < ELEMENTS (mHWData->mBootOrder); ++ pos) 6276 5546 { 6277 5547 const char *device = NULL; … … 6282 5552 * when loading, the default value NoDevice will remain */ 6283 5553 continue; 6284 case DeviceType_FloppyDevice: device = "Floppy"; 5554 case DeviceType_FloppyDevice: device = "Floppy"; break; 6285 5555 case DeviceType_DVDDevice: device = "DVD"; break; 6286 5556 case DeviceType_HardDiskDevice: device = "HardDisk"; break; 6287 5557 case DeviceType_NetworkDevice: device = "Network"; break; 6288 5558 default: 6289 ComAssertMsgFailedBreak (("Invalid boot device: %d\n", 6290 mHWData->mBootOrder [pos]), 6291 rc = E_FAIL); 5559 { 5560 ComAssertMsgFailedRet (("Invalid boot device: %d\n", 5561 mHWData->mBootOrder [pos]), 5562 E_FAIL); 5563 } 6292 5564 } 6293 if (FAILED (rc)) 6294 break; 6295 6296 CFGNODE orderNode = 0; 6297 CFGLDRAppendChildNode (bootNode, "Order", &orderNode); 6298 6299 CFGLDRSetUInt32 (orderNode, "position", pos + 1); 6300 CFGLDRSetString (orderNode, "device", device); 6301 6302 CFGLDRReleaseNode (orderNode); 6303 } 6304 6305 CFGLDRReleaseNode (bootNode); 6306 } 6307 while (0); 6308 6309 CheckComRCReturnRC (rc); 5565 5566 Key orderNode = bootNode.appendKey ("Order"); 5567 orderNode.setValue <ULONG> ("position", pos + 1); 5568 orderNode.setStringValue ("device", device); 5569 } 5570 } 6310 5571 6311 5572 /* display (required) */ 6312 5573 { 6313 CFGNODE displayNode = 0; 6314 CFGLDRCreateChildNode (aNode, "Display", &displayNode); 6315 CFGLDRSetUInt32 (displayNode, "VRAMSize", mHWData->mVRAMSize); 6316 CFGLDRSetUInt32 (displayNode, "MonitorCount", mHWData->mMonitorCount); 6317 CFGLDRReleaseNode (displayNode); 5574 Key displayNode = aNode.createKey ("Display"); 5575 displayNode.setValue <ULONG> ("VRAMSize", mHWData->mVRAMSize); 5576 displayNode.setValue <ULONG> ("MonitorCount", mHWData->mMonitorCount); 6318 5577 } 6319 5578 6320 5579 #ifdef VBOX_VRDP 6321 5580 /* VRDP settings (optional) */ 6322 { 6323 CFGNODE remoteDisplayNode = 0; 6324 CFGLDRCreateChildNode (aNode, "RemoteDisplay", &remoteDisplayNode); 6325 if (remoteDisplayNode) 6326 { 6327 rc = mVRDPServer->saveSettings (remoteDisplayNode); 6328 CFGLDRReleaseNode (remoteDisplayNode); 6329 CheckComRCReturnRC (rc); 6330 } 6331 } 5581 rc = mVRDPServer->saveSettings (aNode); 5582 CheckComRCReturnRC (rc); 6332 5583 #endif 6333 5584 6334 5585 /* BIOS (required) */ 6335 { 6336 CFGNODE biosNode = 0; 6337 CFGLDRCreateChildNode (aNode, "BIOS", &biosNode); 6338 { 6339 BOOL fSet; 6340 /* ACPI */ 6341 CFGNODE acpiNode = 0; 6342 CFGLDRCreateChildNode (biosNode, "ACPI", &acpiNode); 6343 mBIOSSettings->COMGETTER(ACPIEnabled)(&fSet); 6344 CFGLDRSetBool (acpiNode, "enabled", !!fSet); 6345 CFGLDRReleaseNode (acpiNode); 6346 6347 /* IOAPIC */ 6348 CFGNODE ioapicNode = 0; 6349 CFGLDRCreateChildNode (biosNode, "IOAPIC", &ioapicNode); 6350 mBIOSSettings->COMGETTER(IOAPICEnabled)(&fSet); 6351 CFGLDRSetBool (ioapicNode, "enabled", !!fSet); 6352 CFGLDRReleaseNode (ioapicNode); 6353 6354 /* BIOS logo (optional) **/ 6355 CFGNODE logoNode = 0; 6356 CFGLDRCreateChildNode (biosNode, "Logo", &logoNode); 6357 mBIOSSettings->COMGETTER(LogoFadeIn)(&fSet); 6358 CFGLDRSetBool (logoNode, "fadeIn", !!fSet); 6359 mBIOSSettings->COMGETTER(LogoFadeOut)(&fSet); 6360 CFGLDRSetBool (logoNode, "fadeOut", !!fSet); 6361 ULONG ulDisplayTime; 6362 mBIOSSettings->COMGETTER(LogoDisplayTime)(&ulDisplayTime); 6363 CFGLDRSetUInt32 (logoNode, "displayTime", ulDisplayTime); 6364 Bstr logoPath; 6365 mBIOSSettings->COMGETTER(LogoImagePath)(logoPath.asOutParam()); 6366 if (logoPath) 6367 CFGLDRSetBSTR (logoNode, "imagePath", logoPath); 6368 else 6369 CFGLDRDeleteAttribute (logoNode, "imagePath"); 6370 CFGLDRReleaseNode (logoNode); 6371 6372 /* boot menu (optional) */ 6373 CFGNODE bootMenuNode = 0; 6374 CFGLDRCreateChildNode (biosNode, "BootMenu", &bootMenuNode); 6375 BIOSBootMenuMode_T bootMenuMode; 6376 Bstr bootMenuModeStr; 6377 mBIOSSettings->COMGETTER(BootMenuMode)(&bootMenuMode); 6378 switch (bootMenuMode) 6379 { 6380 case BIOSBootMenuMode_Disabled: 6381 bootMenuModeStr = "disabled"; 6382 break; 6383 case BIOSBootMenuMode_MenuOnly: 6384 bootMenuModeStr = "menuonly"; 6385 break; 6386 default: 6387 bootMenuModeStr = "messageandmenu"; 6388 } 6389 CFGLDRSetBSTR (bootMenuNode, "mode", bootMenuModeStr); 6390 CFGLDRReleaseNode (bootMenuNode); 6391 6392 /* time offset (optional) */ 6393 CFGNODE timeOffsetNode = 0; 6394 CFGLDRCreateChildNode (biosNode, "TimeOffset", &timeOffsetNode); 6395 LONG64 timeOffset; 6396 mBIOSSettings->COMGETTER(TimeOffset)(&timeOffset); 6397 CFGLDRSetInt64 (timeOffsetNode, "value", timeOffset); 6398 CFGLDRReleaseNode (timeOffsetNode); 6399 6400 /* PXE debug flag (optional) */ 6401 CFGNODE pxedebugNode = 0; 6402 CFGLDRCreateChildNode (biosNode, "PXEDebug", &pxedebugNode); 6403 mBIOSSettings->COMGETTER(PXEDebugEnabled)(&fSet); 6404 CFGLDRSetBool (pxedebugNode, "enabled", !!fSet); 6405 CFGLDRReleaseNode (pxedebugNode); 6406 6407 /* IDE controller type */ 6408 CFGNODE ideControllerNode = 0; 6409 IDEControllerType_T controllerType; 6410 CFGLDRCreateChildNode (biosNode, "IDEController", &ideControllerNode); 6411 mBIOSSettings->COMGETTER(IDEControllerType)(&controllerType); 6412 switch (controllerType) 6413 { 6414 case IDEControllerType_IDEControllerPIIX3: 6415 CFGLDRSetString (ideControllerNode, "type", "PIIX3"); 6416 break; 6417 case IDEControllerType_IDEControllerPIIX4: 6418 CFGLDRSetString (ideControllerNode, "type", "PIIX4"); 6419 break; 6420 default: 6421 ComAssertMsgFailedBreak (("Invalid IDE Controller type: %d\n", 6422 controllerType), rc = E_FAIL); 6423 } 6424 CFGLDRReleaseNode (ideControllerNode); 6425 6426 } 6427 CFGLDRReleaseNode(biosNode); 6428 } 5586 rc = mBIOSSettings->saveSettings (aNode); 5587 CheckComRCReturnRC (rc); 6429 5588 6430 5589 /* DVD drive (required) */ 6431 /// @todo (dmik) move the code to DVDDrive 6432 do 6433 { 6434 CFGNODE dvdNode = 0; 6435 CFGLDRCreateChildNode (aNode, "DVDDrive", &dvdNode); 6436 6437 BOOL fPassthrough; 6438 mDVDDrive->COMGETTER(Passthrough)(&fPassthrough); 6439 CFGLDRSetBool(dvdNode, "passthrough", !!fPassthrough); 6440 6441 switch (mDVDDrive->data()->mDriveState) 6442 { 6443 case DriveState_ImageMounted: 6444 { 6445 Assert (!mDVDDrive->data()->mDVDImage.isNull()); 6446 6447 Guid id; 6448 rc = mDVDDrive->data()->mDVDImage->COMGETTER(Id) (id.asOutParam()); 6449 Assert (!id.isEmpty()); 6450 6451 CFGNODE imageNode = 0; 6452 CFGLDRCreateChildNode (dvdNode, "Image", &imageNode); 6453 CFGLDRSetUUID (imageNode, "uuid", id.ptr()); 6454 CFGLDRReleaseNode (imageNode); 6455 break; 6456 } 6457 case DriveState_HostDriveCaptured: 6458 { 6459 Assert (!mDVDDrive->data()->mHostDrive.isNull()); 6460 6461 Bstr name; 6462 rc = mDVDDrive->data()->mHostDrive->COMGETTER(Name) (name.asOutParam()); 6463 Assert (!name.isEmpty()); 6464 6465 CFGNODE hostDriveNode = 0; 6466 CFGLDRCreateChildNode (dvdNode, "HostDrive", &hostDriveNode); 6467 CFGLDRSetBSTR (hostDriveNode, "src", name); 6468 CFGLDRReleaseNode (hostDriveNode); 6469 break; 6470 } 6471 case DriveState_NotMounted: 6472 /* do nothing, i.e.leave the DVD drive node empty */ 6473 break; 6474 default: 6475 ComAssertMsgFailedBreak (("Invalid DVD drive state: %d\n", 6476 mDVDDrive->data()->mDriveState), 6477 rc = E_FAIL); 6478 } 6479 6480 CFGLDRReleaseNode (dvdNode); 6481 } 6482 while (0); 6483 5590 rc = mDVDDrive->saveSettings (aNode); 6484 5591 CheckComRCReturnRC (rc); 6485 5592 6486 5593 /* Flooppy drive (required) */ 6487 /// @todo (dmik) move the code to DVDDrive 6488 do 6489 { 6490 CFGNODE floppyNode = 0; 6491 CFGLDRCreateChildNode (aNode, "FloppyDrive", &floppyNode); 6492 6493 BOOL fFloppyEnabled; 6494 rc = mFloppyDrive->COMGETTER(Enabled)(&fFloppyEnabled); 6495 CFGLDRSetBool (floppyNode, "enabled", !!fFloppyEnabled); 6496 6497 switch (mFloppyDrive->data()->mDriveState) 6498 { 6499 case DriveState_ImageMounted: 6500 { 6501 Assert (!mFloppyDrive->data()->mFloppyImage.isNull()); 6502 6503 Guid id; 6504 rc = mFloppyDrive->data()->mFloppyImage->COMGETTER(Id) (id.asOutParam()); 6505 Assert (!id.isEmpty()); 6506 6507 CFGNODE imageNode = 0; 6508 CFGLDRCreateChildNode (floppyNode, "Image", &imageNode); 6509 CFGLDRSetUUID (imageNode, "uuid", id.ptr()); 6510 CFGLDRReleaseNode (imageNode); 6511 break; 6512 } 6513 case DriveState_HostDriveCaptured: 6514 { 6515 Assert (!mFloppyDrive->data()->mHostDrive.isNull()); 6516 6517 Bstr name; 6518 rc = mFloppyDrive->data()->mHostDrive->COMGETTER(Name) (name.asOutParam()); 6519 Assert (!name.isEmpty()); 6520 6521 CFGNODE hostDriveNode = 0; 6522 CFGLDRCreateChildNode (floppyNode, "HostDrive", &hostDriveNode); 6523 CFGLDRSetBSTR (hostDriveNode, "src", name); 6524 CFGLDRReleaseNode (hostDriveNode); 6525 break; 6526 } 6527 case DriveState_NotMounted: 6528 /* do nothing, i.e.leave the Floppy drive node empty */ 6529 break; 6530 default: 6531 ComAssertMsgFailedBreak (("Invalid Floppy drive state: %d\n", 6532 mFloppyDrive->data()->mDriveState), 6533 rc = E_FAIL); 6534 } 6535 6536 CFGLDRReleaseNode (floppyNode); 6537 } 6538 while (0); 6539 5594 rc = mFloppyDrive->saveSettings (aNode); 6540 5595 CheckComRCReturnRC (rc); 6541 6542 5596 6543 5597 /* USB Controller (required) */ … … 6546 5600 6547 5601 /* Network adapters (required) */ 6548 do 6549 { 6550 CFGNODE nwNode = 0; 6551 CFGLDRCreateChildNode (aNode, "Network", &nwNode); 6552 6553 for (ULONG slot = 0; slot < ELEMENTS (mNetworkAdapters); slot ++) 6554 { 6555 CFGNODE networkAdapterNode = 0; 6556 CFGLDRAppendChildNode (nwNode, "Adapter", &networkAdapterNode); 6557 6558 CFGLDRSetUInt32 (networkAdapterNode, "slot", slot); 6559 CFGLDRSetBool (networkAdapterNode, "enabled", 6560 !!mNetworkAdapters [slot]->data()->mEnabled); 6561 CFGLDRSetBSTR (networkAdapterNode, "MACAddress", 6562 mNetworkAdapters [slot]->data()->mMACAddress); 6563 CFGLDRSetBool (networkAdapterNode, "cable", 6564 !!mNetworkAdapters [slot]->data()->mCableConnected); 6565 6566 CFGLDRSetUInt32 (networkAdapterNode, "speed", 6567 mNetworkAdapters [slot]->data()->mLineSpeed); 6568 6569 if (mNetworkAdapters [slot]->data()->mTraceEnabled) 6570 CFGLDRSetBool (networkAdapterNode, "trace", true); 6571 6572 CFGLDRSetBSTR (networkAdapterNode, "tracefile", 6573 mNetworkAdapters [slot]->data()->mTraceFile); 6574 6575 switch (mNetworkAdapters [slot]->data()->mAdapterType) 6576 { 6577 case NetworkAdapterType_NetworkAdapterAm79C970A: 6578 CFGLDRSetString (networkAdapterNode, "type", "Am79C970A"); 6579 break; 6580 case NetworkAdapterType_NetworkAdapterAm79C973: 6581 CFGLDRSetString (networkAdapterNode, "type", "Am79C973"); 6582 break; 6583 default: 6584 ComAssertMsgFailedBreak (("Invalid network adapter type: %d\n", 6585 mNetworkAdapters [slot]->data()->mAdapterType), 6586 rc = E_FAIL); 6587 } 6588 6589 CFGNODE attachmentNode = 0; 6590 switch (mNetworkAdapters [slot]->data()->mAttachmentType) 6591 { 6592 case NetworkAttachmentType_NoNetworkAttachment: 6593 { 6594 /* do nothing -- empty content */ 6595 break; 6596 } 6597 case NetworkAttachmentType_NATNetworkAttachment: 6598 { 6599 CFGLDRAppendChildNode (networkAdapterNode, "NAT", &attachmentNode); 6600 break; 6601 } 6602 case NetworkAttachmentType_HostInterfaceNetworkAttachment: 6603 { 6604 CFGLDRAppendChildNode (networkAdapterNode, "HostInterface", &attachmentNode); 6605 const Bstr &name = mNetworkAdapters [slot]->data()->mHostInterface; 6606 #ifdef RT_OS_WINDOWS 6607 Assert (!name.isNull()); 6608 #endif 6609 #ifdef VBOX_WITH_UNIXY_TAP_NETWORKING 6610 if (!name.isEmpty()) 6611 #endif 6612 CFGLDRSetBSTR (attachmentNode, "name", name); 6613 #ifdef VBOX_WITH_UNIXY_TAP_NETWORKING 6614 const Bstr &tapSetupApp = 6615 mNetworkAdapters [slot]->data()->mTAPSetupApplication; 6616 if (!tapSetupApp.isEmpty()) 6617 CFGLDRSetBSTR (attachmentNode, "TAPSetup", tapSetupApp); 6618 const Bstr &tapTerminateApp = 6619 mNetworkAdapters [slot]->data()->mTAPTerminateApplication; 6620 if (!tapTerminateApp.isEmpty()) 6621 CFGLDRSetBSTR (attachmentNode, "TAPTerminate", tapTerminateApp); 6622 #endif /* VBOX_WITH_UNIXY_TAP_NETWORKING */ 6623 break; 6624 } 6625 case NetworkAttachmentType_InternalNetworkAttachment: 6626 { 6627 CFGLDRAppendChildNode (networkAdapterNode, "InternalNetwork", &attachmentNode); 6628 const Bstr &name = mNetworkAdapters[slot]->data()->mInternalNetwork; 6629 Assert(!name.isNull()); 6630 CFGLDRSetBSTR (attachmentNode, "name", name); 6631 break; 6632 } 6633 default: 6634 { 6635 ComAssertFailedBreak (rc = E_FAIL); 6636 break; 6637 } 6638 } 6639 if (attachmentNode) 6640 CFGLDRReleaseNode (attachmentNode); 6641 6642 CFGLDRReleaseNode (networkAdapterNode); 6643 } 6644 6645 CFGLDRReleaseNode (nwNode); 6646 } 6647 while (0); 6648 6649 if (FAILED (rc)) 6650 return rc; 5602 { 5603 Key nwNode = aNode.createKey ("Network"); 5604 5605 for (ULONG slot = 0; slot < ELEMENTS (mNetworkAdapters); ++ slot) 5606 { 5607 Key adapterNode = nwNode.appendKey ("Adapter"); 5608 5609 adapterNode.setValue <ULONG> ("slot", slot); 5610 5611 rc = mNetworkAdapters [slot]->saveSettings (adapterNode); 5612 CheckComRCReturnRC (rc); 5613 } 5614 } 6651 5615 6652 5616 /* Serial ports */ 6653 CFGNODE serialNode = 0; 6654 CFGLDRCreateChildNode (aNode, "Uart", &serialNode); 6655 6656 for (ULONG slot = 0; slot < ELEMENTS (mSerialPorts); slot++) 6657 { 6658 rc = mSerialPorts [slot]->saveSettings (serialNode); 6659 CheckComRCReturnRC (rc); 6660 } 6661 CFGLDRReleaseNode (serialNode); 5617 { 5618 Key serialNode = aNode.createKey ("Uart"); 5619 for (ULONG slot = 0; slot < ELEMENTS (mSerialPorts); ++ slot) 5620 { 5621 Key portNode = serialNode.appendKey ("Port"); 5622 5623 portNode.setValue <ULONG> ("slot", slot); 5624 5625 rc = mSerialPorts [slot]->saveSettings (portNode); 5626 CheckComRCReturnRC (rc); 5627 } 5628 } 6662 5629 6663 5630 /* Parallel ports */ 6664 CFGNODE parallelNode = 0; 6665 CFGLDRCreateChildNode (aNode, "Lpt", ¶llelNode); 6666 6667 for (ULONG slot = 0; slot < ELEMENTS (mParallelPorts); slot++) 6668 { 6669 rc = mParallelPorts [slot]->saveSettings (parallelNode); 6670 CheckComRCReturnRC (rc); 6671 } 6672 CFGLDRReleaseNode (parallelNode); 5631 { 5632 Key parallelNode = aNode.createKey ("Lpt"); 5633 for (ULONG slot = 0; slot < ELEMENTS (mParallelPorts); ++ slot) 5634 { 5635 Key portNode = parallelNode.appendKey ("Port"); 5636 5637 portNode.setValue <ULONG> ("slot", slot); 5638 5639 rc = mParallelPorts [slot]->saveSettings (portNode); 5640 CheckComRCReturnRC (rc); 5641 } 5642 } 6673 5643 6674 5644 /* Audio adapter */ 6675 do 6676 { 6677 CFGNODE adapterNode = 0; 6678 CFGLDRCreateChildNode (aNode, "AudioAdapter", &adapterNode); 6679 6680 switch (mAudioAdapter->data()->mAudioDriver) 6681 { 6682 case AudioDriverType_NullAudioDriver: 6683 { 6684 CFGLDRSetString (adapterNode, "driver", "null"); 6685 break; 6686 } 6687 #ifdef RT_OS_WINDOWS 6688 case AudioDriverType_WINMMAudioDriver: 6689 # ifdef VBOX_WITH_WINMM 6690 { 6691 CFGLDRSetString (adapterNode, "driver", "winmm"); 6692 break; 6693 } 6694 # endif 6695 case AudioDriverType_DSOUNDAudioDriver: 6696 { 6697 CFGLDRSetString (adapterNode, "driver", "dsound"); 6698 break; 6699 } 6700 #endif /* RT_OS_WINDOWS */ 6701 #ifdef RT_OS_LINUX 6702 case AudioDriverType_ALSAAudioDriver: 6703 # ifdef VBOX_WITH_ALSA 6704 { 6705 CFGLDRSetString (adapterNode, "driver", "alsa"); 6706 break; 6707 } 6708 # endif 6709 # ifdef VBOX_WITH_PULSE 6710 case AudioDriverType_PulseAudioDriver: 6711 { 6712 CFGLDRSetString (adapterNode, "driver", "pulse"); 6713 break; 6714 } 6715 # endif 6716 case AudioDriverType_OSSAudioDriver: 6717 { 6718 CFGLDRSetString (adapterNode, "driver", "oss"); 6719 break; 6720 } 6721 #endif /* RT_OS_LINUX */ 6722 #ifdef RT_OS_DARWIN 6723 case AudioDriverType_CoreAudioDriver: 6724 { 6725 CFGLDRSetString (adapterNode, "driver", "coreaudio"); 6726 break; 6727 } 6728 #endif 6729 #ifdef RT_OS_OS2 6730 case AudioDriverType_MMPMAudioDriver: 6731 { 6732 CFGLDRSetString (adapterNode, "driver", "mmpm"); 6733 break; 6734 } 6735 #endif 6736 default: 6737 ComAssertMsgFailedBreak (("Wrong audio driver type! driver = %d\n", 6738 mAudioAdapter->data()->mAudioDriver), 6739 rc = E_FAIL); 6740 } 6741 6742 CFGLDRSetBool (adapterNode, "enabled", !!mAudioAdapter->data()->mEnabled); 6743 6744 CFGLDRReleaseNode (adapterNode); 6745 } 6746 while (0); 6747 6748 if (FAILED (rc)) 6749 return rc; 5645 rc = mAudioAdapter->saveSettings (aNode); 5646 CheckComRCReturnRC (rc); 6750 5647 6751 5648 /* Shared folders */ 6752 do 6753 { 6754 CFGNODE sharedFoldersNode = 0; 6755 CFGLDRCreateChildNode (aNode, "SharedFolders", &sharedFoldersNode); 5649 { 5650 Key sharedFoldersNode = aNode.createKey ("SharedFolders"); 6756 5651 6757 5652 for (HWData::SharedFolderList::const_iterator it = mHWData->mSharedFolders.begin(); … … 6761 5656 ComObjPtr <SharedFolder> folder = *it; 6762 5657 6763 CFGNODE folderNode = 0; 6764 CFGLDRAppendChildNode (sharedFoldersNode, "SharedFolder", &folderNode); 5658 Key folderNode = sharedFoldersNode.appendKey ("SharedFolder"); 6765 5659 6766 5660 /* all are mandatory */ 6767 CFGLDRSetBSTR (folderNode, "name", folder->name()); 6768 CFGLDRSetBSTR (folderNode, "hostPath", folder->hostPath()); 6769 6770 CFGLDRReleaseNode (folderNode); 6771 } 6772 6773 CFGLDRReleaseNode (sharedFoldersNode); 6774 } 6775 while (0); 5661 folderNode.setValue <Bstr> ("name", folder->name()); 5662 folderNode.setValue <Bstr> ("hostPath", folder->hostPath()); 5663 } 5664 } 6776 5665 6777 5666 /* Clipboard */ 6778 5667 { 6779 CFGNODE clipNode = 0; 6780 CFGLDRCreateChildNode (aNode, "Clipboard", &clipNode); 6781 6782 const char *mode = "Disabled"; 5668 Key clipNode = aNode.createKey ("Clipboard"); 5669 5670 const char *modeStr = "Disabled"; 6783 5671 switch (mHWData->mClipboardMode) 6784 5672 { … … 6787 5675 break; 6788 5676 case ClipboardMode_ClipHostToGuest: 6789 mode = "HostToGuest";5677 modeStr = "HostToGuest"; 6790 5678 break; 6791 5679 case ClipboardMode_ClipGuestToHost: 6792 mode = "GuestToHost";5680 modeStr = "GuestToHost"; 6793 5681 break; 6794 5682 case ClipboardMode_ClipBidirectional: 6795 mode = "Bidirectional";5683 modeStr = "Bidirectional"; 6796 5684 break; 6797 5685 default: 6798 AssertMsgFailed (("Clipboard mode %d is invalid", 6799 mHWData->mClipboardMode)); 6800 break; 6801 } 6802 CFGLDRSetString (clipNode, "mode", mode); 6803 6804 CFGLDRReleaseNode (clipNode); 5686 ComAssertMsgFailedRet (("Clipboard mode %d is invalid", 5687 mHWData->mClipboardMode), 5688 E_FAIL); 5689 } 5690 clipNode.setStringValue ("mode", modeStr); 6805 5691 } 6806 5692 6807 5693 /* Guest */ 6808 5694 { 6809 CFGNODE guestNode = 0; 6810 CFGLDRGetChildNode (aNode, "Guest", 0, &guestNode); 5695 Key guestNode = aNode.findKey ("Guest"); 6811 5696 /* first, delete the entire node if exists */ 6812 if ( guestNode)6813 CFGLDRDeleteNode (guestNode);5697 if (!guestNode.isNull()) 5698 guestNode.zap(); 6814 5699 /* then recreate it */ 6815 guestNode = 0; 6816 CFGLDRCreateChildNode (aNode, "Guest", &guestNode); 6817 6818 CFGLDRSetUInt32 (guestNode, "MemoryBalloonSize", 6819 mHWData->mMemoryBalloonSize); 6820 CFGLDRSetUInt32 (guestNode, "StatisticsUpdateInterval", 6821 mHWData->mStatisticsUpdateInterval); 6822 6823 CFGLDRReleaseNode (guestNode); 6824 } 6825 5700 guestNode = aNode.createKey ("Guest"); 5701 5702 guestNode.setValue <ULONG> ("MemoryBalloonSize", 5703 mHWData->mMemoryBalloonSize); 5704 guestNode.setValue <ULONG> ("StatisticsUpdateInterval", 5705 mHWData->mStatisticsUpdateInterval); 5706 } 5707 5708 AssertComRC (rc); 6826 5709 return rc; 6827 5710 } … … 6831 5714 * It is assumed that the given node is empty. 6832 5715 * 6833 * @param aNode <HardDiskAttachments> node to save the hard disk confguration to 5716 * @param aNode <HardDiskAttachments> node to save the hard disk confguration to. 6834 5717 */ 6835 HRESULT Machine::saveHardDisks ( CFGNODEaNode)6836 { 6837 AssertReturn (aNode, E_INVALIDARG);6838 6839 HRESULT rc = S_OK;5718 HRESULT Machine::saveHardDisks (settings::Key &aNode) 5719 { 5720 using namespace settings; 5721 5722 AssertReturn (!aNode.isNull(), E_INVALIDARG); 6840 5723 6841 5724 for (HDData::HDAttachmentList::const_iterator it = mHDData->mHDAttachments.begin(); 6842 it != mHDData->mHDAttachments.end() && SUCCEEDED (rc);5725 it != mHDData->mHDAttachments.end(); 6843 5726 ++ it) 6844 5727 { 6845 5728 ComObjPtr <HardDiskAttachment> att = *it; 6846 5729 6847 CFGNODE hdNode = 0; 6848 CFGLDRAppendChildNode (aNode, "HardDiskAttachment", &hdNode); 6849 6850 do 5730 Key hdNode = aNode.appendKey ("HardDiskAttachment"); 5731 6851 5732 { 6852 5733 const char *bus = NULL; … … 6856 5737 case DiskControllerType_IDE1Controller: bus = "ide1"; break; 6857 5738 default: 6858 ComAssertFailed Break (rc =E_FAIL);5739 ComAssertFailedRet (E_FAIL); 6859 5740 } 6860 if (FAILED (rc))6861 break;6862 5741 6863 5742 const char *dev = NULL; … … 6867 5746 case 1: dev = "slave"; break; 6868 5747 default: 6869 ComAssertFailed Break (rc =E_FAIL);5748 ComAssertFailedRet (E_FAIL); 6870 5749 } 6871 if (FAILED (rc)) 6872 break; 6873 6874 CFGLDRSetUUID (hdNode, "hardDisk", att->hardDisk()->id()); 6875 CFGLDRSetString (hdNode, "bus", bus); 6876 CFGLDRSetString (hdNode, "device", dev); 6877 } 6878 while (0); 6879 6880 CFGLDRReleaseNode (hdNode); 6881 } 6882 6883 return rc; 5750 5751 hdNode.setValue <Guid> ("hardDisk", att->hardDisk()->id()); 5752 hdNode.setStringValue ("bus", bus); 5753 hdNode.setStringValue ("device", dev); 5754 } 5755 } 5756 5757 return S_OK; 6884 5758 } 6885 5759 … … 6888 5762 * (SaveSTS_* values). 6889 5763 * 6890 * @param aFlags a combination of SaveSTS_* flags6891 * 6892 * @note Locks objects !5764 * @param aFlags Combination of SaveSTS_* flags. 5765 * 5766 * @note Locks objects for writing. 6893 5767 */ 6894 5768 HRESULT Machine::saveStateSettings (int aFlags) … … 6902 5776 AutoLock alock (this); 6903 5777 6904 /* load the config file */ 6905 CFGHANDLE configLoader = 0; 6906 HRESULT rc = openConfigLoader (&configLoader); 6907 if (FAILED (rc)) 6908 return rc; 6909 6910 CFGNODE machineNode = 0; 6911 CFGLDRGetNode (configLoader, "VirtualBox/Machine", 0, &machineNode); 6912 6913 do 6914 { 6915 ComAssertBreak (machineNode, rc = E_FAIL); 5778 AssertReturn (isConfigLocked(), E_FAIL); 5779 5780 HRESULT rc = S_OK; 5781 5782 try 5783 { 5784 using namespace settings; 5785 5786 /* load the config file */ 5787 File file (File::ReadWrite, mData->mHandleCfgFile, 5788 Utf8Str (mData->mConfigFileFull)); 5789 XmlTreeBackend tree; 5790 5791 rc = VirtualBox::loadSettingsTree_ForUpdate (tree, file); 5792 CheckComRCReturnRC (rc); 5793 5794 Key machineNode = tree.rootKey().key ("Machine"); 6916 5795 6917 5796 if (aFlags & SaveSTS_CurStateModified) 6918 5797 { 6919 if (!mData->mCurrentStateModified) 6920 CFGLDRSetBool (machineNode, "currentStateModified", false); 6921 else 6922 CFGLDRDeleteAttribute (machineNode, "currentStateModified"); 5798 /* defaults to true */ 5799 machineNode.setValueOr <bool> ("currentStateModified", 5800 !mData->mCurrentStateModified, true); 6923 5801 } 6924 5802 … … 6930 5808 Utf8Str stateFilePath = mSSData->mStateFilePath; 6931 5809 calculateRelativePath (stateFilePath, stateFilePath); 6932 CFGLDRSetString (machineNode,"stateFile", stateFilePath);5810 machineNode.setStringValue ("stateFile", stateFilePath); 6933 5811 } 6934 5812 else 6935 CFGLDRDeleteAttribute (machineNode,"stateFile");5813 machineNode.zapValue ("stateFile"); 6936 5814 } 6937 5815 … … 6941 5819 mSSData->mStateFilePath.isNull()); 6942 5820 6943 CFGLDRSetDateTime (machineNode, "lastStateChange", 6944 mData->mLastStateChange); 6945 6946 // set the aborted attribute when appropriate 6947 if (mData->mMachineState == MachineState_Aborted) 6948 CFGLDRSetBool (machineNode, "aborted", true); 6949 else 6950 CFGLDRDeleteAttribute (machineNode, "aborted"); 6951 } 6952 } 6953 while (0); 6954 6955 if (machineNode) 6956 CFGLDRReleaseNode (machineNode); 6957 6958 if (SUCCEEDED (rc)) 6959 rc = closeConfigLoader (configLoader, true /* aSaveBeforeClose */); 6960 else 6961 closeConfigLoader (configLoader, false /* aSaveBeforeClose */); 5821 machineNode.setValue <RTTIMESPEC> ("lastStateChange", 5822 mData->mLastStateChange); 5823 5824 /* set the aborted attribute when appropriate, defaults to false */ 5825 machineNode.setValueOr <bool> ("aborted", 5826 mData->mMachineState == MachineState_Aborted, 5827 false); 5828 } 5829 5830 /* save settings on success */ 5831 rc = VirtualBox::saveSettingsTree (tree, file); 5832 CheckComRCReturnRC (rc); 5833 } 5834 catch (...) 5835 { 5836 rc = VirtualBox::handleUnexpectedExceptions (RT_SRC_POS); 5837 } 6962 5838 6963 5839 return rc; … … 8947 7823 snapshot.createObject(); 8948 7824 rc = snapshot->init (snapshotId, aName, aDescription, 8949 RTTimeSpecGetMilli (RTTimeNow (&time)),8950 snapshotMachine,mData->mCurrentSnapshot);8951 AssertComRCReturn (rc,rc);7825 *RTTimeNow (&time), snapshotMachine, 7826 mData->mCurrentSnapshot); 7827 AssertComRCReturnRC (rc); 8952 7828 8953 7829 /* … … 9631 8507 AssertComRCReturn (autoCaller.rc(), autoCaller.rc()); 9632 8508 9633 /* mParent->removeProgress() needsmParent lock */8509 /* mParent->removeProgress() and saveSettings() need mParent lock */ 9634 8510 AutoMultiLock <2> alock (mParent->wlock(), this->wlock()); 9635 8511 … … 9877 8753 ComObjPtr <SnapshotMachine> sm = aTask.snapshot->data().mMachine; 9878 8754 9879 /* mParent is locked because of Progress::notifyComplete(), etc.*/8755 /* Progress::notifyComplete() et al., saveSettings() need mParent lock */ 9880 8756 AutoMultiLock <3> alock (mParent->wlock(), this->wlock(), sm->rlock()); 9881 8757 … … 10269 9145 } 10270 9146 10271 /* mParent is locked because of Progress::notifyComplete(), etc.*/9147 /* Progress::notifyComplete() et al., saveSettings() need mParent lock */ 10272 9148 AutoMultiLock <2> alock (mParent->wlock(), this->wlock()); 10273 9149 … … 10328 9204 } 10329 9205 10330 LONG64 snapshotTimeStamp = 0; 9206 RTTIMESPEC snapshotTimeStamp; 9207 RTTimeSpecSetMilli (&snapshotTimeStamp, 0); 10331 9208 10332 9209 { … … 10462 9339 10463 9340 /* assign the timestamp from the snapshot */ 10464 Assert ( snapshotTimeStamp!= 0);9341 Assert (RTTimeSpecGetMilli (&snapshotTimeStamp) != 0); 10465 9342 mData->mLastStateChange = snapshotTimeStamp; 10466 9343 … … 10879 9756 * @note Locks aMachine object for reading. 10880 9757 */ 10881 HRESULT SnapshotMachine::init (Machine *aMachine, CFGNODE aHWNode, CFGNODE aHDAsNode, 9758 HRESULT SnapshotMachine::init (Machine *aMachine, 9759 const settings::Key &aHWNode, 9760 const settings::Key &aHDAsNode, 10882 9761 INPTR GUIDPARAM aSnapshotId, INPTR BSTR aStateFilePath) 10883 9762 { … … 10885 9764 LogFlowThisFunc (("mName={%ls}\n", aMachine->mUserData->mName.raw())); 10886 9765 10887 AssertReturn (aMachine && aHWNode && aHDAsNode && !Guid (aSnapshotId).isEmpty(), 9766 AssertReturn (aMachine && !aHWNode.isNull() && !aHDAsNode.isNull() && 9767 !Guid (aSnapshotId).isEmpty(), 10888 9768 E_INVALIDARG); 10889 9769 -
trunk/src/VBox/Main/Makefile.kmk
r6056 r6076 1 1 # $Id$ 2 2 3 ## @file 3 4 # Makefile for the VBox Main module. … … 27 28 28 29 LIBRARIES = VBoxCOM 29 DLLS = VBoxXML VBox C30 DLLS = VBoxXML VBoxSettings VBoxC 30 31 PROGRAMS = VBoxSVC 31 32 ifneq ($(BUILD_TARGET),win) … … 101 102 102 103 VBoxSVC_TEMPLATE = VBOXMAINEXE 103 VBoxSVC_DEFS = CFGLDR_HAVE_COM IN_CFGLDR_R3 104 VBoxSVC_DEFS = CFGLDR_HAVE_COM IN_CFGLDR_R3 VBOX_MAIN_SETTINGS_ADDONS 104 105 ifdef VBOX_WITH_VRDP 105 106 VBoxSVC_DEFS += VBOX_VRDP … … 139 140 include \ 140 141 $(PATH_VBoxSVC) \ 141 $(PATH_VBoxCOM) \142 142 $(PATH_CURRENT) 143 VBoxSVC_INCS.win = \ 144 $(PATH_VBoxCOM) 143 145 ifdef VBOX_WITH_USB 144 146 VBoxSVC_INCS.os2 = \ … … 149 151 VBoxSVC_LIBS += \ 150 152 $(PATH_LIB)/VBoxDDU$(VBOX_SUFF_LIB) \ 151 $(PATH_LIB)/VBoxXML$(VBOX_SUFF_LIB) 153 $(PATH_LIB)/VBoxXML$(VBOX_SUFF_LIB) \ 154 $(PATH_LIB)/VBoxSettings$(VBOX_SUFF_LIB) 152 155 else 153 156 VBoxSVC_LIBS += \ 154 157 $(PATH_BIN)/VBoxDDU$(VBOX_SUFF_DLL) \ 155 $(PATH_BIN)/VBoxXML$(VBOX_SUFF_DLL) 158 $(PATH_BIN)/VBoxXML$(VBOX_SUFF_DLL) \ 159 $(PATH_BIN)/VBoxSettings$(VBOX_SUFF_DLL) 156 160 endif 157 161 VBoxSVC_LIBS.darwin = \ … … 167 171 USBProxyService.cpp \ 168 172 VirtualBoxBase.cpp \ 169 VirtualBoxXMLUtil.cpp \170 173 VirtualBoxErrorInfoImpl.cpp \ 171 174 VirtualBoxImpl.cpp \ 175 VirtualBoxImplExtra.cpp \ 172 176 MachineImpl.cpp \ 173 177 SnapshotImpl.cpp \ … … 314 318 VBoxC_INCS = \ 315 319 include \ 316 $(PATH_VBoxC) \317 $(PATH_VBoxCOM) 318 VBoxC_INCS.win :=\320 $(PATH_VBoxC) 321 VBoxC_INCS.win = \ 322 $(PATH_VBoxCOM) \ 319 323 $(PATH_SUB_CURRENT) 320 324 … … 323 327 -exported_symbols_list $(PATH_TARGET)/VBoxC.def 324 328 ifdef VBOX_USE_VCC80 325 VBoxC_LDFLAGS.win = /MANIFEST329 VBoxC_LDFLAGS.win = /MANIFEST 326 330 endif 327 331 … … 395 399 # VBoxXML 396 400 # 401 397 402 VBoxXML_TEMPLATE = VBOXMAINDLL 398 403 VBoxXML_SDKS = VBOX_XALAN VBOX_XERCES … … 419 424 $(call MSG_TOOL,bin2c,VBoxXML,$<,$@) 420 425 $(QUIET)$(VBOX_BIN2C) SettingsConverter_xsl $< $@ 426 427 428 # 429 # VBoxSettings (will supercede VBoxXML when done) 430 # 431 432 VBoxSettings_TEMPLATE = VBOXMAINDLL 433 VBoxSettings_SDKS = VBOX_LIBXML2 VBOX_ZLIB 434 VBoxSettings_DEFS = IN_VBOXSETTINGS_R3 435 VBoxSettings_INCS = \ 436 include \ 437 $(PATH_TARGET) 438 VBoxSettings_SOURCES = \ 439 xml/Settings.cpp 440 VBoxSettings_LDFLAGS.darwin = -install_name @executable_path/VBoxSettings.dylib -Wl,-x # no debug info please. 421 441 422 442 … … 494 514 VBOX_XML_SCHEMA.solaris= xml/VirtualBox-settings-solaris.xsd 495 515 496 VirtualBox XMLUtil.cpp_DEPS = $(VBOX_XML_ENTITIES) $(VBOX_XML_ENTITIES_COMMON)516 VirtualBoxImplExtra.cpp_DEPS = $(VBOX_XML_ENTITIES) $(VBOX_XML_ENTITIES_COMMON) 497 517 498 518 $(VBOX_XML_ENTITIES_COMMON): $(VBOX_XML_SCHEMA_COMMON) $(VBOX_BIN2C) 499 $(call MSG_TOOL,bin2c,VBox XML,$<,$@)519 $(call MSG_TOOL,bin2c,VBoxSVC,$<,$@) 500 520 $(QUIET)$(VBOX_BIN2C) VirtualBox_settings_common_xsd $< $@ 501 521 502 522 $(VBOX_XML_ENTITIES): $(VBOX_XML_SCHEMA.$(BUILD_TARGET)) $(VBOX_BIN2C) 503 $(call MSG_TOOL,bin2c,VBox XML,$<,$@)523 $(call MSG_TOOL,bin2c,VBoxSVC,$<,$@) 504 524 $(QUIET)$(VBOX_BIN2C) VirtualBox_settings_xsd $< $@ 505 525 … … 519 539 520 540 $(VBOX_XML_SCHEMADEFS_H): $(VBOX_XML_SCHEMADEFS_XSL) $(VBOX_XML_SCHEMA.$(BUILD_TARGET)) $(VBOX_XML_SCHEMA_COMMON) 521 $(call MSG_TOOL,xsltproc,VBox XML,$<,$@)541 $(call MSG_TOOL,xsltproc,VBoxSVC,$<,$@) 522 542 $(QUIET)$(VBOX_XSLTPROC) -o $@ $(filter-out $(VBOX_XML_SCHEMA_COMMON),$^) 523 543 … … 556 576 557 577 $(IDLFILE): idl/xpidl.xsl $(XIDLFILE) | $(call DIRDEP,$(dir $(IDLFILE))) 558 $(call MSG_TOOL,xsltproc,VBox XML,$<,$@)578 $(call MSG_TOOL,xsltproc,VBoxSVC,$<,$@) 559 579 $(QUIET)$(MKDIR) -p $(@D) 560 580 $(QUIET)$(VBOX_XSLTPROC) -o $@ $^ 561 581 562 582 $(IDLTYPELIB): $(IDLFILE) | $(call DIRDEP,$(dir $(IDLTYPELIB))) 563 $(call MSG_TOOL,xpidl,VBox XML,$<,$@)583 $(call MSG_TOOL,xpidl,VBoxSVC,$<,$@) 564 584 $(QUIET)$(VBOX_XPIDL) -m typelib -I $(VBOX_PATH_XPCOM_IDL) -e $@ $< 565 585 566 586 $(IDLHEADER): $(IDLFILE) | $(call DIRDEP,$(dir $(IDLHEADER))) 567 $(call MSG_TOOL,xpidl,VBox XML,$<,$@)587 $(call MSG_TOOL,xpidl,VBoxSVC,$<,$@) 568 588 $(QUIET)$(VBOX_XPIDL) -m header -I $(VBOX_PATH_XPCOM_IDL) -e $@ $< 569 589 … … 581 601 582 602 $(IDLFILE): idl/midl.xsl $(XIDLFILE) 583 $(call MSG_TOOL,xsltproc,VBox XML,$<,$@)603 $(call MSG_TOOL,xsltproc,VBoxSVC,$<,$@) 584 604 $(QUIET)$(MKDIR) -p $(VBOX_PATH_SDK)/idl 585 605 $(QUIET)$(VBOX_XSLTPROC) -o $@ $^ -
trunk/src/VBox/Main/NetworkAdapterImpl.cpp
r5999 r6076 935 935 // public methods only for internal purposes 936 936 //////////////////////////////////////////////////////////////////////////////// 937 938 /** 939 * Loads settings from the given adapter node. 940 * May be called once right after this object creation. 941 * 942 * @param aAdapterNode <Adapter> node. 943 * 944 * @note Locks this object for writing. 945 */ 946 HRESULT NetworkAdapter::loadSettings (const settings::Key &aAdapterNode) 947 { 948 using namespace settings; 949 950 AssertReturn (!aAdapterNode.isNull(), E_FAIL); 951 952 AutoCaller autoCaller (this); 953 AssertComRCReturnRC (autoCaller.rc()); 954 955 AutoLock alock (this); 956 957 /* Note: we assume that the default values for attributes of optional 958 * nodes are assigned in the Data::Data() constructor and don't do it 959 * here. It implies that this method may only be called after constructing 960 * a new BIOSSettings object while all its data fields are in the default 961 * values. Exceptions are fields whose creation time defaults don't match 962 * values that should be applied when these fields are not explicitly set 963 * in the settings file (for backwards compatibility reasons). This takes 964 * place when a setting of a newly created object must default to A while 965 * the same setting of an object loaded from the old settings file must 966 * default to B. */ 967 968 HRESULT rc = S_OK; 969 970 /* type (optional, defaults to Am79C970A) */ 971 const char *adapterType = aAdapterNode.stringValue ("type"); 972 973 if (strcmp (adapterType, "Am79C970A") == 0) 974 mData->mAdapterType = NetworkAdapterType_NetworkAdapterAm79C970A; 975 else if (strcmp (adapterType, "Am79C973") == 0) 976 mData->mAdapterType = NetworkAdapterType_NetworkAdapterAm79C973; 977 else 978 ComAssertMsgFailedRet (("Invalid adapter type '%s'", adapterType), 979 E_FAIL); 980 981 /* enabled (required) */ 982 mData->mEnabled = aAdapterNode.value <bool> ("enabled"); 983 /* MAC address (can be null) */ 984 rc = COMSETTER(MACAddress) (Bstr (aAdapterNode.stringValue ("MACAddress"))); 985 CheckComRCReturnRC (rc); 986 /* cable (required) */ 987 mData->mCableConnected = aAdapterNode.value <bool> ("cable"); 988 /* line speed (defaults to 100 Mbps) */ 989 mData->mLineSpeed = aAdapterNode.value <ULONG> ("speed"); 990 /* tracing (defaults to false) */ 991 mData->mTraceEnabled = aAdapterNode.value <bool> ("trace"); 992 mData->mTraceFile = aAdapterNode.stringValue ("tracefile"); 993 994 /* One of NAT, HostInerface, Internal or nothing */ 995 Key attachmentNode; 996 997 if (!(attachmentNode = aAdapterNode.findKey ("NAT")).isNull()) 998 { 999 /* NAT */ 1000 1001 rc = AttachToNAT(); 1002 CheckComRCReturnRC (rc); 1003 } 1004 else 1005 if (!(attachmentNode = aAdapterNode.findKey ("HostInerface")).isNull()) 1006 { 1007 /* Host Interface Networking */ 1008 1009 Bstr name = attachmentNode.stringValue ("name"); 1010 #ifdef RT_OS_WINDOWS 1011 /* name can be empty on Win32, but not null */ 1012 ComAssertRet (!name.isNull(), E_FAIL); 1013 #endif 1014 rc = COMSETTER(HostInterface) (name); 1015 CheckComRCReturnRC (rc); 1016 1017 #ifdef VBOX_WITH_UNIXY_TAP_NETWORKING 1018 /* optopnal */ 1019 mData->mTAPSetupApplication = attachmentNode.stringValue ("TAPSetup"); 1020 mData->mTAPTerminateApplication = attachmentNode.stringValue ("TAPTerminate"); 1021 #endif /* VBOX_WITH_UNIXY_TAP_NETWORKING */ 1022 1023 rc = AttachToHostInterface(); 1024 CheckComRCReturnRC (rc); 1025 } 1026 else 1027 if (!(attachmentNode = aAdapterNode.findKey ("InternalNetwork")).isNull()) 1028 { 1029 /* Internal Networking */ 1030 1031 /* required */ 1032 mData->mInternalNetwork = attachmentNode.stringValue ("name"); 1033 1034 rc = AttachToInternalNetwork(); 1035 CheckComRCReturnRC (rc); 1036 } 1037 else 1038 { 1039 /* Adapter has no children */ 1040 rc = Detach(); 1041 CheckComRCReturnRC (rc); 1042 } 1043 1044 return S_OK; 1045 } 1046 1047 /** 1048 * Saves settings to the given adapter node. 1049 * 1050 * Note that the given Adapter node is comletely empty on input. 1051 * 1052 * @param aAdapterNode <Adapter> node. 1053 * 1054 * @note Locks this object for reading. 1055 */ 1056 HRESULT NetworkAdapter::saveSettings (settings::Key &aAdapterNode) 1057 { 1058 using namespace settings; 1059 1060 AssertReturn (!aAdapterNode.isNull(), E_FAIL); 1061 1062 AutoCaller autoCaller (this); 1063 AssertComRCReturnRC (autoCaller.rc()); 1064 1065 AutoReaderLock alock (this); 1066 1067 aAdapterNode.setValue <bool> ("enabled", !!mData->mEnabled); 1068 aAdapterNode.setValue <Bstr> ("MACAddress", mData->mMACAddress); 1069 aAdapterNode.setValue <bool> ("cable", !!mData->mCableConnected); 1070 1071 aAdapterNode.setValue <ULONG> ("speed", mData->mLineSpeed); 1072 1073 if (mData->mTraceEnabled) 1074 aAdapterNode.setValue <bool> ("trace", true); 1075 1076 aAdapterNode.setValueOr <Bstr> ("tracefile", mData->mTraceFile, Bstr::Null); 1077 1078 const char *typeStr = NULL; 1079 switch (mData->mAdapterType) 1080 { 1081 case NetworkAdapterType_NetworkAdapterAm79C970A: 1082 typeStr = "Am79C970A"; 1083 break; 1084 case NetworkAdapterType_NetworkAdapterAm79C973: 1085 typeStr = "Am79C973"; 1086 break; 1087 default: 1088 ComAssertMsgFailedRet (("Invalid network adapter type: %d\n", 1089 mData->mAdapterType), 1090 E_FAIL); 1091 } 1092 aAdapterNode.setStringValue ("type", typeStr); 1093 1094 switch (mData->mAttachmentType) 1095 { 1096 case NetworkAttachmentType_NoNetworkAttachment: 1097 { 1098 /* do nothing -- empty content */ 1099 break; 1100 } 1101 case NetworkAttachmentType_NATNetworkAttachment: 1102 { 1103 Key attachmentNode = aAdapterNode.createKey ("NAT"); 1104 break; 1105 } 1106 case NetworkAttachmentType_HostInterfaceNetworkAttachment: 1107 { 1108 Key attachmentNode = aAdapterNode.createKey ("HostInterface"); 1109 #ifdef RT_OS_WINDOWS 1110 Assert (!mData->mHostInterface.isNull()); 1111 #endif 1112 #ifdef VBOX_WITH_UNIXY_TAP_NETWORKING 1113 if (!mData->mHostInterface.isEmpty()) 1114 #endif 1115 attachmentNode.setValue <Bstr> ("name", mData->mHostInterface); 1116 #ifdef VBOX_WITH_UNIXY_TAP_NETWORKING 1117 if (!mData->mTAPSetupApplication.isEmpty()) 1118 attachmentNode.setValue <Bstr> ("TAPSetup", 1119 mData->mTAPSetupApplication); 1120 if (!mData->mTAPTerminateApplication.isEmpty()) 1121 attachmentNode.setValue <Bstr> ("TAPTerminate", 1122 mData->mTAPTerminateApplication); 1123 #endif /* VBOX_WITH_UNIXY_TAP_NETWORKING */ 1124 break; 1125 } 1126 case NetworkAttachmentType_InternalNetworkAttachment: 1127 { 1128 Key attachmentNode = aAdapterNode.createKey ("InternalNetwork"); 1129 Assert (!mData->mInternalNetwork.isNull()); 1130 attachmentNode.setValue <Bstr> ("name", mData->mInternalNetwork); 1131 break; 1132 } 1133 default: 1134 { 1135 ComAssertFailedRet (E_FAIL); 1136 } 1137 } 1138 1139 return S_OK; 1140 } 937 1141 938 1142 /** -
trunk/src/VBox/Main/ParallelPortImpl.cpp
r5999 r6076 161 161 162 162 /** 163 * Loads settings from the given port node. 164 * May be called once right after this object creation. 165 * 166 * @param aPortNode <Port> node. 167 * 168 * @note Locks this object for writing. 169 */ 170 HRESULT ParallelPort::loadSettings (const settings::Key &aPortNode) 171 { 172 using namespace settings; 173 174 AssertReturn (!aPortNode.isNull(), E_FAIL); 175 176 AutoCaller autoCaller (this); 177 AssertComRCReturnRC (autoCaller.rc()); 178 179 AutoLock alock (this); 180 181 /* Note: we assume that the default values for attributes of optional 182 * nodes are assigned in the Data::Data() constructor and don't do it 183 * here. It implies that this method may only be called after constructing 184 * a new BIOSSettings object while all its data fields are in the default 185 * values. Exceptions are fields whose creation time defaults don't match 186 * values that should be applied when these fields are not explicitly set 187 * in the settings file (for backwards compatibility reasons). This takes 188 * place when a setting of a newly created object must default to A while 189 * the same setting of an object loaded from the old settings file must 190 * default to B. */ 191 192 /* enabled (required) */ 193 mData->mEnabled = aPortNode.value <bool> ("enabled"); 194 /* I/O base (required) */ 195 mData->mIOBase = aPortNode.value <ULONG> ("IOBase"); 196 /* IRQ (required) */ 197 mData->mIRQ = aPortNode.value <ULONG> ("IRQ"); 198 /* device path (may be null) */ 199 /// @todo report an error if enabled is true and path is empty or null! 200 // The same applies to COMSETTER(Path). 201 mData->mPath = aPortNode.stringValue ("path"); 202 203 return S_OK; 204 } 205 206 /** 207 * Saves settings to the given port node. 208 * 209 * Note that the given Port node is comletely empty on input. 210 * 211 * @param aPortNode <Port> node. 212 * 213 * @note Locks this object for reading. 214 */ 215 HRESULT ParallelPort::saveSettings (settings::Key &aPortNode) 216 { 217 using namespace settings; 218 219 AssertReturn (!aPortNode.isNull(), E_FAIL); 220 221 AutoCaller autoCaller (this); 222 AssertComRCReturnRC (autoCaller.rc()); 223 224 AutoReaderLock alock (this); 225 226 aPortNode.setValue <bool> ("enabled", !!mData->mEnabled); 227 aPortNode.setValue <ULONG> ("IOBase", mData->mIOBase, 16); 228 aPortNode.setValue <ULONG> ("IRQ", mData->mIRQ); 229 230 /* 'path' is optional in XML */ 231 if (!mData->mPath.isEmpty()) 232 aPortNode.setValue <Bstr> ("path", mData->mPath); 233 234 return S_OK; 235 } 236 237 /** 163 238 * @note Locks this object for writing. 164 239 */ … … 233 308 /* this will back up current data */ 234 309 mData.assignCopy (aThat->mData); 235 }236 237 HRESULT ParallelPort::loadSettings (CFGNODE aNode, ULONG aSlot)238 {239 LogFlowThisFunc (("aMachine=%p\n", aNode));240 241 AssertReturn (aNode, E_FAIL);242 243 AutoCaller autoCaller (this);244 AssertComRCReturnRC (autoCaller.rc());245 246 AutoLock alock (this);247 248 CFGNODE portNode = NULL;249 CFGLDRGetChildNode (aNode, "Port", aSlot, &portNode);250 251 /* slot number (required) */252 /* slot unicity is guaranteed by XML Schema */253 uint32_t uSlot = 0;254 CFGLDRQueryUInt32 (portNode, "slot", &uSlot);255 /* enabled (required) */256 bool fEnabled = false;257 CFGLDRQueryBool (portNode, "enabled", &fEnabled);258 /* I/O base (required) */259 uint32_t uIOBase;260 CFGLDRQueryUInt32 (portNode, "IOBase", &uIOBase);261 /* IRQ (required) */262 uint32_t uIRQ;263 CFGLDRQueryUInt32 (portNode, "IRQ", &uIRQ);264 /* device path */265 Bstr path;266 CFGLDRQueryBSTR (portNode, "path", path.asOutParam());267 268 mData->mEnabled = fEnabled;269 mData->mSlot = uSlot;270 mData->mIOBase = uIOBase;271 mData->mIRQ = uIRQ;272 mData->mPath = path;273 274 return S_OK;275 }276 277 /**278 * Saves the port settings to the given <Port> node.279 *280 * Note that the given node is always empty so it is not necessary to delete281 * old values.282 *283 * @param aNode Node to save the settings to.284 *285 * @return286 */287 HRESULT ParallelPort::saveSettings (CFGNODE aNode)288 {289 AssertReturn (aNode, E_FAIL);290 291 AutoCaller autoCaller (this);292 CheckComRCReturnRC (autoCaller.rc());293 294 AutoReaderLock alock (this);295 296 CFGNODE portNode = 0;297 int vrc = CFGLDRAppendChildNode (aNode, "Port", &portNode);298 ComAssertRCRet (vrc, E_FAIL);299 300 CFGLDRSetUInt32 (portNode, "slot", mData->mSlot);301 CFGLDRSetBool (portNode, "enabled", !!mData->mEnabled);302 CFGLDRSetUInt32Ex (portNode, "IOBase", mData->mIOBase, 16);303 CFGLDRSetUInt32 (portNode, "IRQ", mData->mIRQ);304 305 /* 'path' is optional in XML */306 if (!mData->mPath.isEmpty())307 CFGLDRSetBSTR (portNode, "path", mData->mPath);308 309 return S_OK;310 310 } 311 311 -
trunk/src/VBox/Main/SerialPortImpl.cpp
r5999 r6076 161 161 162 162 /** 163 * @note Locks this object for writing. 164 */ 165 bool SerialPort::rollback() 166 { 167 /* sanity */ 168 AutoCaller autoCaller (this); 169 AssertComRCReturn (autoCaller.rc(), false); 170 171 AutoLock alock (this); 172 173 bool changed = false; 174 175 if (mData.isBackedUp()) 176 { 177 /* we need to check all data to see whether anything will be changed 178 * after rollback */ 179 changed = mData.hasActualChanges(); 180 mData.rollback(); 181 } 182 183 return changed; 184 } 185 186 /** 187 * @note Locks this object for writing, together with the peer object (also 188 * for writing) if there is one. 189 */ 190 void SerialPort::commit() 191 { 192 /* sanity */ 193 AutoCaller autoCaller (this); 194 AssertComRCReturnVoid (autoCaller.rc()); 195 196 /* sanity too */ 197 AutoCaller thatCaller (mPeer); 198 AssertComRCReturnVoid (thatCaller.rc()); 199 200 /* lock both for writing since we modify both */ 201 AutoMultiLock <2> alock (this->wlock(), AutoLock::maybeWlock (mPeer)); 202 203 if (mData.isBackedUp()) 204 { 205 mData.commit(); 206 if (mPeer) 207 { 208 /* attach new data to the peer and reshare it */ 209 mPeer->mData.attach (mData); 210 } 211 } 212 } 213 214 /** 215 * @note Locks this object for writing, together with the peer object 216 * represented by @a aThat (locked for reading). 217 */ 218 void SerialPort::copyFrom (SerialPort *aThat) 219 { 220 AssertReturnVoid (aThat != NULL); 221 222 /* sanity */ 223 AutoCaller autoCaller (this); 224 AssertComRCReturnVoid (autoCaller.rc()); 225 226 /* sanity too */ 227 AutoCaller thatCaller (mPeer); 228 AssertComRCReturnVoid (thatCaller.rc()); 229 230 /* peer is not modified, lock it for reading */ 231 AutoMultiLock <2> alock (this->wlock(), aThat->rlock()); 232 233 /* this will back up current data */ 234 mData.assignCopy (aThat->mData); 235 } 236 237 HRESULT SerialPort::loadSettings (CFGNODE aNode, ULONG aSlot) 238 { 239 LogFlowThisFunc (("aMachine=%p\n", aNode)); 240 241 AssertReturn (aNode, E_FAIL); 163 * Loads settings from the given port node. 164 * May be called once right after this object creation. 165 * 166 * @param aPortNode <Port> node. 167 * 168 * @note Locks this object for writing. 169 */ 170 HRESULT SerialPort::loadSettings (const settings::Key &aPortNode) 171 { 172 using namespace settings; 173 174 AssertReturn (!aPortNode.isNull(), E_FAIL); 242 175 243 176 AutoCaller autoCaller (this); … … 246 179 AutoLock alock (this); 247 180 248 HRESULT rc = S_OK; 249 250 CFGNODE portNode = NULL; 251 CFGLDRGetChildNode (aNode, "Port", aSlot, &portNode); 252 253 /* slot number (required) */ 254 /* slot unicity is guaranteed by XML Schema */ 255 uint32_t uSlot = 0; 256 CFGLDRQueryUInt32 (portNode, "slot", &uSlot); 181 /* Note: we assume that the default values for attributes of optional 182 * nodes are assigned in the Data::Data() constructor and don't do it 183 * here. It implies that this method may only be called after constructing 184 * a new BIOSSettings object while all its data fields are in the default 185 * values. Exceptions are fields whose creation time defaults don't match 186 * values that should be applied when these fields are not explicitly set 187 * in the settings file (for backwards compatibility reasons). This takes 188 * place when a setting of a newly created object must default to A while 189 * the same setting of an object loaded from the old settings file must 190 * default to B. */ 191 257 192 /* enabled (required) */ 258 bool fEnabled = false; 259 CFGLDRQueryBool (portNode, "enabled", &fEnabled); 260 uint32_t uIOBase; 193 mData->mEnabled = aPortNode.value <bool> ("enabled"); 261 194 /* I/O base (required) */ 262 CFGLDRQueryUInt32 (portNode, "IOBase", &uIOBase);195 mData->mIOBase = aPortNode.value <ULONG> ("IOBase"); 263 196 /* IRQ (required) */ 264 uint32_t uIRQ; 265 CFGLDRQueryUInt32 (portNode, "IRQ", &uIRQ); 197 mData->mIRQ = aPortNode.value <ULONG> ("IRQ"); 266 198 /* host mode (required) */ 267 Bstr mode; 268 CFGLDRQueryBSTR (portNode, "hostMode", mode.asOutParam()); 269 if (mode == L"HostPipe") 199 const char *mode = aPortNode.stringValue ("hostMode"); 200 if (strcmp (mode, "HostPipe") == 0) 270 201 mData->mHostMode = PortMode_HostPipePort; 271 else if ( mode == L"HostDevice")202 else if (strcmp (mode, "HostDevice") == 0) 272 203 mData->mHostMode = PortMode_HostDevicePort; 204 else if (strcmp (mode, "Disconnected") == 0) 205 mData->mHostMode = PortMode_DisconnectedPort; 273 206 else 274 mData->mHostMode = PortMode_DisconnectedPort; 275 /* pipe/device path */ 276 Bstr path; 277 CFGLDRQueryBSTR (portNode, "path", path.asOutParam()); 278 /* server mode */ 279 bool fServer = true; 280 CFGLDRQueryBool (portNode, "server", &fServer); 281 282 mData->mEnabled = fEnabled; 283 mData->mSlot = uSlot; 284 mData->mIOBase = uIOBase; 285 mData->mIRQ = uIRQ; 286 287 rc = checkSetPath (path); 207 ComAssertMsgFailedRet (("Invalid port mode '%s'\n", mode), E_FAIL); 208 209 /* pipe/device path (optional, defaults to null) */ 210 Bstr path = aPortNode.stringValue ("path"); 211 HRESULT rc = checkSetPath (path); 288 212 CheckComRCReturnRC (rc); 289 290 mData->mPath = path; 291 mData->mServer = fServer; 292 293 return rc; 294 } 295 296 /** 297 * Saves the port settings to the given <Port> node. 298 * 299 * Note that the given node is always empty so it is not necessary to delete 300 * old values. 213 mData->mPath = path; 214 215 /* server mode (optional, defaults to false) */ 216 mData->mServer = aPortNode.value <bool> ("server"); 217 218 return S_OK; 219 } 220 221 /** 222 * Saves the port settings to the given port node. 223 * 224 * Note that the given Port node is comletely empty on input. 225 * 226 * @param aPortNode <Port> node. 301 227 * 302 * @ param aNode Node to save the settings to.303 * 304 * @return 305 */ 306 HRESULT SerialPort::saveSettings (CFGNODE aNode) 307 { 308 AssertReturn ( aNode, E_FAIL);309 310 AutoCaller autoCaller (this); 311 CheckComRCReturnRC (autoCaller.rc());312 313 AutoReaderLock alock (this); 314 315 CFGNODE portNode = 0;316 int vrc = CFGLDRAppendChildNode (aNode, "Port", &portNode);317 ComAssertRCRet (vrc, E_FAIL);318 319 const char *mode ;228 * @note Locks this object for reading. 229 */ 230 HRESULT SerialPort::saveSettings (settings::Key &aPortNode) 231 { 232 using namespace settings; 233 234 AssertReturn (!aPortNode.isNull(), E_FAIL); 235 236 AutoCaller autoCaller (this); 237 AssertComRCReturnRC (autoCaller.rc()); 238 239 AutoReaderLock alock (this); 240 241 aPortNode.setValue <bool> ("enabled", !!mData->mEnabled); 242 aPortNode.setValue <ULONG> ("IOBase", mData->mIOBase, 16); 243 aPortNode.setValue <ULONG> ("IRQ", mData->mIRQ); 244 245 const char *mode = NULL; 320 246 switch (mData->mHostMode) 321 247 { 322 default:323 248 case PortMode_DisconnectedPort: 324 249 mode = "Disconnected"; … … 330 255 mode = "HostDevice"; 331 256 break; 332 }333 CFGLDRSetUInt32 (portNode, "slot", mData->mSlot);334 CFGLDRSetBool (portNode, "enabled", !!mData->mEnabled);335 CFGLDRSetUInt32Ex (portNode, "IOBase", mData->mIOBase, 16);336 CFGLDRSetUInt32 (portNode, "IRQ", mData->mIRQ);337 CFGLDRSetString (portNode,"hostMode", mode);338 257 default: 258 ComAssertMsgFailedRet (("Invalid serial port mode: %d\n", 259 mData->mHostMode), 260 E_FAIL); 261 } 262 aPortNode.setStringValue ("hostMode", mode); 263 339 264 /* Always save non-null mPath and mServer to preserve the user values for 340 265 * later use. Note that 'server' is false by default in XML so we don't 341 266 * save it when it's false. */ 342 267 if (!mData->mPath.isEmpty()) 343 CFGLDRSetBSTR (portNode,"path", mData->mPath);268 aPortNode.setValue <Bstr> ("path", mData->mPath); 344 269 if (mData->mServer) 345 CFGLDRSetBool (portNode, "server", !!mData->mServer); 346 347 return S_OK; 270 aPortNode.setValue <bool> ("server", !!mData->mServer); 271 272 return S_OK; 273 } 274 275 /** 276 * @note Locks this object for writing. 277 */ 278 bool SerialPort::rollback() 279 { 280 /* sanity */ 281 AutoCaller autoCaller (this); 282 AssertComRCReturn (autoCaller.rc(), false); 283 284 AutoLock alock (this); 285 286 bool changed = false; 287 288 if (mData.isBackedUp()) 289 { 290 /* we need to check all data to see whether anything will be changed 291 * after rollback */ 292 changed = mData.hasActualChanges(); 293 mData.rollback(); 294 } 295 296 return changed; 297 } 298 299 /** 300 * @note Locks this object for writing, together with the peer object (also 301 * for writing) if there is one. 302 */ 303 void SerialPort::commit() 304 { 305 /* sanity */ 306 AutoCaller autoCaller (this); 307 AssertComRCReturnVoid (autoCaller.rc()); 308 309 /* sanity too */ 310 AutoCaller thatCaller (mPeer); 311 AssertComRCReturnVoid (thatCaller.rc()); 312 313 /* lock both for writing since we modify both */ 314 AutoMultiLock <2> alock (this->wlock(), AutoLock::maybeWlock (mPeer)); 315 316 if (mData.isBackedUp()) 317 { 318 mData.commit(); 319 if (mPeer) 320 { 321 /* attach new data to the peer and reshare it */ 322 mPeer->mData.attach (mData); 323 } 324 } 325 } 326 327 /** 328 * @note Locks this object for writing, together with the peer object 329 * represented by @a aThat (locked for reading). 330 */ 331 void SerialPort::copyFrom (SerialPort *aThat) 332 { 333 AssertReturnVoid (aThat != NULL); 334 335 /* sanity */ 336 AutoCaller autoCaller (this); 337 AssertComRCReturnVoid (autoCaller.rc()); 338 339 /* sanity too */ 340 AutoCaller thatCaller (mPeer); 341 AssertComRCReturnVoid (thatCaller.rc()); 342 343 /* peer is not modified, lock it for reading */ 344 AutoMultiLock <2> alock (this->wlock(), aThat->rlock()); 345 346 /* this will back up current data */ 347 mData.assignCopy (aThat->mData); 348 348 } 349 349 -
trunk/src/VBox/Main/SnapshotImpl.cpp
r5999 r6076 32 32 Snapshot::Data::Data() 33 33 { 34 mTimeStamp = 0;34 RTTimeSpecSetMilli (&mTimeStamp, 0); 35 35 }; 36 36 … … 62 62 */ 63 63 HRESULT Snapshot::init (const Guid &aId, INPTR BSTR aName, INPTR BSTR aDescription, 64 LONG64aTimeStamp, SnapshotMachine *aMachine,64 RTTIMESPEC aTimeStamp, SnapshotMachine *aMachine, 65 65 Snapshot *aParent) 66 66 { … … 249 249 CHECK_READY(); 250 250 251 *aTimeStamp = mData.mTimeStamp;251 *aTimeStamp = RTTimeSpecGetMilli (&mData.mTimeStamp); 252 252 return S_OK; 253 253 } -
trunk/src/VBox/Main/SystemPropertiesImpl.cpp
r5999 r6076 378 378 ///////////////////////////////////////////////////////////////////////////// 379 379 380 HRESULT SystemProperties::loadSettings (CFGNODE aGlobal) 381 { 380 HRESULT SystemProperties::loadSettings (const settings::Key &aGlobal) 381 { 382 using namespace settings; 383 382 384 AutoLock lock (this); 383 385 CHECK_READY(); 384 386 385 ComAssertRet (aGlobal, E_FAIL); 386 387 CFGNODE properties = NULL; 388 CFGLDRGetChildNode (aGlobal, "SystemProperties", 0, &properties); 389 ComAssertRet (properties, E_FAIL); 390 391 HRESULT rc = E_FAIL; 392 393 do 394 { 395 Bstr bstr; 396 397 CFGLDRQueryBSTR (properties, "defaultVDIFolder", 398 bstr.asOutParam()); 399 rc = setDefaultVDIFolder (bstr); 400 if (FAILED (rc)) 401 break; 402 403 CFGLDRQueryBSTR (properties, "defaultMachineFolder", 404 bstr.asOutParam()); 405 rc = setDefaultMachineFolder (bstr); 406 if (FAILED (rc)) 407 break; 408 409 CFGLDRQueryBSTR (properties, "remoteDisplayAuthLibrary", 410 bstr.asOutParam()); 411 rc = setRemoteDisplayAuthLibrary (bstr); 412 if (FAILED (rc)) 413 break; 414 415 CFGLDRQueryBSTR (properties, "webServiceAuthLibrary", 416 bstr.asOutParam()); 417 rc = setWebServiceAuthLibrary (bstr); 418 if (FAILED (rc)) 419 break; 420 421 CFGLDRQueryBool (properties, "HWVirtExEnabled", (bool*)&mHWVirtExEnabled); 422 423 uint32_t u32Count = 3; 424 CFGLDRQueryUInt32 (properties, "LogHistoryCount", &u32Count); 425 mLogHistoryCount = u32Count; 426 } 427 while (0); 428 429 CFGLDRReleaseNode (properties); 430 431 return rc; 432 } 433 434 HRESULT SystemProperties::saveSettings (CFGNODE aGlobal) 435 { 387 AssertReturn (!aGlobal.isNull(), E_FAIL); 388 389 HRESULT rc = S_OK; 390 391 Key properties = aGlobal.key ("SystemProperties"); 392 393 Bstr bstr; 394 395 bstr = properties.stringValue ("defaultVDIFolder"); 396 rc = setDefaultVDIFolder (bstr); 397 CheckComRCReturnRC (rc); 398 399 bstr = properties.stringValue ("defaultMachineFolder"); 400 rc = setDefaultMachineFolder (bstr); 401 CheckComRCReturnRC (rc); 402 403 bstr = properties.stringValue ("remoteDisplayAuthLibrary"); 404 rc = setRemoteDisplayAuthLibrary (bstr); 405 CheckComRCReturnRC (rc); 406 407 bstr = properties.stringValue ("webServiceAuthLibrary"); 408 rc = setWebServiceAuthLibrary (bstr); 409 CheckComRCReturnRC (rc); 410 411 /* Note: not <BOOL> because Win32 defines BOOL as int */ 412 mHWVirtExEnabled = properties.value <bool> ("HWVirtExEnabled"); 413 414 mLogHistoryCount = properties.value <ULONG> ("LogHistoryCount"); 415 416 return S_OK; 417 } 418 419 HRESULT SystemProperties::saveSettings (settings::Key &aGlobal) 420 { 421 using namespace settings; 422 436 423 AutoLock lock (this); 437 424 CHECK_READY(); 438 425 439 ComAssertRet (aGlobal, E_FAIL); 440 441 // first, delete the entry 442 CFGNODE properties = NULL; 443 int vrc = CFGLDRGetChildNode (aGlobal, "SystemProperties", 0, &properties); 444 if (VBOX_SUCCESS (vrc)) 445 { 446 vrc = CFGLDRDeleteNode (properties); 447 ComAssertRCRet (vrc, E_FAIL); 448 } 449 // then, recreate it 450 vrc = CFGLDRCreateChildNode (aGlobal, "SystemProperties", &properties); 451 ComAssertRCRet (vrc, E_FAIL); 426 ComAssertRet (!aGlobal.isNull(), E_FAIL); 427 428 /* first, delete the entry */ 429 Key properties = aGlobal.findKey ("SystemProperties"); 430 if (!properties.isNull()) 431 properties.zap(); 432 /* then, recreate it */ 433 properties = aGlobal.createKey ("SystemProperties"); 452 434 453 435 if (mDefaultVDIFolder) 454 CFGLDRSetBSTR (properties, "defaultVDIFolder", 455 mDefaultVDIFolder); 436 properties.setValue <Bstr> ("defaultVDIFolder", mDefaultVDIFolder); 456 437 457 438 if (mDefaultMachineFolder) 458 CFGLDRSetBSTR (properties, "defaultMachineFolder", 459 mDefaultMachineFolder); 439 properties.setValue <Bstr> ("defaultMachineFolder", mDefaultMachineFolder); 460 440 461 441 if (mRemoteDisplayAuthLibrary) 462 CFGLDRSetBSTR (properties, "remoteDisplayAuthLibrary", 463 mRemoteDisplayAuthLibrary); 442 properties.setValue <Bstr> ("remoteDisplayAuthLibrary", mRemoteDisplayAuthLibrary); 464 443 465 444 if (mWebServiceAuthLibrary) 466 CFGLDRSetBSTR (properties, "webServiceAuthLibrary", 467 mWebServiceAuthLibrary); 468 469 CFGLDRSetBool (properties, "HWVirtExEnabled", !!mHWVirtExEnabled); 470 471 CFGLDRSetUInt32 (properties, "LogHistoryCount", mLogHistoryCount); 445 properties.setValue <Bstr> ("webServiceAuthLibrary", mWebServiceAuthLibrary); 446 447 properties.setValue <bool> ("HWVirtExEnabled", !!mHWVirtExEnabled); 448 449 properties.setValue <ULONG> ("LogHistoryCount", mLogHistoryCount); 472 450 473 451 return S_OK; -
trunk/src/VBox/Main/USBControllerImpl.cpp
r5999 r6076 481 481 ///////////////////////////////////////////////////////////////////////////// 482 482 483 /** 484 * Loads settings from the configuration node. 485 * 486 * @note Locks objects for writing! 483 /** 484 * Loads settings from the given machine node. 485 * May be called once right after this object creation. 486 * 487 * @param aMachineNode <Machine> node. 488 * 489 * @note Locks this object for writing. 487 490 */ 488 HRESULT USBController::loadSettings (CFGNODE aMachine) 489 { 490 AssertReturn (aMachine, E_FAIL); 491 HRESULT USBController::loadSettings (const settings::Key &aMachineNode) 492 { 493 using namespace settings; 494 495 AssertReturn (!aMachineNode.isNull(), E_FAIL); 491 496 492 497 AutoCaller autoCaller (this); … … 495 500 AutoLock alock (this); 496 501 497 CFGNODE controller = NULL; 498 CFGLDRGetChildNode (aMachine, "USBController", 0, &controller); 499 Assert (controller); 500 501 /* enabled */ 502 bool enabled; 503 CFGLDRQueryBool (controller, "enabled", &enabled); 504 mData->mEnabled = enabled; 505 506 /* enabledEhci */ 507 CFGLDRQueryBool (controller, "enabledEhci", &enabled); 508 mData->mEnabledEhci = enabled; 502 /* Note: we assume that the default values for attributes of optional 503 * nodes are assigned in the Data::Data() constructor and don't do it 504 * here. It implies that this method may only be called after constructing 505 * a new BIOSSettings object while all its data fields are in the default 506 * values. Exceptions are fields whose creation time defaults don't match 507 * values that should be applied when these fields are not explicitly set 508 * in the settings file (for backwards compatibility reasons). This takes 509 * place when a setting of a newly created object must default to A while 510 * the same setting of an object loaded from the old settings file must 511 * default to B. */ 512 513 /* USB Controller node (required) */ 514 Key controller = aMachineNode.key ("USBController"); 515 516 /* enabled (required) */ 517 mData->mEnabled = controller.value <bool> ("enabled"); 518 519 /* enabledEhci (optiona, defaults to false) */ 520 mData->mEnabledEhci = controller.value <bool> ("enabledEhci"); 509 521 510 522 HRESULT rc = S_OK; 511 523 512 unsigned filterCount = 0; 513 CFGLDRCountChildren (controller, "DeviceFilter", &filterCount); 514 for (unsigned i = 0; i < filterCount && SUCCEEDED (rc); i++) 515 { 516 CFGNODE filter = NULL; 517 CFGLDRGetChildNode (controller, "DeviceFilter", i, &filter); 518 Assert (filter); 519 520 Bstr name; 521 CFGLDRQueryBSTR (filter, "name", name.asOutParam()); 522 bool active; 523 CFGLDRQueryBool (filter, "active", &active); 524 525 Bstr vendorId; 526 CFGLDRQueryBSTR (filter, "vendorid", vendorId.asOutParam()); 527 Bstr productId; 528 CFGLDRQueryBSTR (filter, "productid", productId.asOutParam()); 529 Bstr revision; 530 CFGLDRQueryBSTR (filter, "revision", revision.asOutParam()); 531 Bstr manufacturer; 532 CFGLDRQueryBSTR (filter, "manufacturer", manufacturer.asOutParam()); 533 Bstr product; 534 CFGLDRQueryBSTR (filter, "product", product.asOutParam()); 535 Bstr serialNumber; 536 CFGLDRQueryBSTR (filter, "serialnumber", serialNumber.asOutParam()); 537 Bstr port; 538 CFGLDRQueryBSTR (filter, "port", port.asOutParam()); 539 Bstr remote; 540 CFGLDRQueryBSTR (filter, "remote", remote.asOutParam()); 541 uint32_t maskedIfs; 542 if (RT_FAILURE(CFGLDRQueryUInt32 (filter, "maskedInterfaces", &maskedIfs))) 543 maskedIfs = 0; 524 Key::List children = controller.keys ("DeviceFilter"); 525 for (Key::List::const_iterator it = children.begin(); 526 it != children.end(); ++ it) 527 { 528 /* required */ 529 Bstr name = (*it).stringValue ("name"); 530 bool active = (*it).value <bool> ("active"); 531 532 /* optional */ 533 Bstr vendorId = (*it).stringValue ("vendorid"); 534 Bstr productId = (*it).stringValue ("productid"); 535 Bstr revision = (*it).stringValue ("revision"); 536 Bstr manufacturer = (*it).stringValue ("manufacturer"); 537 Bstr product = (*it).stringValue ("product"); 538 Bstr serialNumber = (*it).stringValue ("serialnumber"); 539 Bstr port = (*it).stringValue ("port"); 540 Bstr remote = (*it).stringValue ("remote"); 541 ULONG maskedIfs = (*it).value <ULONG> ("maskedInterfaces"); 544 542 545 543 ComObjPtr <USBDeviceFilter> filterObj; … … 550 548 port, remote, maskedIfs); 551 549 /* error info is set by init() when appropriate */ 552 if (SUCCEEDED (rc)) 553 { 554 mDeviceFilters->push_back (filterObj); 555 filterObj->mInList = true; 556 } 557 558 CFGLDRReleaseNode (filter); 559 } 560 561 CFGLDRReleaseNode (controller); 562 563 return rc; 564 } 565 566 /** 567 * Saves settings to the configuration node. 568 * 569 * @note Locks objects for reading! 550 CheckComRCReturnRC (rc); 551 552 mDeviceFilters->push_back (filterObj); 553 filterObj->mInList = true; 554 } 555 556 return S_OK; 557 } 558 559 /** 560 * Saves settings to the given machine node. 561 * 562 * @param aMachineNode <Machine> node. 563 * 564 * @note Locks this object for reading. 570 565 */ 571 HRESULT USBController::saveSettings (CFGNODE aMachine) 572 { 573 AssertReturn (aMachine, E_FAIL); 566 HRESULT USBController::saveSettings (settings::Key &aMachineNode) 567 { 568 using namespace settings; 569 570 AssertReturn (!aMachineNode.isNull(), E_FAIL); 574 571 575 572 AutoCaller autoCaller (this); … … 579 576 580 577 /* first, delete the entry */ 581 CFGNODE controller = NULL; 582 int vrc = CFGLDRGetChildNode (aMachine, "USBController", 0, &controller); 583 if (VBOX_SUCCESS (vrc)) 584 { 585 vrc = CFGLDRDeleteNode (controller); 586 ComAssertRCRet (vrc, E_FAIL); 587 } 578 Key controller = aMachineNode.findKey ("USBController"); 579 if (!controller.isNull()) 580 controller.zap(); 588 581 /* then, recreate it */ 589 vrc = CFGLDRCreateChildNode (aMachine, "USBController", &controller); 590 ComAssertRCRet (vrc, E_FAIL); 582 controller = aMachineNode.createKey ("USBController"); 591 583 592 584 /* enabled */ 593 CFGLDRSetBool (controller,"enabled", !!mData->mEnabled);585 controller.setValue <bool> ("enabled", !!mData->mEnabled); 594 586 595 587 /* enabledEhci */ 596 CFGLDRSetBool (controller,"enabledEhci", !!mData->mEnabledEhci);588 controller.setValue <bool> ("enabledEhci", !!mData->mEnabledEhci); 597 589 598 590 DeviceFilterList::const_iterator it = mDeviceFilters->begin(); … … 602 594 const USBDeviceFilter::Data &data = (*it)->data(); 603 595 604 CFGNODE filter = NULL; 605 CFGLDRAppendChildNode (controller, "DeviceFilter", &filter); 606 607 CFGLDRSetBSTR (filter, "name", data.mName); 608 CFGLDRSetBool (filter, "active", !!data.mActive); 596 Key filter = controller.appendKey ("DeviceFilter"); 597 598 filter.setValue <Bstr> ("name", data.mName); 599 filter.setValue <bool> ("active", !!data.mActive); 609 600 610 601 /* all are optional */ 611 602 #ifndef VBOX_WITH_USBFILTER 603 612 604 if (data.mVendorId.string()) 613 CFGLDRSetBSTR (filter,"vendorid", data.mVendorId.string());605 filter.setValue <Bstr> ("vendorid", data.mVendorId.string()); 614 606 if (data.mProductId.string()) 615 CFGLDRSetBSTR (filter,"productid", data.mProductId.string());607 filter.setValue <Bstr> ("productid", data.mProductId.string()); 616 608 if (data.mRevision.string()) 617 CFGLDRSetBSTR (filter,"revision", data.mRevision.string());609 filter.setValue <Bstr> ("revision", data.mRevision.string()); 618 610 if (data.mManufacturer.string()) 619 CFGLDRSetBSTR (filter,"manufacturer", data.mManufacturer.string());611 filter.setValue <Bstr> ("manufacturer", data.mManufacturer.string()); 620 612 if (data.mProduct.string()) 621 CFGLDRSetBSTR (filter,"product", data.mProduct.string());613 filter.setValue <Bstr> ("product", data.mProduct.string()); 622 614 if (data.mSerialNumber.string()) 623 CFGLDRSetBSTR (filter,"serialnumber", data.mSerialNumber.string());615 filter.setValue <Bstr> ("serialnumber", data.mSerialNumber.string()); 624 616 if (data.mPort.string()) 625 CFGLDRSetBSTR (filter,"port", data.mPort.string());617 filter.setValue <Bstr> ("port", data.mPort.string()); 626 618 if (data.mRemote.string()) 627 CFGLDRSetBSTR (filter,"remote", data.mRemote.string());619 filter.setValue <Bstr> ("remote", data.mRemote.string()); 628 620 629 621 #else /* VBOX_WITH_USBFILTER */ 622 630 623 Bstr str; 631 624 (*it)->COMGETTER (VendorId) (str.asOutParam()); 632 625 if (!str.isNull()) 633 CFGLDRSetBSTR (filter,"vendorid", str);626 filter.setValue <Bstr> ("vendorid", str); 634 627 635 628 (*it)->COMGETTER (ProductId) (str.asOutParam()); 636 629 if (!str.isNull()) 637 CFGLDRSetBSTR (filter,"productid", str);630 filter.setValue <Bstr> ("productid", str); 638 631 639 632 (*it)->COMGETTER (Revision) (str.asOutParam()); 640 633 if (!str.isNull()) 641 CFGLDRSetBSTR (filter,"revision", str);634 filter.setValue <Bstr> ("revision", str); 642 635 643 636 (*it)->COMGETTER (Manufacturer) (str.asOutParam()); 644 637 if (!str.isNull()) 645 CFGLDRSetBSTR (filter,"manufacturer", str);638 filter.setValue <Bstr> ("manufacturer", str); 646 639 647 640 (*it)->COMGETTER (Product) (str.asOutParam()); 648 641 if (!str.isNull()) 649 CFGLDRSetBSTR (filter,"product", str);642 filter.setValue <Bstr> ("product", str); 650 643 651 644 (*it)->COMGETTER (SerialNumber) (str.asOutParam()); 652 645 if (!str.isNull()) 653 CFGLDRSetBSTR (filter,"serialnumber", str);646 filter.setValue <Bstr> ("serialnumber", str); 654 647 655 648 (*it)->COMGETTER (Port) (str.asOutParam()); 656 649 if (!str.isNull()) 657 CFGLDRSetBSTR (filter,"port", str);650 filter.setValue <Bstr> ("port", str); 658 651 659 652 if (data.mRemote.string()) 660 CFGLDRSetBSTR (filter, "remote", data.mRemote.string()); 653 filter.setValue <Bstr> ("remote", data.mRemote.string()); 654 661 655 #endif /* VBOX_WITH_USBFILTER */ 662 656 663 657 if (data.mMaskedIfs) 664 CFGLDRSetUInt32 (filter, "maskedInterfaces", data.mMaskedIfs); 665 666 CFGLDRReleaseNode (filter); 658 filter.setValue <ULONG> ("maskedInterfaces", data.mMaskedIfs); 667 659 668 660 ++ it; 669 661 } 670 671 CFGLDRReleaseNode (controller);672 662 673 663 return S_OK; -
trunk/src/VBox/Main/VBoxDll.cpp
r5999 r6076 21 21 *******************************************************************************/ 22 22 #include <iprt/assert.h> 23 #undef CFGLDR_HAVE_COM24 #include <VBox/cfgldr.h>25 23 26 24 void __reference_stuff(void); -
trunk/src/VBox/Main/VirtualBoxBase.cpp
r5999 r6076 1 /* $Id$ */ 2 1 3 /** @file 2 4 * … … 930 932 } 931 933 934 #if defined VBOX_MAIN_SETTINGS_ADDONS 935 936 // Settings API additions 937 //////////////////////////////////////////////////////////////////////////////// 938 939 namespace settings 940 { 941 942 template<> stdx::char_auto_ptr 943 ToString <com::Bstr> (const com::Bstr &aValue, unsigned int aExtra) 944 { 945 stdx::char_auto_ptr result; 946 947 if (aValue.raw() == NULL) 948 throw ENoValue(); 949 950 /* The only way to cause RTUtf16ToUtf8Ex return a number of bytes needed 951 * w/o allocating the result buffer itself is to provide that both cch 952 * and *ppsz are not NULL. */ 953 char dummy [1]; 954 char *dummy2 = dummy; 955 size_t strLen = 1; 956 957 int vrc = RTUtf16ToUtf8Ex (aValue.raw(), RTSTR_MAX, 958 &dummy2, strLen, &strLen); 959 if (RT_SUCCESS (vrc)) 960 { 961 /* the string only contains '\0' :) */ 962 result.reset (new char [1]); 963 result.get() [0] = '\0'; 964 return result; 965 } 966 967 if (vrc == VERR_BUFFER_OVERFLOW) 968 { 969 result.reset (new char [strLen + 1]); 970 char *buf = result.get(); 971 vrc = RTUtf16ToUtf8Ex (aValue.raw(), RTSTR_MAX, &buf, strLen + 1, NULL); 972 } 973 974 if (RT_FAILURE (vrc)) 975 throw LogicError (RT_SRC_POS); 976 977 return result; 978 } 979 980 template<> com::Guid FromString <com::Guid> (const char *aValue) 981 { 982 if (aValue == NULL) 983 throw ENoValue(); 984 985 /* For settings, the format is always {XXX...XXX} */ 986 char buf [RTUUID_STR_LENGTH]; 987 if (aValue == NULL || *aValue != '{' || 988 strlen (aValue) != RTUUID_STR_LENGTH + 1 || 989 aValue [RTUUID_STR_LENGTH] != '}') 990 throw ENoConversion (FmtStr ("'%s' is not Guid", aValue)); 991 992 /* strip { and } */ 993 memcpy (buf, aValue + 1, RTUUID_STR_LENGTH - 1); 994 buf [RTUUID_STR_LENGTH - 1] = '\0'; 995 /* we don't use Guid (const char *) because we want to throw 996 * ENoConversion on format error */ 997 RTUUID uuid; 998 int vrc = RTUuidFromStr (&uuid, buf); 999 if (RT_FAILURE (vrc)) 1000 throw ENoConversion (FmtStr ("'%s' is not Guid (%Vrc)", aValue, vrc)); 1001 1002 return com::Guid (uuid); 1003 } 1004 1005 template<> stdx::char_auto_ptr 1006 ToString <com::Guid> (const com::Guid &aValue, unsigned int aExtra) 1007 { 1008 /* For settings, the format is always {XXX...XXX} */ 1009 stdx::char_auto_ptr result (new char [RTUUID_STR_LENGTH + 2]); 1010 1011 int vrc = RTUuidToStr (aValue.raw(), result.get() + 1, RTUUID_STR_LENGTH); 1012 if (RT_FAILURE (vrc)) 1013 throw LogicError (RT_SRC_POS); 1014 1015 result.get() [0] = '{'; 1016 result.get() [RTUUID_STR_LENGTH] = '}'; 1017 result.get() [RTUUID_STR_LENGTH + 1] = '\0'; 1018 1019 return result; 1020 } 1021 1022 } /* namespace settings */ 1023 1024 #endif /* VBOX_MAIN_SETTINGS_ADDONS */ -
trunk/src/VBox/Main/VirtualBoxImpl.cpp
r5999 r6076 26 26 #include "USBControllerImpl.h" 27 27 #include "SystemPropertiesImpl.h" 28 #include "GuestOSTypeImpl.h" 29 30 #include "VirtualBoxXMLUtil.h" 31 28 32 #include "Logging.h" 29 30 #include "GuestOSTypeImpl.h"31 33 32 34 #ifdef RT_OS_WINDOWS … … 59 61 #include <set> 60 62 #include <memory> // for auto_ptr 63 64 #include <typeinfo> 61 65 62 66 // defines … … 187 191 } 188 192 189 /* initialize our Xerces XML subsystem */190 193 if (SUCCEEDED (rc)) 191 194 { 192 int vrc = CFGLDRInitialize(); 193 if (VBOX_FAILURE (vrc)) 194 rc = setError (E_FAIL, tr ("Could not initialize the XML parser (%Vrc)"), 195 vrc); 196 } 197 198 if (SUCCEEDED (rc)) 199 { 200 CFGHANDLE configLoader = NULL; 201 char *loaderError = NULL; 202 203 /* load the config file */ 204 int vrc = CFGLDRLoad (&configLoader, vboxConfigFile, mData.mCfgFile.mHandle, 205 XmlSchemaNS, true, cfgLdrEntityResolver, 206 &loaderError); 207 if (VBOX_SUCCESS (vrc)) 208 { 209 CFGNODE global = NULL; 210 CFGLDRGetNode (configLoader, "VirtualBox/Global", 0, &global); 211 Assert (global); 212 213 do 214 { 215 /* create the host object early, machines will need it */ 216 unconst (mData.mHost).createObject(); 217 rc = mData.mHost->init (this); 218 ComAssertComRCBreak (rc, rc = rc); 219 220 unconst (mData.mSystemProperties).createObject(); 221 rc = mData.mSystemProperties->init (this); 222 ComAssertComRCBreak (rc, rc = rc); 223 224 rc = loadDisks (global); 225 CheckComRCBreakRC ((rc)); 226 227 /* guest OS type objects, needed by the machines */ 228 rc = registerGuestOSTypes(); 229 ComAssertComRCBreak (rc, rc = rc); 230 231 /* machines */ 232 rc = loadMachines (global); 233 CheckComRCBreakRC ((rc)); 234 235 /* host data (USB filters) */ 236 rc = mData.mHost->loadSettings (global); 237 CheckComRCBreakRC ((rc)); 238 239 rc = mData.mSystemProperties->loadSettings (global); 240 CheckComRCBreakRC ((rc)); 241 242 /* check hard disk consistency */ 195 try 196 { 197 using namespace settings; 198 199 File file (File::ReadWrite, mData.mCfgFile.mHandle, vboxConfigFile); 200 XmlTreeBackend tree; 201 202 rc = VirtualBox::loadSettingsTree_FirstTime (tree, file); 203 CheckComRCThrowRC (rc); 204 205 Key global = tree.rootKey().key ("Global"); 206 207 /* create the host object early, machines will need it */ 208 unconst (mData.mHost).createObject(); 209 rc = mData.mHost->init (this); 210 ComAssertComRCThrowRC (rc); 211 212 rc = mData.mHost->loadSettings (global); 213 CheckComRCThrowRC (rc); 214 215 /* create the system properties object */ 216 unconst (mData.mSystemProperties).createObject(); 217 rc = mData.mSystemProperties->init (this); 218 ComAssertComRCThrowRC (rc); 219 220 rc = mData.mSystemProperties->loadSettings (global); 221 CheckComRCThrowRC (rc); 222 223 /* guest OS type objects, needed by machines */ 224 rc = registerGuestOSTypes(); 225 ComAssertComRCThrowRC (rc); 226 227 /* hard disks, needed by machines */ 228 rc = loadDisks (global); 229 CheckComRCThrowRC (rc); 230 231 /* machines */ 232 rc = loadMachines (global); 233 CheckComRCThrowRC (rc); 234 235 /* check hard disk consistency */ 243 236 /// @todo (r=dmik) add IVirtualBox::cleanupHardDisks() instead or similar 244 // for (HardDiskList::const_iterator it = mData.mHardDisks.begin(); 245 // it != mData.mHardDisks.end() && SUCCEEDED (rc); 246 // ++ it) 247 // { 248 // rc = (*it)->checkConsistency(); 249 // } 250 // CheckComRCBreakRC ((rc)); 251 } 252 while (0); 237 // for (HardDiskList::const_iterator it = mData.mHardDisks.begin(); 238 // it != mData.mHardDisks.end() && SUCCEEDED (rc); 239 // ++ it) 240 // { 241 // rc = (*it)->checkConsistency(); 242 // } 243 // CheckComRCBreakRC ((rc)); 253 244 254 245 /// @todo (dmik) if successful, check for orphan (unused) diffs 255 // that might be left because of the server crash, and remove them. 256 257 CFGLDRReleaseNode (global); 258 CFGLDRFree(configLoader); 259 } 260 else 261 { 262 rc = setError (E_FAIL, 263 tr ("Could not load the settings file '%ls' (%Vrc)%s%s"), 264 mData.mCfgFile.mName.raw(), vrc, 265 loaderError ? ".\n" : "", loaderError ? loaderError : ""); 266 } 267 268 if (loaderError) 269 RTMemTmpFree (loaderError); 246 // that might be left because of the server crash, and remove 247 // Hmm, is it the same remark as above?.. 248 } 249 catch (HRESULT err) 250 { 251 /* we assume that error info is set by the thrower */ 252 rc = err; 253 } 254 catch (...) 255 { 256 rc = VirtualBox::handleUnexpectedExceptions (RT_SRC_POS); 257 } 270 258 } 271 259 … … 436 424 #endif 437 425 438 /* uninitialize the Xerces XML subsystem */439 CFGLDRShutdown();440 441 426 LogFlowThisFuncLeave(); 442 427 LogFlow (("===========================================================\n")); … … 914 899 915 900 /* save the global registry */ 916 rc = save Config();901 rc = saveSettings(); 917 902 918 903 /* return the unregistered machine to the caller */ … … 1365 1350 1366 1351 /* save the global config file */ 1367 rc = save Config();1352 rc = saveSettings(); 1368 1353 1369 1354 if (SUCCEEDED (rc)) … … 1534 1519 1535 1520 /* save the global config file */ 1536 rc = save Config();1521 rc = saveSettings(); 1537 1522 if (SUCCEEDED (rc)) 1538 1523 { … … 1604 1589 } 1605 1590 1606 /** @note Locks this object for reading. */ 1591 /** 1592 * @note Locks this object for reading. 1593 */ 1607 1594 STDMETHODIMP VirtualBox:: 1608 1595 GetNextExtraDataKey (INPTR BSTR aKey, BSTR *aNextKey, BSTR *aNextValue) … … 1616 1603 /* start with nothing found */ 1617 1604 *aNextKey = NULL; 1605 if (aNextValue) 1606 *aNextValue = NULL; 1618 1607 1619 1608 HRESULT rc = S_OK; 1620 1609 1621 /* serialize file access */1610 /* serialize config file access */ 1622 1611 AutoReaderLock alock (this); 1623 1612 1624 CFGHANDLE configLoader; 1625 1626 /* load the config file */ 1627 int vrc = CFGLDRLoad (&configLoader, Utf8Str (mData.mCfgFile.mName), 1628 mData.mCfgFile.mHandle, 1629 XmlSchemaNS, true, cfgLdrEntityResolver, NULL); 1630 ComAssertRCRet (vrc, E_FAIL); 1631 1632 CFGNODE extraDataNode; 1633 1634 /* navigate to the right position */ 1635 if (VBOX_SUCCESS (CFGLDRGetNode (configLoader, 1636 "VirtualBox/Global/ExtraData", 0, 1637 &extraDataNode))) 1638 { 1639 /* check if it exists */ 1640 bool found = false; 1641 unsigned count; 1642 CFGNODE extraDataItemNode; 1643 CFGLDRCountChildren (extraDataNode, "ExtraDataItem", &count); 1644 for (unsigned i = 0; (i < count) && (found == false); i++) 1645 { 1646 Bstr name; 1647 CFGLDRGetChildNode (extraDataNode, "ExtraDataItem", i, &extraDataItemNode); 1648 CFGLDRQueryBSTR (extraDataItemNode, "name", name.asOutParam()); 1649 1650 /* if we're supposed to return the first one */ 1651 if (aKey == NULL) 1613 try 1614 { 1615 using namespace settings; 1616 1617 /* load the config file */ 1618 File file (File::ReadWrite, mData.mCfgFile.mHandle, 1619 Utf8Str (mData.mCfgFile.mName)); 1620 XmlTreeBackend tree; 1621 1622 rc = VirtualBox::loadSettingsTree_Again (tree, file); 1623 CheckComRCReturnRC (rc); 1624 1625 Key globalNode = tree.rootKey().key ("Global"); 1626 Key extraDataNode = tree.rootKey().findKey ("ExtraData"); 1627 1628 if (!extraDataNode.isNull()) 1629 { 1630 Key::List items = extraDataNode.keys ("ExtraDataItem"); 1631 if (items.size()) 1652 1632 { 1653 name.cloneTo (aNextKey); 1654 if (aNextValue) 1655 CFGLDRQueryBSTR (extraDataItemNode, "value", aNextValue); 1656 found = true; 1657 } 1658 /* did we find the key we're looking for? */ 1659 else if (name == aKey) 1660 { 1661 found = true; 1662 /* is there another item? */ 1663 if (i + 1 < count) 1633 for (Key::List::const_iterator it = items.begin(); 1634 it != items.end(); ++ it) 1664 1635 { 1665 CFGLDRGetChildNode (extraDataNode, "ExtraDataItem", i + 1, 1666 &extraDataItemNode); 1667 CFGLDRQueryBSTR (extraDataItemNode, "name", name.asOutParam()); 1668 name.cloneTo (aNextKey); 1669 if (aNextValue) 1670 CFGLDRQueryBSTR (extraDataItemNode, "value", aNextValue); 1671 found = true; 1672 } 1673 else 1674 { 1675 /* it's the last one */ 1676 *aNextKey = NULL; 1636 Bstr key = (*it).stringValue ("name"); 1637 1638 /* if we're supposed to return the first one */ 1639 if (aKey == NULL) 1640 { 1641 key.cloneTo (aNextKey); 1642 if (aNextValue) 1643 { 1644 Bstr val = (*it).stringValue ("value"); 1645 val.cloneTo (aNextValue); 1646 } 1647 return S_OK; 1648 } 1649 1650 /* did we find the key we're looking for? */ 1651 if (key == aKey) 1652 { 1653 ++ it; 1654 /* is there another item? */ 1655 if (it != items.end()) 1656 { 1657 Bstr key = (*it).stringValue ("name"); 1658 key.cloneTo (aNextKey); 1659 if (aNextValue) 1660 { 1661 Bstr val = (*it).stringValue ("value"); 1662 val.cloneTo (aNextValue); 1663 } 1664 } 1665 /* else it's the last one, arguments are already NULL */ 1666 return S_OK; 1667 } 1677 1668 } 1678 1669 } 1679 CFGLDRReleaseNode (extraDataItemNode); 1680 } 1681 1682 /* if we haven't found the key, it's an error */ 1683 if (!found) 1684 rc = setError (E_FAIL, 1685 tr ("Could not find extra data key '%ls'"), aKey); 1686 1687 CFGLDRReleaseNode (extraDataNode); 1688 } 1689 1690 CFGLDRFree (configLoader); 1691 1692 return rc; 1693 } 1694 1695 /** @note Locks this object for reading. */ 1670 } 1671 1672 /* Here we are when a) there are no items at all or b) there are items 1673 * but none of them equals to the requested non-NULL key. b) is an 1674 * error as well as a) if the key is non-NULL. When the key is NULL 1675 * (which is the case only when there are no items), we just fall 1676 * through to return NULLs and S_OK. */ 1677 1678 if (aKey != NULL) 1679 return setError (E_FAIL, 1680 tr ("Could not find the extra data key '%ls'"), aKey); 1681 } 1682 catch (...) 1683 { 1684 rc = VirtualBox::handleUnexpectedExceptions (RT_SRC_POS); 1685 } 1686 1687 return rc; 1688 } 1689 1690 /** 1691 * @note Locks this object for reading. 1692 */ 1696 1693 STDMETHODIMP VirtualBox::GetExtraData (INPTR BSTR aKey, BSTR *aValue) 1697 1694 { 1698 if (!aKey || !(*aKey))1695 if (!aKey) 1699 1696 return E_INVALIDARG; 1700 1697 if (!aValue) … … 1712 1709 AutoReaderLock alock (this); 1713 1710 1714 CFGHANDLE configLoader; 1715 1716 /* load the config file */ 1717 int vrc = CFGLDRLoad (&configLoader, Utf8Str (mData.mCfgFile.mName), 1718 mData.mCfgFile.mHandle, 1719 XmlSchemaNS, true, cfgLdrEntityResolver, NULL); 1720 ComAssertRCRet (vrc, E_FAIL); 1721 1722 CFGNODE extraDataNode; 1723 1724 /* navigate to the right position */ 1725 if (VBOX_SUCCESS (CFGLDRGetNode (configLoader, 1726 "VirtualBox/Global/ExtraData", 0, 1727 &extraDataNode))) 1728 { 1729 /* check if it exists */ 1730 bool found = false; 1731 unsigned count; 1732 CFGNODE extraDataItemNode; 1733 CFGLDRCountChildren (extraDataNode, "ExtraDataItem", &count); 1734 for (unsigned i = 0; (i < count) && (found == false); i++) 1735 { 1736 Bstr name; 1737 CFGLDRGetChildNode (extraDataNode, "ExtraDataItem", i, &extraDataItemNode); 1738 CFGLDRQueryBSTR (extraDataItemNode, "name", name.asOutParam()); 1739 if (name == aKey) 1711 try 1712 { 1713 using namespace settings; 1714 1715 /* load the config file */ 1716 File file (File::ReadWrite, mData.mCfgFile.mHandle, 1717 Utf8Str (mData.mCfgFile.mName)); 1718 XmlTreeBackend tree; 1719 1720 rc = VirtualBox::loadSettingsTree_Again (tree, file); 1721 CheckComRCReturnRC (rc); 1722 1723 const Utf8Str key = aKey; 1724 1725 Key globalNode = tree.rootKey().key ("Global"); 1726 Key extraDataNode = globalNode.findKey ("ExtraData"); 1727 1728 if (!extraDataNode.isNull()) 1729 { 1730 /* check if the key exists */ 1731 Key::List items = extraDataNode.keys ("ExtraDataItem"); 1732 for (Key::List::const_iterator it = items.begin(); 1733 it != items.end(); ++ it) 1740 1734 { 1741 found = true; 1742 CFGLDRQueryBSTR (extraDataItemNode, "value", aValue); 1735 if (key == (*it).stringValue ("name")) 1736 { 1737 Bstr val = (*it).stringValue ("value"); 1738 val.cloneTo (aValue); 1739 break; 1740 } 1743 1741 } 1744 CFGLDRReleaseNode (extraDataItemNode); 1745 } 1746 1747 CFGLDRReleaseNode (extraDataNode); 1748 } 1749 1750 CFGLDRFree (configLoader); 1751 1752 return rc; 1753 } 1754 1755 /** @note Locks this object for writing. */ 1756 STDMETHODIMP VirtualBox::SetExtraData(INPTR BSTR aKey, INPTR BSTR aValue) 1742 } 1743 } 1744 catch (...) 1745 { 1746 rc = VirtualBox::handleUnexpectedExceptions (RT_SRC_POS); 1747 } 1748 1749 return rc; 1750 } 1751 1752 /** 1753 * @note Locks this object for writing. 1754 */ 1755 STDMETHODIMP VirtualBox::SetExtraData (INPTR BSTR aKey, INPTR BSTR aValue) 1757 1756 { 1758 1757 if (!aKey) 1759 return E_ POINTER;1758 return E_INVALIDARG; 1760 1759 1761 1760 AutoCaller autoCaller (this); … … 1770 1769 AutoLock alock (this); 1771 1770 1772 CFGHANDLE configLoader; 1773 1774 /* load the config file */ 1775 int vrc = CFGLDRLoad (&configLoader, Utf8Str (mData.mCfgFile.mName), 1776 mData.mCfgFile.mHandle, 1777 XmlSchemaNS, true, cfgLdrEntityResolver, NULL); 1778 ComAssertRCRet (vrc, E_FAIL); 1779 1780 CFGNODE extraDataNode = 0; 1781 1782 vrc = CFGLDRGetNode (configLoader, "VirtualBox/Global/ExtraData", 0, 1783 &extraDataNode); 1784 if (VBOX_FAILURE (vrc) && aValue) 1785 vrc = CFGLDRCreateNode (configLoader, "VirtualBox/Global/ExtraData", 1786 &extraDataNode); 1787 1788 if (extraDataNode) 1789 { 1790 CFGNODE extraDataItemNode = 0; 1771 try 1772 { 1773 using namespace settings; 1774 1775 /* load the config file */ 1776 File file (File::ReadWrite, mData.mCfgFile.mHandle, 1777 Utf8Str (mData.mCfgFile.mName)); 1778 XmlTreeBackend tree; 1779 1780 rc = VirtualBox::loadSettingsTree_ForUpdate (tree, file); 1781 CheckComRCReturnRC (rc); 1782 1783 const Utf8Str key = aKey; 1791 1784 Bstr oldVal; 1792 1785 1793 unsigned count;1794 CFGLDRCountChildren (extraDataNode, "ExtraDataItem", &count);1795 1796 for (unsigned i = 0; i < count; i++) 1797 {1798 CFGLDRGetChildNode (extraDataNode, "ExtraDataItem", i, &extraDataItemNode);1799 Bstr name;1800 CFGLDRQueryBSTR (extraDataItemNode, "name", name.asOutParam());1801 if ( name == aKey)1786 Key globalNode = tree.rootKey().key ("Global"); 1787 Key extraDataNode = globalNode.createKey ("ExtraData"); 1788 Key extraDataItemNode; 1789 1790 Key::List items = extraDataNode.keys ("ExtraDataItem"); 1791 for (Key::List::const_iterator it = items.begin(); 1792 it != items.end(); ++ it) 1793 { 1794 if (key == (*it).stringValue ("name")) 1802 1795 { 1803 CFGLDRQueryBSTR (extraDataItemNode, "value", oldVal.asOutParam()); 1796 extraDataItemNode = *it; 1797 oldVal = (*it).stringValue ("value"); 1804 1798 break; 1805 1799 } 1806 CFGLDRReleaseNode (extraDataItemNode); 1807 extraDataItemNode = 0; 1808 } 1809 1810 /* 1811 * When no key is found, oldVal is null. Note: 1812 * 1. when oldVal is null, |oldVal == (BSTR) NULL| is true 1813 * 2. we cannot do |oldVal != value| because it will compare 1814 * BSTR pointers instead of strings (due to type conversion ops) 1815 */ 1816 changed = !(oldVal == aValue); 1800 } 1801 1802 /* When no key is found, oldVal is null */ 1803 changed = oldVal != aValue; 1817 1804 1818 1805 if (changed) … … 1820 1807 /* ask for permission from all listeners */ 1821 1808 Bstr error; 1822 if (!onExtraDataCanChange ( emptyGuid, aKey, aValue, error))1809 if (!onExtraDataCanChange (Guid::Empty, aKey, aValue, error)) 1823 1810 { 1824 1811 const char *sep = error.isEmpty() ? "" : ": "; … … 1826 1813 LogWarningFunc (("Someone vetoed! Change refused%s%ls\n", 1827 1814 sep, err)); 1828 r c =setError (E_ACCESSDENIED,1815 return setError (E_ACCESSDENIED, 1829 1816 tr ("Could not set extra data because someone refused " 1830 1817 "the requested change of '%ls' to '%ls'%s%ls"), 1831 1818 aKey, aValue, sep, err); 1832 1819 } 1820 1821 if (aValue != NULL) 1822 { 1823 if (extraDataItemNode.isNull()) 1824 { 1825 extraDataItemNode = extraDataNode.appendKey ("ExtraDataItem"); 1826 extraDataItemNode.setStringValue ("name", key); 1827 } 1828 extraDataItemNode.setStringValue ("value", Utf8Str (aValue)); 1829 } 1833 1830 else 1834 1831 { 1835 if (aValue) 1836 { 1837 if (!extraDataItemNode) 1838 { 1839 /* create a new item */ 1840 CFGLDRAppendChildNode (extraDataNode, "ExtraDataItem", 1841 &extraDataItemNode); 1842 CFGLDRSetBSTR (extraDataItemNode, "name", aKey); 1843 } 1844 CFGLDRSetBSTR (extraDataItemNode, "value", aValue); 1845 } 1846 else 1847 { 1848 /* an old value does for sure exist here */ 1849 CFGLDRDeleteNode (extraDataItemNode); 1850 extraDataItemNode = 0; 1851 } 1832 /* an old value does for sure exist here (XML schema 1833 * guarantees that "value" may not absent in the 1834 * <ExtraDataItem> element) */ 1835 Assert (!extraDataItemNode.isNull()); 1836 extraDataItemNode.zap(); 1852 1837 } 1853 } 1854 1855 if (extraDataItemNode) 1856 CFGLDRReleaseNode (extraDataItemNode); 1857 1858 CFGLDRReleaseNode (extraDataNode); 1859 1860 if (SUCCEEDED (rc) && changed) 1861 { 1862 char *loaderError = NULL; 1863 vrc = CFGLDRSave (configLoader, &loaderError); 1864 if (VBOX_FAILURE (vrc)) 1865 { 1866 rc = setError (E_FAIL, 1867 tr ("Could not save the settings file '%ls' (%Vrc)%s%s"), 1868 mData.mCfgFile.mName.raw(), vrc, 1869 loaderError ? ".\n" : "", loaderError ? loaderError : ""); 1870 if (loaderError) 1871 RTMemTmpFree (loaderError); 1872 } 1873 } 1874 } 1875 1876 CFGLDRFree (configLoader); 1877 1878 /* notification handling */ 1838 1839 /* save settings on success */ 1840 rc = VirtualBox::saveSettingsTree (tree, file); 1841 CheckComRCReturnRC (rc); 1842 } 1843 } 1844 catch (...) 1845 { 1846 rc = VirtualBox::handleUnexpectedExceptions (RT_SRC_POS); 1847 } 1848 1849 /* fire a notification */ 1879 1850 if (SUCCEEDED (rc) && changed) 1880 onExtraDataChange ( emptyGuid, aKey, aValue);1851 onExtraDataChange (Guid::Empty, aKey, aValue); 1881 1852 1882 1853 return rc; … … 3398 3369 * and creates the relevant objects. 3399 3370 * 3371 * @param aGlobal <Global> node. 3372 * 3400 3373 * @note Can be called only from #init(). 3401 3374 * @note Doesn't lock anything. 3402 3375 */ 3403 HRESULT VirtualBox::loadMachines (CFGNODE aGlobal) 3404 { 3376 HRESULT VirtualBox::loadMachines (const settings::Key &aGlobal) 3377 { 3378 using namespace settings; 3379 3405 3380 AutoCaller autoCaller (this); 3406 3381 AssertReturn (autoCaller.state() == InInit, E_FAIL); 3407 3382 3408 3383 HRESULT rc = S_OK; 3409 CFGNODE machineRegistry = 0; 3410 unsigned count = 0; 3411 3412 CFGLDRGetChildNode (aGlobal, "MachineRegistry", 0, &machineRegistry); 3413 Assert (machineRegistry); 3414 3415 CFGLDRCountChildren(machineRegistry, "MachineEntry", &count); 3416 for (unsigned i = 0; i < count && SUCCEEDED (rc); i++) 3417 { 3418 CFGNODE vm = 0; 3419 CFGLDRGetChildNode(machineRegistry, "MachineEntry", i, &vm); 3420 /* get the UUID */ 3421 Guid uuid; 3422 CFGLDRQueryUUID(vm, "uuid", uuid.ptr()); 3423 /* get the machine configuration file name */ 3424 Bstr src; 3425 CFGLDRQueryBSTR(vm, "src", src.asOutParam()); 3426 3427 /* create a new object */ 3384 3385 Key::List machines = aGlobal.key ("MachineRegistry").keys ("MachineEntry"); 3386 for (Key::List::const_iterator it = machines.begin(); 3387 it != machines.end(); ++ it) 3388 { 3389 /* required */ 3390 Guid uuid = (*it).value <Guid> ("uuid"); 3391 /* required */ 3392 Bstr src = (*it).stringValue ("src"); 3393 3394 /* create a new machine object */ 3428 3395 ComObjPtr <Machine> machine; 3429 3396 rc = machine.createObject(); … … 3436 3403 rc = registerMachine (machine); 3437 3404 } 3438 3439 CFGLDRReleaseNode(vm); 3440 } 3441 3442 CFGLDRReleaseNode(machineRegistry); 3405 } 3443 3406 3444 3407 return rc; … … 3454 3417 * @note Doesn't lock anything. 3455 3418 */ 3456 HRESULT VirtualBox::loadDisks (CFGNODE aGlobal) 3457 { 3419 HRESULT VirtualBox::loadDisks (const settings::Key &aGlobal) 3420 { 3421 using namespace settings; 3422 3458 3423 AutoCaller autoCaller (this); 3459 3424 AssertReturn (autoCaller.state() == InInit, E_FAIL); 3460 3425 3461 3426 HRESULT rc = S_OK; 3462 CFGNODE registryNode = 0; 3463 3464 CFGLDRGetChildNode (aGlobal, "DiskRegistry", 0, ®istryNode); 3465 ComAssertRet (registryNode, E_FAIL); 3466 3467 const char *ImagesNodes[] = { "HardDisks", "DVDImages", "FloppyImages" }; 3468 3469 for (size_t node = 0; node < ELEMENTS (ImagesNodes) && SUCCEEDED (rc); node ++) 3470 { 3471 CFGNODE imagesNode = 0; 3472 CFGLDRGetChildNode (registryNode, ImagesNodes [node], 0, &imagesNode); 3473 3474 // all three nodes are optional 3475 if (!imagesNode) 3427 3428 Key registry = aGlobal.key ("DiskRegistry"); 3429 3430 const char *kMediaNodes[] = { "HardDisks", "DVDImages", "FloppyImages" }; 3431 3432 for (size_t n = 0; n < ELEMENTS (kMediaNodes); ++ n) 3433 { 3434 /* All three media nodes are optional */ 3435 Key node = registry.findKey (kMediaNodes [n]); 3436 if (node.isNull()) 3476 3437 continue; 3477 3438 3478 if (node == 0) // HardDisks node 3479 rc = loadHardDisks (imagesNode); 3480 else 3481 { 3482 unsigned count = 0; 3483 CFGLDRCountChildren (imagesNode, "Image", &count); 3484 for (unsigned i = 0; i < count && SUCCEEDED (rc); ++ i) 3439 if (n == 0) 3440 { 3441 /* HardDisks node */ 3442 rc = loadHardDisks (node); 3443 continue; 3444 } 3445 3446 Key::List images = node.keys ("Image"); 3447 for (Key::List::const_iterator it = images.begin(); 3448 it != images.end(); ++ it) 3449 { 3450 /* required */ 3451 Guid uuid = (*it).value <Guid> ("uuid"); 3452 /* required */ 3453 Bstr src = (*it).stringValue ("src"); 3454 3455 switch (n) 3485 3456 { 3486 CFGNODE imageNode = 0; 3487 CFGLDRGetChildNode (imagesNode, "Image", i, &imageNode); 3488 ComAssertBreak (imageNode, rc = E_FAIL); 3489 3490 Guid uuid; // uuid (required) 3491 CFGLDRQueryUUID (imageNode, "uuid", uuid.ptr()); 3492 Bstr src; // source (required) 3493 CFGLDRQueryBSTR (imageNode, "src", src.asOutParam()); 3494 3495 switch (node) 3457 case 1: /* DVDImages */ 3496 3458 { 3497 case 1: // DVDImages 3498 { 3499 ComObjPtr <DVDImage> dvdImage; 3500 dvdImage.createObject(); 3501 rc = dvdImage->init (this, src, TRUE /* isRegistered */, uuid); 3502 if (SUCCEEDED (rc)) 3503 rc = registerDVDImage (dvdImage, TRUE /* aOnStartUp */); 3504 3505 break; 3506 } 3507 case 2: // FloppyImages 3508 { 3509 ComObjPtr <FloppyImage> floppyImage; 3510 floppyImage.createObject(); 3511 rc = floppyImage->init (this, src, TRUE /* isRegistered */, uuid); 3512 if (SUCCEEDED (rc)) 3513 rc = registerFloppyImage (floppyImage, TRUE /* aOnStartUp */); 3514 3515 break; 3516 } 3517 default: 3518 AssertFailed(); 3459 ComObjPtr <DVDImage> image; 3460 image.createObject(); 3461 rc = image->init (this, src, TRUE /* isRegistered */, uuid); 3462 if (SUCCEEDED (rc)) 3463 rc = registerDVDImage (image, TRUE /* aOnStartUp */); 3464 3465 break; 3519 3466 } 3520 3521 CFGLDRReleaseNode (imageNode); 3467 case 2: /* FloppyImages */ 3468 { 3469 ComObjPtr <FloppyImage> image; 3470 image.createObject(); 3471 rc = image->init (this, src, TRUE /* isRegistered */, uuid); 3472 if (SUCCEEDED (rc)) 3473 rc = registerFloppyImage (image, TRUE /* aOnStartUp */); 3474 3475 break; 3476 } 3477 default: 3478 AssertFailed(); 3522 3479 } 3523 } 3524 3525 CFGLDRReleaseNode (imagesNode);3526 } 3527 3528 CFGLDRReleaseNode (registryNode);3480 3481 CheckComRCBreakRC (rc); 3482 } 3483 3484 CheckComRCBreakRC (rc); 3485 } 3529 3486 3530 3487 return rc; … … 3535 3492 * Note that all loaded hard disks register themselves within this VirtualBox. 3536 3493 * 3537 * @param aNode <HardDisks> node 3494 * @param aNode <HardDisks> node. 3538 3495 * 3539 3496 * @note Can be called only from #init(). 3540 3497 * @note Doesn't lock anything. 3541 3498 */ 3542 HRESULT VirtualBox::loadHardDisks (CFGNODE aNode) 3543 { 3499 HRESULT VirtualBox::loadHardDisks (const settings::Key &aNode) 3500 { 3501 using namespace settings; 3502 3544 3503 AutoCaller autoCaller (this); 3545 3504 AssertReturn (autoCaller.state() == InInit, E_FAIL); 3546 3505 3547 AssertReturn ( aNode, E_INVALIDARG);3506 AssertReturn (!aNode.isNull(), E_INVALIDARG); 3548 3507 3549 3508 HRESULT rc = S_OK; 3550 3509 3551 unsigned count = 0; 3552 CFGLDRCountChildren (aNode, "HardDisk", &count); 3553 for (unsigned i = 0; i < count && SUCCEEDED (rc); ++ i) 3554 { 3555 CFGNODE hdNode = 0; 3556 3557 CFGLDRGetChildNode (aNode, "HardDisk", i, &hdNode); 3558 ComAssertBreak (hdNode, rc = E_FAIL); 3559 3560 { 3561 CFGNODE storageNode = 0; 3562 3563 // detect the type of the hard disk 3564 // (either one of HVirtualDiskImage, HISCSIHardDisk or HPhysicalVolume 3565 do 3510 Key::List disks = aNode.keys ("HardDisk"); 3511 for (Key::List::const_iterator it = disks.begin(); 3512 it != disks.end(); ++ it) 3513 { 3514 Key storageNode; 3515 3516 /* detect the type of the hard disk (either one of VirtualDiskImage, 3517 * ISCSIHardDisk, VMDKImage or HCustomHardDisk) */ 3518 3519 do 3520 { 3521 storageNode = (*it).findKey ("VirtualDiskImage"); 3522 if (!storageNode.isNull()) 3566 3523 { 3567 CFGLDRGetChildNode (hdNode, "VirtualDiskImage", 0, &storageNode); 3568 if (storageNode) 3569 { 3570 ComObjPtr <HVirtualDiskImage> vdi; 3571 vdi.createObject(); 3572 rc = vdi->init (this, NULL, hdNode, storageNode); 3573 break; 3574 } 3575 3576 CFGLDRGetChildNode (hdNode, "ISCSIHardDisk", 0, &storageNode); 3577 if (storageNode) 3578 { 3579 ComObjPtr <HISCSIHardDisk> iscsi; 3580 iscsi.createObject(); 3581 rc = iscsi->init (this, hdNode, storageNode); 3582 break; 3583 } 3584 3585 CFGLDRGetChildNode (hdNode, "VMDKImage", 0, &storageNode); 3586 if (storageNode) 3587 { 3588 ComObjPtr <HVMDKImage> vmdk; 3589 vmdk.createObject(); 3590 rc = vmdk->init (this, NULL, hdNode, storageNode); 3591 break; 3592 } 3593 CFGLDRGetChildNode (hdNode, "CustomHardDisk", 0, &storageNode); 3594 if (storageNode) 3595 { 3596 ComObjPtr <HCustomHardDisk> custom; 3597 custom.createObject(); 3598 rc = custom->init (this, NULL, hdNode, storageNode); 3599 break; 3600 } 3601 3602 /// @todo (dmik) later 3603 // CFGLDRGetChildNode (hdNode, "PhysicalVolume", 0, &storageNode); 3604 // if (storageNode) 3605 // { 3606 // break; 3607 // } 3608 3609 ComAssertMsgFailedBreak (("No valid hard disk storage node!\n"), 3610 rc = E_FAIL); 3524 ComObjPtr <HVirtualDiskImage> vdi; 3525 vdi.createObject(); 3526 rc = vdi->init (this, NULL, (*it), storageNode); 3527 break; 3611 3528 } 3612 while (0); 3613 3614 if (storageNode) 3615 CFGLDRReleaseNode (storageNode); 3616 } 3617 3618 CFGLDRReleaseNode (hdNode); 3619 } 3620 3621 return rc; 3622 } 3623 3624 /** 3625 * Helper function to write out the configuration to XML. 3626 * 3627 * @note Locks objects! 3628 */ 3629 HRESULT VirtualBox::saveConfig() 3529 3530 storageNode = (*it).findKey ("ISCSIHardDisk"); 3531 if (!storageNode.isNull()) 3532 { 3533 ComObjPtr <HISCSIHardDisk> iscsi; 3534 iscsi.createObject(); 3535 rc = iscsi->init (this, (*it), storageNode); 3536 break; 3537 } 3538 3539 storageNode = (*it).findKey ("VMDKImage"); 3540 if (!storageNode.isNull()) 3541 { 3542 ComObjPtr <HVMDKImage> vmdk; 3543 vmdk.createObject(); 3544 rc = vmdk->init (this, NULL, (*it), storageNode); 3545 break; 3546 } 3547 3548 storageNode = (*it).findKey ("CustomHardDisk"); 3549 if (!storageNode.isNull()) 3550 { 3551 ComObjPtr <HCustomHardDisk> custom; 3552 custom.createObject(); 3553 rc = custom->init (this, NULL, (*it), storageNode); 3554 break; 3555 } 3556 3557 ComAssertMsgFailedBreak (("No valid hard disk storage node!\n"), 3558 rc = E_FAIL); 3559 } 3560 while (0); 3561 } 3562 3563 return rc; 3564 } 3565 3566 /** 3567 * Helper function to write out the configuration tree. 3568 * 3569 * @note Locks objects for reading! 3570 */ 3571 HRESULT VirtualBox::saveSettings() 3630 3572 { 3631 3573 AutoCaller autoCaller (this); 3632 3574 AssertComRCReturn (autoCaller.rc(), autoCaller.rc()); 3633 3575 3634 ComAssertRet(!!mData.mCfgFile.mName, E_FAIL);3576 AssertReturn (!!mData.mCfgFile.mName, E_FAIL); 3635 3577 3636 3578 HRESULT rc = S_OK; 3637 3579 3638 AutoLock alock (this); 3639 3640 CFGHANDLE configLoader; 3641 3642 /* load the config file */ 3643 int vrc = CFGLDRLoad (&configLoader, Utf8Str (mData.mCfgFile.mName), 3644 mData.mCfgFile.mHandle, 3645 XmlSchemaNS, true, cfgLdrEntityResolver, NULL); 3646 ComAssertRCRet (vrc, E_FAIL); 3647 3648 const char * Global = "VirtualBox/Global"; 3649 CFGNODE global; 3650 3651 vrc = CFGLDRGetNode(configLoader, Global, 0, &global); 3652 if (VBOX_FAILURE (vrc)) 3653 CFGLDRCreateNode (configLoader, Global, &global); 3654 3655 do 3656 { 3657 ComAssertBreak (global, rc = E_FAIL); 3580 AutoReaderLock alock (this); 3581 3582 try 3583 { 3584 using namespace settings; 3585 3586 File file (File::ReadWrite, mData.mCfgFile.mHandle, 3587 Utf8Str (mData.mCfgFile.mName)); 3588 XmlTreeBackend tree; 3589 3590 rc = VirtualBox::loadSettingsTree_ForUpdate (tree, file); 3591 CheckComRCThrowRC (rc); 3592 3593 Key global = tree.rootKey().createKey ("Global"); 3658 3594 3659 3595 /* machines */ 3660 do 3661 { 3662 const char *Registry = "MachineRegistry"; 3663 const char *Entry = "MachineEntry"; 3664 CFGNODE registryNode = NULL; 3665 3596 { 3666 3597 /* first, delete the entire machine registry */ 3667 if (VBOX_SUCCESS (CFGLDRGetChildNode (global, Registry, 0, ®istryNode)))3668 CFGLDRDeleteNode (registryNode);3669 3598 Key registryNode = global.findKey ("MachineRegistry"); 3599 if (!registryNode.isNull()) 3600 registryNode.zap(); 3670 3601 /* then, recreate it */ 3671 CFGLDRCreateChildNode (global, Registry, ®istryNode);3602 registryNode = global.createKey ("MachineRegistry"); 3672 3603 3673 3604 /* write out the machines */ … … 3676 3607 ++ it) 3677 3608 { 3678 /// @todo (dmik) move this part to Machine for better incapsulation 3679 3680 CFGNODE entryNode = NULL; 3681 CFGLDRAppendChildNode (registryNode, Entry, &entryNode); 3609 Key entryNode = registryNode.appendKey ("MachineEntry"); 3682 3610 rc = (*it)->saveRegistryEntry (entryNode); 3683 CFGLDRReleaseNode (entryNode); 3684 CheckComRCBreakRC (rc); 3611 CheckComRCThrowRC (rc); 3685 3612 } 3686 3687 CFGLDRReleaseNode (registryNode); 3688 } 3689 while (0); 3690 CheckComRCBreakRC (rc); 3613 } 3691 3614 3692 3615 /* disk images */ 3693 do 3694 { 3695 CFGNODE registryNode = 0; 3696 CFGLDRGetChildNode (global, "DiskRegistry", 0, ®istryNode); 3616 { 3697 3617 /* first, delete the entire disk image registr */ 3698 if (registryNode) 3699 CFGLDRDeleteNode (registryNode); 3618 Key registryNode = global.findKey ("DiskRegistry"); 3619 if (!registryNode.isNull()) 3620 registryNode.zap(); 3700 3621 /* then, recreate it */ 3701 CFGLDRCreateChildNode (global, "DiskRegistry", ®istryNode); 3702 ComAssertBreak (registryNode, rc = E_FAIL); 3622 registryNode = global.createKey ("DiskRegistry"); 3703 3623 3704 3624 /* write out the hard disks */ 3705 3625 { 3706 CFGNODE imagesNode = 0; 3707 CFGLDRCreateChildNode (registryNode, "HardDisks", &imagesNode); 3626 Key imagesNode = registryNode.createKey ("HardDisks"); 3708 3627 rc = saveHardDisks (imagesNode); 3709 CFGLDRReleaseNode (imagesNode); 3710 CheckComRCBreakRC (rc); 3628 CheckComRCThrowRC (rc); 3711 3629 } 3712 3630 3713 3631 /* write out the CD/DVD images */ 3714 3632 { 3715 CFGNODE imagesNode = 0; 3716 CFGLDRCreateChildNode (registryNode, "DVDImages", &imagesNode); 3633 Key imagesNode = registryNode.createKey ("DVDImages"); 3717 3634 3718 3635 for (DVDImageList::iterator it = mData.mDVDImages.begin(); … … 3722 3639 ComObjPtr <DVDImage> dvd = *it; 3723 3640 /* no need to lock: fields are constant */ 3724 CFGNODE imageNode = 0; 3725 CFGLDRAppendChildNode (imagesNode, "Image", &imageNode); 3726 CFGLDRSetUUID (imageNode, "uuid", dvd->id()); 3727 CFGLDRSetBSTR (imageNode, "src", dvd->filePath()); 3728 CFGLDRReleaseNode (imageNode); 3641 Key imageNode = imagesNode.appendKey ("Image"); 3642 imageNode.setValue <Guid> ("uuid", dvd->id()); 3643 imageNode.setValue <Bstr> ("src", dvd->filePath()); 3729 3644 } 3730 3731 CFGLDRReleaseNode (imagesNode);3732 3645 } 3733 3646 3734 3647 /* write out the floppy images */ 3735 3648 { 3736 CFGNODE imagesNode = 0; 3737 CFGLDRCreateChildNode (registryNode, "FloppyImages", &imagesNode); 3649 Key imagesNode = registryNode.createKey ("FloppyImages"); 3738 3650 3739 3651 for (FloppyImageList::iterator it = mData.mFloppyImages.begin(); … … 3743 3655 ComObjPtr <FloppyImage> fd = *it; 3744 3656 /* no need to lock: fields are constant */ 3745 CFGNODE imageNode = 0; 3746 CFGLDRAppendChildNode (imagesNode, "Image", &imageNode); 3747 CFGLDRSetUUID (imageNode, "uuid", fd->id()); 3748 CFGLDRSetBSTR (imageNode, "src", fd->filePath()); 3749 CFGLDRReleaseNode (imageNode); 3657 Key imageNode = imagesNode.appendKey ("Image"); 3658 imageNode.setValue <Guid> ("uuid", fd->id()); 3659 imageNode.setValue <Bstr> ("src", fd->filePath()); 3750 3660 } 3751 3752 CFGLDRReleaseNode (imagesNode);3753 3661 } 3754 3755 CFGLDRReleaseNode (registryNode); 3756 } 3757 while (0); 3758 CheckComRCBreakRC (rc); 3759 3760 do 3761 { 3762 /* host data (USB filters) */ 3763 rc = mData.mHost->saveSettings (global); 3764 CheckComRCBreakRC (rc); 3765 3766 rc = mData.mSystemProperties->saveSettings (global); 3767 CheckComRCBreakRC (rc); 3768 } 3769 while (0); 3770 } 3771 while (0); 3772 3773 if (global) 3774 CFGLDRReleaseNode (global); 3775 3776 if (SUCCEEDED (rc)) 3777 { 3778 char *loaderError = NULL; 3779 vrc = CFGLDRSave (configLoader, &loaderError); 3780 if (VBOX_FAILURE (vrc)) 3781 { 3782 rc = setError (E_FAIL, 3783 tr ("Could not save the settings file '%ls' (%Vrc)%s%s"), 3784 mData.mCfgFile.mName.raw(), vrc, 3785 loaderError ? ".\n" : "", loaderError ? loaderError : ""); 3786 if (loaderError) 3787 RTMemTmpFree (loaderError); 3788 } 3789 } 3790 3791 CFGLDRFree(configLoader); 3662 } 3663 3664 /* host data (USB filters) */ 3665 rc = mData.mHost->saveSettings (global); 3666 CheckComRCThrowRC (rc); 3667 3668 rc = mData.mSystemProperties->saveSettings (global); 3669 CheckComRCThrowRC (rc); 3670 3671 /* save the settings on success */ 3672 rc = VirtualBox::saveSettingsTree (tree, file); 3673 CheckComRCThrowRC (rc); 3674 } 3675 catch (HRESULT err) 3676 { 3677 /* we assume that error info is set by the thrower */ 3678 rc = err; 3679 } 3680 catch (...) 3681 { 3682 rc = VirtualBox::handleUnexpectedExceptions (RT_SRC_POS); 3683 } 3792 3684 3793 3685 return rc; … … 3797 3689 * Saves all hard disks to the given <HardDisks> node. 3798 3690 * 3799 * @param aNode <HardDisks> node 3691 * @param aNode <HardDisks> node. 3800 3692 * 3801 3693 * @note Locks this object for reding. 3802 3694 */ 3803 HRESULT VirtualBox::saveHardDisks (CFGNODE aNode) 3804 { 3805 AssertReturn (aNode, E_INVALIDARG); 3695 HRESULT VirtualBox::saveHardDisks (settings::Key &aNode) 3696 { 3697 using namespace settings; 3698 3699 AssertReturn (!aNode.isNull(), E_INVALIDARG); 3806 3700 3807 3701 HRESULT rc = S_OK; … … 3810 3704 3811 3705 for (HardDiskList::const_iterator it = mData.mHardDisks.begin(); 3812 it != mData.mHardDisks.end() && SUCCEEDED (rc);3706 it != mData.mHardDisks.end(); 3813 3707 ++ it) 3814 3708 { … … 3816 3710 AutoReaderLock hdLock (hd); 3817 3711 3818 CFGNODE hdNode = 0; 3819 CFGLDRAppendChildNode (aNode, "HardDisk", &hdNode); 3820 ComAssertBreak (hdNode, rc = E_FAIL); 3821 3822 CFGNODE storageNode = 0; 3712 Key hdNode = aNode.appendKey ("HardDisk"); 3823 3713 3824 3714 switch (hd->storageType()) … … 3826 3716 case HardDiskStorageType_VirtualDiskImage: 3827 3717 { 3828 CFGLDRAppendChildNode (hdNode, "VirtualDiskImage", &storageNode); 3829 ComAssertBreak (storageNode, rc = E_FAIL); 3718 Key storageNode = hdNode.createKey ("VirtualDiskImage"); 3830 3719 rc = hd->saveSettings (hdNode, storageNode); 3831 3720 break; … … 3834 3723 case HardDiskStorageType_ISCSIHardDisk: 3835 3724 { 3836 CFGLDRAppendChildNode (hdNode, "ISCSIHardDisk", &storageNode); 3837 ComAssertBreak (storageNode, rc = E_FAIL); 3725 Key storageNode = hdNode.createKey ("ISCSIHardDisk"); 3838 3726 rc = hd->saveSettings (hdNode, storageNode); 3839 3727 break; … … 3842 3730 case HardDiskStorageType_VMDKImage: 3843 3731 { 3844 CFGLDRAppendChildNode (hdNode, "VMDKImage", &storageNode); 3845 ComAssertBreak (storageNode, rc = E_FAIL); 3732 Key storageNode = hdNode.createKey ("VMDKImage"); 3846 3733 rc = hd->saveSettings (hdNode, storageNode); 3847 3734 break; … … 3849 3736 case HardDiskStorageType_CustomHardDisk: 3850 3737 { 3851 CFGLDRAppendChildNode (hdNode, "CustomHardDisk", &storageNode); 3852 ComAssertBreak (storageNode, rc = E_FAIL); 3738 Key storageNode = hdNode.createKey ("CustomHardDisk"); 3853 3739 rc = hd->saveSettings (hdNode, storageNode); 3854 3740 break; 3855 3741 } 3856 3857 /// @todo (dmik) later 3858 // case HardDiskStorageType_PhysicalVolume: 3859 // { 3860 // break; 3861 // } 3862 } 3863 3864 if (storageNode) 3865 CFGLDRReleaseNode (storageNode); 3866 3867 CFGLDRReleaseNode (hdNode); 3742 } 3743 3744 CheckComRCBreakRC (rc); 3868 3745 } 3869 3746 … … 3926 3803 3927 3804 if (autoCaller.state() != InInit) 3928 rc = save Config();3805 rc = saveSettings(); 3929 3806 3930 3807 return rc; … … 3971 3848 /// @todo (dmik) optimize later to save only the <HardDisks> node 3972 3849 if (aFlags != RHD_OnStartUp) 3973 rc = save Config();3850 rc = saveSettings(); 3974 3851 3975 3852 return rc; … … 4031 3908 /* save the global config file anyway (already unregistered) */ 4032 3909 /// @todo (dmik) optimize later to save only the <HardDisks> node 4033 HRESULT rc2 = save Config();3910 HRESULT rc2 = saveSettings(); 4034 3911 if (SUCCEEDED (rc)) 4035 3912 rc = rc2; … … 4154 4031 } 4155 4032 4156 HRESULT rc = saveConfig(); 4157 4158 return rc; 4033 HRESULT rc = saveSettings(); 4034 4035 return rc; 4036 } 4037 4038 /** 4039 * Helper method to load the setting tree and turn expected exceptions into 4040 * COM errors, according to arguments. 4041 * 4042 * Note that this method will not catch unexpected errors so it may still 4043 * throw something. 4044 * 4045 * @param aTree Tree to load into settings. 4046 * @param aFile File to load settings from. 4047 * @param aValidate @c @true to enable tree validation. 4048 * @param aCatchLoadErrors @c true to catch exceptions caused by file 4049 * access or validation errors. 4050 * @param aAddDefaults @c true to cause the substitution of default 4051 * values for for missing attributes that have 4052 * defaults in the XML schema. 4053 */ 4054 /* static */ 4055 HRESULT VirtualBox::loadSettingsTree (settings::XmlTreeBackend &aTree, 4056 settings::File &aFile, 4057 bool aValidate, 4058 bool aCatchLoadErrors, 4059 bool aAddDefaults) 4060 { 4061 using namespace settings; 4062 4063 try 4064 { 4065 SettingsInputResolver resolver = SettingsInputResolver(); 4066 4067 aTree.setInputResolver (resolver); 4068 aTree.read (aFile, aValidate ? VBOX_XML_SCHEMA : NULL, 4069 aAddDefaults ? XmlTreeBackend::Read_AddDefaults : 0); 4070 aTree.resetInputResolver(); 4071 } 4072 catch (const EIPRTFailure &err) 4073 { 4074 if (!aCatchLoadErrors) 4075 throw; 4076 4077 return setError (E_FAIL, 4078 tr ("Could not load the settings file '%s' (%Vrc)"), 4079 aFile.uri(), err.rc()); 4080 } 4081 catch (const XmlTreeBackend::Error &err) 4082 { 4083 Assert (err.what() != NULL); 4084 4085 if (!aCatchLoadErrors) 4086 throw; 4087 4088 return setError (E_FAIL, 4089 tr ("Could not load the settings file '%s'.\n%s"), 4090 aFile.uri(), 4091 err.what() ? err.what() : "Unknown error"); 4092 } 4093 4094 return S_OK; 4095 } 4096 4097 /** 4098 * Helper method to save the settings tree and turn expected exceptions to COM 4099 * errors. 4100 * 4101 * Note that this method will not catch unexpected errors so it may still 4102 * throw something. 4103 * 4104 * @param aTree Tree to save. 4105 * @param aFile File to save the tree to. 4106 */ 4107 /* static */ 4108 HRESULT VirtualBox::saveSettingsTree (settings::TreeBackend &aTree, 4109 settings::File &aFile) 4110 { 4111 using namespace settings; 4112 4113 try 4114 { 4115 aTree.write (aFile); 4116 } 4117 catch (const EIPRTFailure &err) 4118 { 4119 /* this is the only expected exception for now */ 4120 return setError (E_FAIL, 4121 tr ("Could not save the settings file '%s' (%Vrc)"), 4122 aFile.uri(), err.rc()); 4123 } 4124 4125 return S_OK; 4126 } 4127 4128 /** 4129 * Handles unexpected exceptions by turning them into COM errors in release 4130 * builds or by hitting a breakpoint in the release builds. 4131 * 4132 * Usage pattern: 4133 * @code 4134 try 4135 { 4136 // ... 4137 } 4138 catch (LaLalA) 4139 { 4140 // ... 4141 } 4142 catch (...) 4143 { 4144 rc = VirtualBox::handleUnexpectedExceptions (RT_SRC_POS); 4145 } 4146 * @endcode 4147 * 4148 * @param RT_SRC_POS_DECL "RT_SRC_POS" macro instantiation. 4149 */ 4150 /* static */ 4151 HRESULT VirtualBox::handleUnexpectedExceptions (RT_SRC_POS_DECL) 4152 { 4153 try 4154 { 4155 /* rethrow the current exception */ 4156 throw; 4157 } 4158 catch (const std::exception &err) 4159 { 4160 ComAssertMsgFailedPos (("Unexpected exception '%s' (%s)\n", 4161 typeid (err).name(), err.what()), 4162 pszFile, iLine, pszFunction); 4163 return E_FAIL; 4164 } 4165 catch (...) 4166 { 4167 ComAssertMsgFailedPos (("Unknown exception\n"), 4168 pszFile, iLine, pszFunction); 4169 return E_FAIL; 4170 } 4171 4172 /* should not get here */ 4173 AssertFailed(); 4174 return E_FAIL; 4159 4175 } 4160 4176 … … 4187 4203 /* save global config file if we're supposed to */ 4188 4204 if (!aOnStartUp) 4189 rc = save Config();4205 rc = saveSettings(); 4190 4206 4191 4207 return rc; … … 4220 4236 /* save global config file if we're supposed to */ 4221 4237 if (!aOnStartUp) 4222 rc = save Config();4238 rc = saveSettings(); 4223 4239 4224 4240 return rc; -
trunk/src/VBox/Main/glue/com.cpp
r5999 r6076 1 /* $Id$ */ 2 1 3 /** @file 2 4 * MS COM / XPCOM Abstraction Layer … … 41 43 #include "VBox/com/com.h" 42 44 #include "VBox/com/assert.h" 45 46 #include <VBox/com/Guid.h> 43 47 44 48 … … 182 186 } 183 187 188 /* static */ 189 const Guid Guid::Empty; /* default ctor is OK */ 190 184 191 } /* namespace com */ -
trunk/src/VBox/Main/glue/string.cpp
r5999 r6076 1 /* $Id$ */ 2 1 3 /** @file 2 4 * … … 19 21 #include "VBox/com/string.h" 20 22 23 #include <iprt/err.h> 24 21 25 namespace com 22 26 { 27 28 /* static */ 29 const Bstr Bstr::Null; /* default ctor is OK */ 30 31 /* static */ 32 const Utf8Str Utf8Str::Null; /* default ctor is OK */ 23 33 24 34 struct FormatData … … 86 96 87 97 } /* namespace com */ 88 -
trunk/src/VBox/Main/idl/VirtualBox.xidl
r6056 r6076 1588 1588 <method name="getNextExtraDataKey"> 1589 1589 <desc> 1590 Returns the extra data key name following the supplied key. 1591 An error is returned if the supplied key does not exist. 1592 @c NULL is returned if the supplied key is the last key. 1593 When supplying @c NULL for the key, the first item is returned. 1594 @a nextValue is an optional parameter and if supplied, the next 1595 key's value is returned in it. 1590 Returns the global extra data key name following the supplied key. 1591 1592 An error is returned if the supplied @a key does not exist. @c NULL is 1593 returned in @a nextKey if the supplied key is the last key. When 1594 supplying @c NULL for the @a key, the first key item is returned in @a 1595 nextKey (if there is any). @a nextValue is an optional parameter and 1596 if supplied, the next key's value is returned in it. 1596 1597 </desc> 1597 1598 <param name="key" type="wstring" dir="in"> … … 1608 1609 <method name="getExtraData"> 1609 1610 <desc> 1610 Returns associated extra data. 1611 If the reuqested key does not exist, this function will 1612 succeed and return @c null in the @a value argument. 1611 Returns associated global extra data. 1612 1613 If the reuqested data @a key does not exist, this function will 1614 succeed and return @c NULL in the @a value argument. 1613 1615 </desc> 1614 1616 <param name="key" type="wstring" dir="in"> … … 1622 1624 <method name="setExtraData"> 1623 1625 <desc> 1624 Sets associated extra data. 1625 If you pass @c NULL as a key @a vaule, the given key will be 1626 Sets associated global extra data. 1627 1628 If you pass @c NULL as a key @a vaule, the given @a key will be 1626 1629 deleted. 1627 <note> 1628 This method can be called outside a machine session and 1629 therefore it's a caller's responsibility to handle race 1630 condition when several clients change the same key at the 1631 same time. 1630 1631 <note> 1632 Before performing the actual data change, this method will ask all 1633 registered callbacks using the 1634 <link to="IVirtualBoxCallback::onExtraDataCanChange()"/> 1635 notification for a permission. If one of the callbacks refuses the 1636 new value, the change will not be performed. 1637 </note> 1638 <note> 1639 On success, the 1640 <link to="IVirtualBoxCallback::onExtraDataChange()"/> notification 1641 is called to inform all registered callbacks about a successful data 1642 change. 1632 1643 </note> 1633 1644 </desc> … … 2850 2861 <method name="getNextExtraDataKey"> 2851 2862 <desc> 2852 Returns the extra data key name following the supplied key. 2853 An error is returned if the supplied key does not exist. 2854 NULL is returned if the supplied key is the last key. 2855 When supplying NULL for the key, the first item is returned. 2856 NextValue is an optional parameter and if supplied, the next 2857 key's value is returned as well. 2858 </desc> 2859 <param name="key" type="wstring" dir="in"/> 2860 <param name="nextKey" type="wstring" dir="out"/> 2861 <param name="nextValue" type="wstring" dir="out"/> 2863 Returns the machine-specific extra data key name following the 2864 supplied key. 2865 2866 An error is returned if the supplied @a key does not exist. @c NULL is 2867 returned in @a nextKey if the supplied key is the last key. When 2868 supplying @c NULL for the @a key, the first key item is returned in @a 2869 nextKey (if there is any). @a nextValue is an optional parameter and 2870 if supplied, the next key's value is returned in it. 2871 </desc> 2872 <param name="key" type="wstring" dir="in"> 2873 <desc>Name of the data key to follow.</desc> 2874 </param> 2875 <param name="nextKey" type="wstring" dir="out"> 2876 <desc>Name of the next data key.</desc> 2877 </param> 2878 <param name="nextValue" type="wstring" dir="out"> 2879 <desc>Value of the next data key.</desc> 2880 </param> 2862 2881 </method> 2863 2882 2864 2883 <method name="getExtraData"> 2865 <desc>Returns associated extra data.</desc> 2866 <param name="key" type="wstring" dir="in"/> 2867 <param name="value" type="wstring" dir="return"/> 2884 <desc> 2885 Returns associated machine-specific extra data. 2886 2887 If the reuqested data @a key does not exist, this function will 2888 succeed and return @c NULL in the @a value argument. 2889 </desc> 2890 <param name="key" type="wstring" dir="in"> 2891 <desc>Name of the data key to get.</desc> 2892 </param> 2893 <param name="value" type="wstring" dir="return"> 2894 <desc>Value of the requested data key.</desc> 2895 </param> 2868 2896 </method> 2869 2897 2870 2898 <method name="setExtraData"> 2871 <desc>Sets associated extra data.</desc> 2872 <param name="key" type="wstring" dir="in"/> 2873 <param name="value" type="wstring" dir="in"/> 2899 <desc> 2900 Sets associated machine-specific extra data. 2901 2902 If you pass @c NULL as a key @a vaule, the given @a key will be 2903 deleted. 2904 2905 <note> 2906 Before performing the actual data change, this method will ask all 2907 registered callbacks using the 2908 <link to="IVirtualBoxCallback::onExtraDataCanChange()"/> 2909 notification for a permission. If one of the callbacks refuses the 2910 new value, the change will not be performed. 2911 </note> 2912 <note> 2913 On success, the 2914 <link to="IVirtualBoxCallback::onExtraDataChange()"/> notification 2915 is called to inform all registered callbacks about a successful data 2916 change. 2917 </note> 2918 <note> 2919 This method can be called outside the machine session and therefore 2920 it's a caller's responsibility to handle possible race conditions 2921 when several clients change the same key at the same time. 2922 </note> 2923 </desc> 2924 <param name="key" type="wstring" dir="in"> 2925 <desc>Name of the data key to set.</desc> 2926 </param> 2927 <param name="value" type="wstring" dir="in"> 2928 <desc>Value to assign to the key.</desc> 2929 </param> 2874 2930 </method> 2875 2931 -
trunk/src/VBox/Main/include/AudioAdapterImpl.h
r5999 r6076 1 /* $Id$ */ 2 1 3 /** @file 2 4 * … … 80 82 // public methods only for internal purposes 81 83 84 HRESULT loadSettings (const settings::Key &aMachineNode); 85 HRESULT saveSettings (settings::Key &aMachineNode); 86 82 87 bool isModified() { AutoLock alock (this); return mData.isBackedUp(); } 83 88 bool isReallyModified() { AutoLock alock (this); return mData.hasActualChanges(); } -
trunk/src/VBox/Main/include/BIOSSettingsImpl.h
r5999 r6076 1 /* $Id$ */ 2 1 3 /** @file 2 4 * … … 116 118 // public methods only for internal purposes 117 119 120 HRESULT loadSettings (const settings::Key &aMachineNode); 121 HRESULT saveSettings (settings::Key &aMachineNode); 122 118 123 const Backupable <Data> &data() const { return mData; } 119 124 -
trunk/src/VBox/Main/include/DVDDriveImpl.h
r5999 r6076 1 /* $Id$ */ 2 1 3 /** @file 2 4 * … … 90 92 // public methods only for internal purposes 91 93 94 HRESULT loadSettings (const settings::Key &aMachineNode); 95 HRESULT saveSettings (settings::Key &aMachineNode); 96 92 97 bool isModified() { AutoLock alock (this); return mData.isBackedUp(); } 93 98 bool isReallyModified() { AutoLock alock (this); return mData.hasActualChanges(); } -
trunk/src/VBox/Main/include/FloppyDriveImpl.h
r5999 r6076 1 /* $Id$ */ 2 1 3 /** @file 2 4 * … … 91 93 // public methods only for internal purposes 92 94 95 HRESULT loadSettings (const settings::Key &aMachineNode); 96 HRESULT saveSettings (settings::Key &aMachineNode); 97 93 98 bool isModified() { AutoLock alock (this); return mData.isBackedUp(); } 94 99 bool isReallyModified() { AutoLock alock (this); return mData.hasActualChanges(); } -
trunk/src/VBox/Main/include/HardDiskImpl.h
r5999 r6076 1 /* $Id$ */ 2 1 3 /** @file 2 4 * … … 22 24 #include "Collection.h" 23 25 24 #include <VBox/cfgldr.h>25 26 #include <VBox/VBoxHDD-new.h> 26 27 … … 134 135 virtual HRESULT getAccessible (Bstr &aAccessError) = 0; 135 136 136 virtual HRESULT saveSettings ( CFGNODE aHDNode, CFGNODEaStorageNode) = 0;137 virtual HRESULT saveSettings (settings::Key &aHDNode, settings::Key &aStorageNode) = 0; 137 138 138 139 virtual void updatePath (const char *aOldPath, const char *aNewPath) {} … … 180 181 protected: 181 182 182 HRESULT loadSettings ( CFGNODEaHDNode);183 HRESULT saveSettings ( CFGNODEaHDNode);183 HRESULT loadSettings (const settings::Key &aHDNode); 184 HRESULT saveSettings (settings::Key &aHDNode); 184 185 185 186 /** weak VirualBox parent */ … … 234 235 235 236 HRESULT init (VirtualBox *aVirtualBox, HardDisk *aParent, 236 CFGNODE aHDNode, CFGNODEaVDINode);237 const settings::Key &aHDNode, const settings::Key &aVDINode); 237 238 HRESULT init (VirtualBox *aVirtualBox, HardDisk *aParent, 238 239 const BSTR aFilePath, BOOL aRegistered = FALSE); … … 263 264 HRESULT getAccessible (Bstr &aAccessError); 264 265 265 HRESULT saveSettings ( CFGNODE aHDNode, CFGNODEaStorageNode);266 HRESULT saveSettings (settings::Key &aHDNode, settings::Key &aStorageNode); 266 267 267 268 void updatePath (const char *aOldPath, const char *aNewPath); … … 359 360 360 361 HRESULT init (VirtualBox *aVirtualBox, 361 CFGNODE aHDNode, CFGNODEaISCSINode);362 const settings::Key &aHDNode, const settings::Key &aISCSINode); 362 363 HRESULT init (VirtualBox *aVirtualBox); 363 364 void uninit(); … … 395 396 HRESULT getAccessible (Bstr &aAccessError); 396 397 397 HRESULT saveSettings ( CFGNODE aHDNode, CFGNODEaStorageNode);398 HRESULT saveSettings (settings::Key &aHDNode, settings::Key &aStorageNode); 398 399 399 400 Bstr toString (bool aShort = false); … … 456 457 457 458 HRESULT init (VirtualBox *aVirtualBox, HardDisk *aParent, 458 CFGNODE aHDNode, CFGNODEaVMDKNode);459 const settings::Key &aHDNode, const settings::Key &aVMDKNode); 459 460 HRESULT init (VirtualBox *aVirtualBox, HardDisk *aParent, 460 461 INPTR BSTR aFilePath, BOOL aRegistered = FALSE); … … 485 486 HRESULT getAccessible (Bstr &aAccessError); 486 487 487 HRESULT saveSettings ( CFGNODE aHDNode, CFGNODEaStorageNode);488 HRESULT saveSettings (settings::Key &aHDNode, settings::Key &aStorageNode); 488 489 489 490 void updatePath (const char *aOldPath, const char *aNewPath); … … 569 570 570 571 HRESULT init (VirtualBox *aVirtualBox, HardDisk *aParent, 571 CFGNODE aHDNode, CFGNODEaCustomNode);572 const settings::Key &aHDNode, const settings::Key &aCustomNode); 572 573 HRESULT init (VirtualBox *aVirtualBox, HardDisk *aParent, 573 574 INPTR BSTR aLocation, BOOL aRegistered = FALSE); … … 598 599 HRESULT getAccessible (Bstr &aAccessError); 599 600 600 HRESULT saveSettings ( CFGNODE aHDNode, CFGNODEaStorageNode);601 HRESULT saveSettings (settings::Key &aHDNode, settings::Key &aStorageNode); 601 602 602 603 Bstr toString (bool aShort = false); -
trunk/src/VBox/Main/include/HostImpl.h
r5999 r6076 1 /* $Id$ */ 2 1 3 /** @file 2 4 * … … 26 28 #include "win32/svchlp.h" 27 29 #endif 28 29 #include <VBox/cfgldr.h>30 30 31 31 class VirtualBox; … … 98 98 BOOL aActiveChanged = FALSE); 99 99 100 HRESULT loadSettings ( CFGNODEaGlobal);101 HRESULT saveSettings ( CFGNODEaGlobal);100 HRESULT loadSettings (const settings::Key &aGlobal); 101 HRESULT saveSettings (settings::Key &aGlobal); 102 102 103 103 HRESULT captureUSBDevice (SessionMachine *aMachine, INPTR GUIDPARAM aId); -
trunk/src/VBox/Main/include/MachineImpl.h
r5999 r6076 1 /* $Id$ */ 2 1 3 /** @file 2 4 * … … 20 22 21 23 #include "VirtualBoxBase.h" 22 #include "VirtualBoxXMLUtil.h"23 24 #include "ProgressImpl.h" 24 25 #include "SnapshotImpl.h" … … 38 39 39 40 #include <VBox/types.h> 40 #include <VBox/cfgldr.h> 41 41 42 #include <iprt/file.h> 42 43 #include <iprt/thread.h> 44 #include <iprt/time.h> 43 45 44 46 #include <list> … … 69 71 class ATL_NO_VTABLE Machine : 70 72 public VirtualBoxBaseWithChildrenNEXT, 71 public VirtualBoxXMLUtil,72 73 public VirtualBoxSupportErrorInfoImpl <Machine, IMachine>, 73 74 public VirtualBoxSupportTranslation <Machine>, … … 141 142 142 143 MachineState_T mMachineState; 143 LONG64mLastStateChange;144 RTTIMESPEC mLastStateChange; 144 145 145 146 uint32_t mMachineStateDeps; … … 557 558 virtual HRESULT onSharedFolderChange() { return S_OK; } 558 559 559 HRESULT saveRegistryEntry ( CFGNODEaEntryNode);560 HRESULT saveRegistryEntry (settings::Key &aEntryNode); 560 561 561 562 int calculateFullPath (const char *aPath, Utf8Str &aResult); … … 613 614 614 615 HRESULT loadSettings (bool aRegistered); 615 HRESULT loadSnapshot ( CFGNODEaNode, const Guid &aCurSnapshotId,616 HRESULT loadSnapshot (const settings::Key &aNode, const Guid &aCurSnapshotId, 616 617 Snapshot *aParentSnapshot); 617 HRESULT loadHardware ( CFGNODEaNode);618 HRESULT loadHardDisks ( CFGNODEaNode, bool aRegistered,618 HRESULT loadHardware (const settings::Key &aNode); 619 HRESULT loadHardDisks (const settings::Key &aNode, bool aRegistered, 619 620 const Guid *aSnapshotId = NULL); 620 621 621 HRESULT openConfigLoader (CFGHANDLE *aLoader, bool aIsNew = false); 622 HRESULT closeConfigLoader (CFGHANDLE aLoader, bool aSaveBeforeClose); 623 624 HRESULT findSnapshotNode (Snapshot *aSnapshot, CFGNODE aMachineNode, 625 CFGNODE *aSnapshotsNode, CFGNODE *aSnapshotNode); 622 HRESULT findSnapshotNode (Snapshot *aSnapshot, settings::Key &aMachineNode, 623 settings::Key *aSnapshotsNode, 624 settings::Key *aSnapshotNode); 626 625 627 626 HRESULT findSnapshot (const Guid &aId, ComObjPtr <Snapshot> &aSnapshot, … … 655 654 656 655 HRESULT saveSnapshotSettings (Snapshot *aSnapshot, int aOpFlags); 657 HRESULT saveSnapshotSettingsWorker ( CFGNODEaMachineNode,656 HRESULT saveSnapshotSettingsWorker (settings::Key &aMachineNode, 658 657 Snapshot *aSnapshot, int aOpFlags); 659 658 660 HRESULT saveSnapshot ( CFGNODEaNode, Snapshot *aSnapshot, bool aAttrsOnly);661 HRESULT saveHardware ( CFGNODEaNode);662 HRESULT saveHardDisks ( CFGNODEaNode);659 HRESULT saveSnapshot (settings::Key &aNode, Snapshot *aSnapshot, bool aAttrsOnly); 660 HRESULT saveHardware (settings::Key &aNode); 661 HRESULT saveHardDisks (settings::Key &aNode); 663 662 664 663 HRESULT saveStateSettings (int aFlags); … … 919 918 HRESULT init (SessionMachine *aSessionMachine, 920 919 INPTR GUIDPARAM aSnapshotId, INPTR BSTR aStateFilePath); 921 HRESULT init (Machine *aMachine, CFGNODE aHWNode, CFGNODE aHDAsNode, 920 HRESULT init (Machine *aMachine, 921 const settings::Key &aHWNode, const settings::Key &aHDAsNode, 922 922 INPTR GUIDPARAM aSnapshotId, INPTR BSTR aStateFilePath); 923 923 void uninit(); -
trunk/src/VBox/Main/include/NetworkAdapterImpl.h
r5999 r6076 1 /* $Id$ */ 2 1 3 /** @file 2 4 * … … 146 148 // public methods only for internal purposes 147 149 150 HRESULT loadSettings (const settings::Key &aAdapterNode); 151 HRESULT saveSettings (settings::Key &aAdapterNode); 152 148 153 bool isModified() { AutoLock alock (this); return mData.isBackedUp(); } 149 154 bool isReallyModified() { AutoLock alock (this); return mData.hasActualChanges(); } -
trunk/src/VBox/Main/include/ParallelPortImpl.h
r5999 r6076 1 1 /* $Id$ */ 2 2 3 /** @file 3 4 * VirtualBox COM class implementation. … … 20 21 21 22 #include "VirtualBoxBase.h" 22 23 #include <VBox/cfgldr.h>24 23 25 24 class Machine; … … 95 94 96 95 // public methods only for internal purposes 96 97 HRESULT loadSettings (const settings::Key &aPortNode); 98 HRESULT saveSettings (settings::Key &aPortNode); 99 97 100 bool isModified() { AutoLock alock (this); return mData.isBackedUp(); } 98 101 bool isReallyModified() { AutoLock alock (this); return mData.hasActualChanges(); } … … 103 106 // public methods for internal purposes only 104 107 // (ensure there is a caller and a read lock before calling them!) 105 106 HRESULT loadSettings (CFGNODE aMachine, ULONG aSlot);107 HRESULT saveSettings (CFGNODE aMachine);108 108 109 109 // for VirtualBoxSupportErrorInfoImpl -
trunk/src/VBox/Main/include/SerialPortImpl.h
r5999 r6076 1 /* $Id$ */ 2 1 3 /** @file 2 4 * … … 20 22 21 23 #include "VirtualBoxBase.h" 22 23 #include <VBox/cfgldr.h>24 24 25 25 class Machine; … … 105 105 106 106 // public methods only for internal purposes 107 108 HRESULT loadSettings (const settings::Key &aPortNode); 109 HRESULT saveSettings (settings::Key &aPortNode); 110 107 111 bool isModified() { AutoLock alock (this); return mData.isBackedUp(); } 108 112 bool isReallyModified() { AutoLock alock (this); return mData.hasActualChanges(); } … … 113 117 // public methods for internal purposes only 114 118 // (ensure there is a caller and a read lock before calling them!) 115 116 HRESULT loadSettings (CFGNODE aMachine, ULONG aSlot);117 HRESULT saveSettings (CFGNODE aMachine);118 119 119 120 // for VirtualBoxSupportErrorInfoImpl -
trunk/src/VBox/Main/include/SnapshotImpl.h
r5999 r6076 22 22 #include "Collection.h" 23 23 24 #include <iprt/time.h> 25 24 26 #include <list> 25 27 … … 42 44 Bstr mName; 43 45 Bstr mDescription; 44 LONG64mTimeStamp;46 RTTIMESPEC mTimeStamp; 45 47 ComObjPtr <SnapshotMachine> mMachine; 46 48 }; … … 65 67 // public initializer/uninitializer only for internal purposes 66 68 HRESULT init (const Guid &aId, INPTR BSTR aName, INPTR BSTR aDescription, 67 LONG64aTimeStamp, SnapshotMachine *aMachine,69 RTTIMESPEC aTimeStamp, SnapshotMachine *aMachine, 68 70 Snapshot *aParent); 69 71 void uninit(); -
trunk/src/VBox/Main/include/SystemPropertiesImpl.h
r5999 r6076 1 /* $Id$ */ 2 1 3 /** @file 2 4 * … … 20 22 21 23 #include "VirtualBoxBase.h" 22 23 #include <VBox/cfgldr.h>24 24 25 25 class VirtualBox; … … 77 77 // public methods only for internal purposes 78 78 79 HRESULT loadSettings ( CFGNODEaGlobal);80 HRESULT saveSettings ( CFGNODEaGlobal);79 HRESULT loadSettings (const settings::Key &aGlobal); 80 HRESULT saveSettings (settings::Key &aGlobal); 81 81 82 82 /** Default VDI path (as is, not full). Not thread safe (use object lock). */ -
trunk/src/VBox/Main/include/USBControllerImpl.h
r5999 r6076 1 /* $Id$ */ 2 1 3 /** @file 2 4 * … … 21 23 #include "VirtualBoxBase.h" 22 24 #include "USBDeviceFilterImpl.h" 23 24 #include <VBox/cfgldr.h>25 25 26 26 #include <list> … … 102 102 // public methods only for internal purposes 103 103 104 HRESULT loadSettings ( CFGNODE aMachine);105 HRESULT saveSettings ( CFGNODE aMachine);104 HRESULT loadSettings (const settings::Key &aMachineNode); 105 HRESULT saveSettings (settings::Key &aMachineNode); 106 106 107 107 bool isModified(); -
trunk/src/VBox/Main/include/VRDPServerImpl.h
r5999 r6076 1 /* $Id$ */ 2 1 3 /** @file 2 4 * … … 22 24 23 25 #include <VBox/VRDPAuth.h> 24 #include <VBox/cfgldr.h>25 26 26 27 class Machine; … … 97 98 // public methods only for internal purposes 98 99 99 HRESULT loadSettings ( CFGNODE aNode);100 HRESULT saveSettings ( CFGNODE aNode);100 HRESULT loadSettings (const settings::Key &aMachineNode); 101 HRESULT saveSettings (settings::Key &aMachineNode); 101 102 102 103 bool isModified() { AutoLock alock (this); return mData.isBackedUp(); } -
trunk/src/VBox/Main/include/VirtualBoxBase.h
r5999 r6076 25 25 26 26 #include "VBox/com/VirtualBox.h" 27 28 #include <VBox/settings.h> 27 29 28 30 #include "AutoLock.h" … … 121 123 122 124 /** 123 * A special version of the Assert macro to be used within VirtualBoxBase125 * Special version of the Assert macro to be used within VirtualBoxBase 124 126 * subclasses that also inherit the VirtualBoxSupportErrorInfoImpl template. 125 127 * … … 145 147 146 148 /** 147 * A special version of the AssertMsg macro to be used within VirtualBoxBase149 * Special version of the AssertMsg macro to be used within VirtualBoxBase 148 150 * subclasses that also inherit the VirtualBoxSupportErrorInfoImpl template. 149 151 * … … 167 169 168 170 /** 169 * A special version of the AssertRC macro to be used within VirtualBoxBase171 * Special version of the AssertRC macro to be used within VirtualBoxBase 170 172 * subclasses that also inherit the VirtualBoxSupportErrorInfoImpl template. 171 173 * … … 181 183 182 184 /** 183 * A special version of the AssertMsgRC macro to be used within VirtualBoxBase185 * Special version of the AssertMsgRC macro to be used within VirtualBoxBase 184 186 * subclasses that also inherit the VirtualBoxSupportErrorInfoImpl template. 185 187 * … … 197 199 198 200 /** 199 * A special version of the AssertFailed macro to be used within VirtualBoxBase201 * Special version of the AssertFailed macro to be used within VirtualBoxBase 200 202 * subclasses that also inherit the VirtualBoxSupportErrorInfoImpl template. 201 203 * … … 214 216 215 217 /** 216 * A special version of the AssertMsgFailed macro to be used within VirtualBoxBase218 * Special version of the AssertMsgFailed macro to be used within VirtualBoxBase 217 219 * subclasses that also inherit the VirtualBoxSupportErrorInfoImpl template. 218 220 * … … 234 236 235 237 /** 236 * A special version of the AssertComRC macro to be used within VirtualBoxBase 238 * Special version of the ComAssertMsgFailed macro that additionally takes 239 * line number, file and function arguments to inject an assertion position 240 * that differs from the position where this macro is instantiated. 241 * 242 * @param a printf argument list (in parenthesis). 243 * @param file, line, func Line number (int), file and function (const char *). 244 */ 245 #if defined (DEBUG) 246 #define ComAssertMsgFailedPos(a, file, line, func) \ 247 do { \ 248 AssertMsg1 ((const char *) 0, line, file, func); \ 249 AssertMsg2 a; \ 250 AssertBreakpoint(); \ 251 } while (0) 252 #else 253 #define ComAssertMsgFailedPos(a, file, line, func) \ 254 do { \ 255 setError (E_FAIL, \ 256 "Assertion failed at '%s' (%d) in %s.\n" \ 257 "%s.\n" \ 258 "Please contact the product vendor!", \ 259 file, line, func, Utf8StrFmt a .raw()); \ 260 } while (0) 261 #endif 262 263 /** 264 * Special version of the AssertComRC macro to be used within VirtualBoxBase 237 265 * subclasses that also inherit the VirtualBoxSupportErrorInfoImpl template. 238 266 * … … 299 327 if (1) { ComAssertComRC (rc); if (!SUCCEEDED (rc)) { break; } } else do {} while (0) 300 328 329 330 /** Special version of ComAssert that evaulates eval and throws it if expr fails */ 331 #define ComAssertThrow(expr, eval) \ 332 if (1) { ComAssert (expr); if (!(expr)) { throw (eval); } } else do {} while (0) 333 /** Special version of ComAssertMsg that evaulates eval and throws it if expr fails */ 334 #define ComAssertMsgThrow(expr, a, eval) \ 335 if (1) { ComAssertMsg (expr, a); if (!(expr)) { throw (eval); } } else do {} while (0) 336 /** Special version of ComAssertRC that evaulates eval and throws it if vrc does not succeed */ 337 #define ComAssertRCThrow(vrc, eval) \ 338 if (1) { ComAssertRC (vrc); if (!VBOX_SUCCESS (vrc)) { throw (eval); } } else do {} while (0) 339 /** Special version of ComAssertMsgRC that evaulates eval and throws it if vrc does not succeed */ 340 #define ComAssertMsgRCThrow(vrc, msg, eval) \ 341 if (1) { ComAssertMsgRC (vrc, msg); if (!VBOX_SUCCESS (vrc)) { throw (eval); } } else do {} while (0) 342 /** Special version of ComAssertFailed that evaulates eval and throws it */ 343 #define ComAssertFailedThrow(eval) \ 344 if (1) { ComAssertFailed(); { throw (eval); } } else do {} while (0) 345 /** Special version of ComAssertMsgFailed that evaulates eval and throws it */ 346 #define ComAssertMsgFailedThrow(msg, eval) \ 347 if (1) { ComAssertMsgFailed (msg); { throw (eval); } } else do {} while (0) 348 /** Special version of ComAssertComRC that evaulates eval and throws it if rc does not succeed */ 349 #define ComAssertComRCThrow(rc, eval) \ 350 if (1) { ComAssertComRC (rc); if (!SUCCEEDED (rc)) { throw (eval); } } else do {} while (0) 351 /** Special version of ComAssertComRC that just throws rc if rc does not succeed */ 352 #define ComAssertComRCThrowRC(rc) \ 353 if (1) { ComAssertComRC (rc); if (!SUCCEEDED (rc)) { throw rc; } } else do {} while (0) 354 355 301 356 /// @todo (dmik) remove after we switch to VirtualBoxBaseNEXT completely 302 357 /** … … 1924 1979 }; 1925 1980 1981 #if defined VBOX_MAIN_SETTINGS_ADDONS 1982 1983 /** 1984 * Settinsg API additions. 1985 */ 1986 namespace settings 1987 { 1988 1989 /// @todo once string data in Bstr and Utf8Str is auto_ref_ptr, enable the 1990 /// code below 1991 1992 #if 0 1993 1994 /** Specialization of FromString for Bstr. */ 1995 template<> com::Bstr FromString <com::Bstr> (const char *aValue); 1996 1997 #endif 1998 1999 /** Specialization of ToString for Bstr. */ 2000 template<> stdx::char_auto_ptr 2001 ToString <com::Bstr> (const com::Bstr &aValue, unsigned int aExtra); 2002 2003 /** Specialization of FromString for Guid. */ 2004 template<> com::Guid FromString <com::Guid> (const char *aValue); 2005 2006 /** Specialization of ToString for Guid. */ 2007 template<> stdx::char_auto_ptr 2008 ToString <com::Guid> (const com::Guid &aValue, unsigned int aExtra); 2009 2010 } /* namespace settings */ 2011 2012 #endif /* VBOX_MAIN_SETTINGS_ADDONS */ 2013 1926 2014 #endif // ____H_VIRTUALBOXBASEIMPL -
trunk/src/VBox/Main/include/VirtualBoxImpl.h
r5999 r6076 1 /* $Id$ */ 2 1 3 /** @file 2 4 * … … 20 22 21 23 #include "VirtualBoxBase.h" 22 #include "VirtualBoxXMLUtil.h"23 24 24 25 #include "VBox/com/EventQueue.h" 25 26 #include <VBox/cfgldr.h>27 26 28 27 #include <list> … … 60 59 class ATL_NO_VTABLE VirtualBox : 61 60 public VirtualBoxBaseWithChildrenNEXT, 62 public VirtualBoxXMLUtil,63 61 public VirtualBoxSupportErrorInfoImpl <VirtualBox, IVirtualBox>, 64 62 public VirtualBoxSupportTranslation <VirtualBox>, … … 253 251 HRESULT unregisterDiffHardDisk (HardDisk *aHardDisk); 254 252 255 HRESULT saveSettings() { return saveConfig(); }253 HRESULT saveSettings(); 256 254 HRESULT updateSettings (const char *aOldPath, const char *aNewPath); 257 255 258 256 const Bstr &settingsFileName() { return mData.mCfgFile.mName; } 257 258 class SettingsInputResolver : public settings::XmlTreeBackend::InputResolver 259 { 260 public: 261 262 settings::Input *resolveEntity (const char *aURI, const char *aID); 263 }; 264 265 static HRESULT loadSettingsTree (settings::XmlTreeBackend &aTree, 266 settings::File &aFile, 267 bool aValidate, 268 bool aCatchLoadErrors, 269 bool aAddDefaults); 270 271 /** 272 * Shortcut to loadSettingsTree (aTree, aFile, true, true, true). 273 * 274 * Used when the settings file is to be loaded for the first time for the 275 * given object in order to recreate it from the stored settings. 276 */ 277 static HRESULT loadSettingsTree_FirstTime (settings::XmlTreeBackend &aTree, 278 settings::File &aFile) 279 { 280 return loadSettingsTree (aTree, aFile, true, true, true); 281 } 282 283 /** 284 * Shortcut to loadSettingsTree (aTree, aFile, true, false, true). 285 * 286 * Used when the settings file is loaded again (after it has been fully 287 * checked and validated by #loadSettingsTree_FirstTime()) in order to 288 * look at settings that don't have any representation within object's 289 * data fields. 290 */ 291 static HRESULT loadSettingsTree_Again (settings::XmlTreeBackend &aTree, 292 settings::File &aFile) 293 { 294 return loadSettingsTree (aTree, aFile, true, false, true); 295 } 296 297 /** 298 * Shortcut to loadSettingsTree (aTree, aFile, true, false, false). 299 * 300 * Used when the settings file is loaded again (after it has been fully 301 * checked and validated by #loadSettingsTree_FirstTime()) in order to 302 * update some settings and then save them back. 303 */ 304 static HRESULT loadSettingsTree_ForUpdate (settings::XmlTreeBackend &aTree, 305 settings::File &aFile) 306 { 307 return loadSettingsTree (aTree, aFile, true, false, false); 308 } 309 310 static HRESULT saveSettingsTree (settings::TreeBackend &aTree, 311 settings::File &aFile); 312 313 static HRESULT handleUnexpectedExceptions (RT_SRC_POS_DECL); 259 314 260 315 /* for VirtualBoxSupportErrorInfoImpl */ … … 290 345 const Guid *aId, const BSTR aFilePathFull); 291 346 292 HRESULT loadMachines (CFGNODE aGlobal); 293 HRESULT loadDisks (CFGNODE aGlobal); 294 HRESULT loadHardDisks (CFGNODE aNode); 295 296 HRESULT saveConfig(); 297 HRESULT saveHardDisks (CFGNODE aNode); 347 HRESULT loadMachines (const settings::Key &aGlobal); 348 HRESULT loadDisks (const settings::Key &aGlobal); 349 HRESULT loadHardDisks (const settings::Key &aNode); 350 351 HRESULT saveHardDisks (settings::Key &aNode); 298 352 299 353 HRESULT registerMachine (Machine *aMachine); -
trunk/src/VBox/Main/include/VirtualBoxXMLUtil.h
r5999 r6076 1 /* $Id$ */ 2 1 3 /** @file 2 4 * 3 * VirtualBox XML utility class declaration5 * VirtualBox XML/Settings API utility declarations 4 6 */ 5 7 … … 18 20 #ifndef ____H_VIRTUALBOXXMLUTIL 19 21 #define ____H_VIRTUALBOXXMLUTIL 20 21 // for BSTR referred from VBox/cfgldr.h22 #include "VBox/com/defs.h"23 24 #include <VBox/cdefs.h>25 #include <VBox/cfgldr.h>26 #include <iprt/file.h>27 22 28 23 /** VirtualBox XML settings namespace */ … … 59 54 #define VBOX_XML_SCHEMA_COMMON "VirtualBox-settings-" VBOX_XML_PLATFORM_COMMON ".xsd" 60 55 61 class VirtualBoxXMLUtil 62 { 63 protected: 64 65 static DECLCALLBACK(int) cfgLdrEntityResolver (const char *pcszPublicId, 66 const char *pcszSystemId, 67 const char *pcszBaseURI, 68 PCFGLDRENTITY pEntity); 69 70 /** VirtualBox XML settings "namespace schema" pair */ 71 static const char *XmlSchemaNS; 72 }; 73 74 75 #endif // ____H_VIRTUALBOXXMLUTIL 76 56 #endif /* ____H_VIRTUALBOXXMLUTIL */ -
trunk/src/VBox/Main/xml/VirtualBox-settings-common.xsd
r5999 r6076 303 303 <xsd:attribute name="port" type="xsd:token"/> 304 304 <xsd:attribute name="remote" type="xsd:token"/> 305 <xsd:attribute name="maskedInterfaces" type="xsd:unsignedInt" />305 <xsd:attribute name="maskedInterfaces" type="xsd:unsignedInt" default="0"/> 306 306 </xsd:complexType> 307 307 … … 437 437 438 438 <xsd:complexType name="TRemoteDisplay"> 439 <xsd:attribute name="enabled" type="xsd:boolean" />439 <xsd:attribute name="enabled" type="xsd:boolean" use="required"/> 440 440 <xsd:attribute name="port" type="xsd:unsignedInt" default="0"/> 441 441 <xsd:attribute name="netAddress" type="xsd:token" default=""/> … … 644 644 <xsd:complexType name="THardware"> 645 645 <xsd:all> 646 <xsd:element name="CPU" type="TCPU" minOccurs ="0"/>646 <xsd:element name="CPU" type="TCPU" minOccurs="0"/> 647 647 <xsd:element name="Memory" type="TMemory"/> 648 648 <xsd:element name="Boot" type="TBoot"> … … 708 708 <!--- @todo (dmik) make lastStateChange required on next format change! --> 709 709 <xsd:attribute name="lastStateChange" type="TPresentDateTimeUTC"/> 710 <xsd:attribute name="aborted" type="xsd:boolean" />710 <xsd:attribute name="aborted" type="xsd:boolean" default="false"/> 711 711 <xsd:attribute name="currentStateModified" type="xsd:boolean" default="true"/> 712 712 </xsd:complexType> -
trunk/src/VBox/Main/xml/VirtualBox-settings-freebsd.xsd
r5999 r6076 86 86 87 87 <xsd:complexType name="TAudioAdapter"> 88 <xsd:attribute name="enabled" type="xsd:boolean" />88 <xsd:attribute name="enabled" type="xsd:boolean" use="required"/> 89 89 <xsd:attribute name="driver" use="required"> 90 90 <!--- @todo (dmik) capitalize enum values on next format change! --> -
trunk/src/VBox/Main/xml/VirtualBox-settings-linux.xsd
r6056 r6076 86 86 87 87 <xsd:complexType name="TAudioAdapter"> 88 <xsd:attribute name="enabled" type="xsd:boolean" />88 <xsd:attribute name="enabled" type="xsd:boolean" use="required"/> 89 89 <xsd:attribute name="driver" use="required"> 90 90 <!--- @todo (dmik) capitalize enum values on next format change! --> -
trunk/src/VBox/Main/xml/VirtualBox-settings-macosx.xsd
r5999 r6076 86 86 87 87 <xsd:complexType name="TAudioAdapter"> 88 <xsd:attribute name="enabled" type="xsd:boolean" />88 <xsd:attribute name="enabled" type="xsd:boolean" use="required"/> 89 89 <xsd:attribute name="driver" use="required"> 90 90 <!--- @todo (dmik) capitalize enum values on next format change! --> -
trunk/src/VBox/Main/xml/VirtualBox-settings-os2.xsd
r5999 r6076 86 86 87 87 <xsd:complexType name="TAudioAdapter"> 88 <xsd:attribute name="enabled" type="xsd:boolean" />88 <xsd:attribute name="enabled" type="xsd:boolean" use="required"/> 89 89 <xsd:attribute name="driver" use="required"> 90 90 <!--- @todo (dmik) capitalize enum values on next format change! --> -
trunk/src/VBox/Main/xml/VirtualBox-settings-solaris.xsd
r5999 r6076 86 86 87 87 <xsd:complexType name="TAudioAdapter"> 88 <xsd:attribute name="enabled" type="xsd:boolean" />88 <xsd:attribute name="enabled" type="xsd:boolean" use="required"/> 89 89 <xsd:attribute name="driver" use="required"> 90 90 <!--- @todo (dmik) capitalize enum values on next format change! --> -
trunk/src/VBox/Main/xml/VirtualBox-settings-windows.xsd
r5999 r6076 84 84 85 85 <xsd:complexType name="TAudioAdapter"> 86 <xsd:attribute name="enabled" type="xsd:boolean" />86 <xsd:attribute name="enabled" type="xsd:boolean" use="required"/> 87 87 <xsd:attribute name="driver" use="required"> 88 88 <!--- @todo (dmik) capitalize enum values on next format change! -->
Note:
See TracChangeset
for help on using the changeset viewer.