3478
* Remembers the given hard disk by storing it in either the global hard disk registry
3481
* @note Caller must hold the media tree lock for writing; in addition, this locks @a aHardDisk for reading
3483
* @param aHardDisk Hard disk object to remember.
3484
* @param uuidMachineRegistry UUID of machine whose registry should be used, or a NULL UUID for the global registry.
3468
* Remembers the given medium object by storing it in either the global
3469
* medium registry or a machine one.
3471
* @note Caller must hold the media tree lock for writing; in addition, this locks @a pMedium for reading
3473
* @param pMedium Medium object to remember.
3474
* @param ppMedium Actually stored medium object. Can be different if due
3475
* to an unavoidable race there was a duplicate Medium object
3477
* @param argType Either DeviceType_HardDisk, DeviceType_DVD or DeviceType_Floppy.
3485
3478
* @param pllRegistriesThatNeedSaving Optional pointer to a list of UUIDs of media registries that need saving.
3488
HRESULT VirtualBox::registerHardDisk(Medium *pMedium,
3489
GuidList *pllRegistriesThatNeedSaving)
3481
HRESULT VirtualBox::registerMedium(const ComObjPtr<Medium> &pMedium,
3482
ComObjPtr<Medium> *ppMedium,
3483
DeviceType_T argType,
3484
GuidList *pllRegistriesThatNeedSaving)
3491
3486
AssertReturn(pMedium != NULL, E_INVALIDARG);
3487
AssertReturn(ppMedium != NULL, E_INVALIDARG);
3493
3489
AutoCaller autoCaller(this);
3494
3490
AssertComRCReturn(autoCaller.rc(), autoCaller.rc());
3496
AutoCaller hardDiskCaller(pMedium);
3497
AssertComRCReturn(hardDiskCaller.rc(), hardDiskCaller.rc());
3492
AutoCaller mediumCaller(pMedium);
3493
AssertComRCReturn(mediumCaller.rc(), mediumCaller.rc());
3495
const char *pszDevType = NULL;
3496
ObjectsList<Medium> *pall = NULL;
3499
case DeviceType_HardDisk:
3500
pall = &m->allHardDisks;
3501
pszDevType = tr("hard disk");
3503
case DeviceType_DVD:
3504
pszDevType = tr("DVD image");
3505
pall = &m->allDVDImages;
3507
case DeviceType_Floppy:
3508
pszDevType = tr("floppy image");
3509
pall = &m->allFloppyImages;
3512
AssertMsgFailedReturn(("invalid device type %d", argType), E_INVALIDARG);
3499
3515
// caller must hold the media tree write lock
3500
3516
Assert(getMediaTreeLockHandle().isWriteLockOnCurrentThread());
3514
3530
Utf8Str strConflict;
3531
ComObjPtr<Medium> pDupMedium;
3516
3532
rc = checkMediaForConflicts(id,
3517
3533
strLocationFull,
3520
3536
if (FAILED(rc)) return rc;
3538
if (pDupMedium.isNull())
3524
3540
if (strConflict.length())
3525
3541
return setError(E_INVALIDARG,
3526
tr("Cannot register the hard disk '%s' {%RTuuid} because a %s already exists"),
3542
tr("Cannot register the %s '%s' {%RTuuid} because a %s already exists"),
3527
3544
strLocationFull.c_str(),
3529
3546
strConflict.c_str(),
3530
3547
m->strSettingsFilePath.c_str());
3532
// store base (root) hard disks in the list
3549
// add to the collection if it is a base medium
3533
3550
if (pParent.isNull())
3534
m->allHardDisks.getList().push_back(pMedium);
3535
// access the list directly because we already locked the list above
3551
pall->getList().push_back(pMedium);
3537
3553
// store all hard disks (even differencing images) in the map
3538
m->mapHardDisks[id] = pMedium;
3554
if (argType == DeviceType_HardDisk)
3555
m->mapHardDisks[id] = pMedium;
3557
*ppMedium = pMedium;
3540
3559
if (pllRegistriesThatNeedSaving)
3541
3560
pMedium->addToRegistryIDList(*pllRegistriesThatNeedSaving);
3562
*ppMedium = pMedium;
3566
// pMedium may be the last reference to the Medium object, and the
3567
// caller may have specified the same ComObjPtr as the output parameter.
3568
// In this case the assignment will uninit the object, and we must not
3569
// have a caller pending.
3570
mediumCaller.release();
3571
*ppMedium = pDupMedium;
3573
// no need to update pllRegistriesThatNeedSaving since there must be
3574
// already some saved medium registry which contains the data.
3548
* Removes the given hard disk from the hard disk registry.
3550
* @param aHardDisk Hard disk object to remove.
3551
* @param pfNeedsGlobalSaveSettings Optional pointer to a bool that must have been initialized to false and that will be set to true
3552
* by this function if the caller should invoke VirtualBox::saveSettings() because the global settings have changed.
3554
* @note Caller must hold the media tree lock for writing; in addition, this locks @a aHardDisk for reading
3581
* Removes the given medium from the respective registry.
3583
* @param pMedium Hard disk object to remove.
3584
* @param pllRegistriesThatNeedSaving Optional pointer to a list of UUIDs of media registries that need saving.
3586
* @note Caller must hold the media tree lock for writing; in addition, this locks @a pMedium for reading
3556
HRESULT VirtualBox::unregisterHardDisk(Medium *aHardDisk,
3557
GuidList *pllRegistriesThatNeedSaving)
3588
HRESULT VirtualBox::unregisterMedium(Medium *pMedium,
3589
GuidList *pllRegistriesThatNeedSaving)
3559
AssertReturn(aHardDisk != NULL, E_INVALIDARG);
3591
AssertReturn(pMedium != NULL, E_INVALIDARG);
3561
3593
AutoCaller autoCaller(this);
3562
3594
AssertComRCReturn(autoCaller.rc(), autoCaller.rc());
3564
AutoCaller hardDiskCaller(aHardDisk);
3565
AssertComRCReturn(hardDiskCaller.rc(), hardDiskCaller.rc());
3596
AutoCaller mediumCaller(pMedium);
3597
AssertComRCReturn(mediumCaller.rc(), mediumCaller.rc());
3567
3599
// caller must hold the media tree write lock
3568
3600
Assert(getMediaTreeLockHandle().isWriteLockOnCurrentThread());
3571
3603
ComObjPtr<Medium> pParent;
3573
AutoReadLock hardDiskLock(aHardDisk COMMA_LOCKVAL_SRC_POS);
3574
id = aHardDisk->getId();
3575
pParent = aHardDisk->getParent();
3578
// remove base (root) hard disks from the list
3604
DeviceType_T devType;
3606
AutoReadLock mediumLock(pMedium COMMA_LOCKVAL_SRC_POS);
3607
id = pMedium->getId();
3608
pParent = pMedium->getParent();
3609
devType = pMedium->getDeviceType();
3612
ObjectsList<Medium> *pall = NULL;
3615
case DeviceType_HardDisk:
3616
pall = &m->allHardDisks;
3618
case DeviceType_DVD:
3619
pall = &m->allDVDImages;
3621
case DeviceType_Floppy:
3622
pall = &m->allFloppyImages;
3625
AssertMsgFailedReturn(("invalid device type %d", devType), E_INVALIDARG);
3628
// remove from the collection if it is a base medium
3579
3629
if (pParent.isNull())
3580
m->allHardDisks.getList().remove(aHardDisk);
3581
// access the list directly because caller must have locked the list
3630
pall->getList().remove(pMedium);
3583
3632
// remove all hard disks (even differencing images) from map
3584
size_t cnt = m->mapHardDisks.erase(id);
3633
if (devType == DeviceType_HardDisk)
3635
size_t cnt = m->mapHardDisks.erase(id);
3588
3640
if (pllRegistriesThatNeedSaving)
3589
aHardDisk->addToRegistryIDList(*pllRegistriesThatNeedSaving);
3641
pMedium->addToRegistryIDList(*pllRegistriesThatNeedSaving);
3595
* Remembers the given image by storing it in the CD/DVD or floppy image registry.
3597
* @param argImage Image object to remember.
3598
* @param argType Either DeviceType_DVD or DeviceType_Floppy.
3599
* @param uuidMachineRegistry UUID of machine whose registry should be used, or a NULL UUID for the global registry.
3601
* @note Caller must hold the media tree lock for writing; in addition, this locks @a argImage for reading
3603
HRESULT VirtualBox::registerImage(Medium *pMedium,
3604
DeviceType_T argType,
3605
GuidList *pllRegistriesThatNeedSaving)
3607
AssertReturn(pMedium != NULL, E_INVALIDARG);
3609
AutoCaller autoCaller(this);
3610
AssertComRCReturn(autoCaller.rc(), autoCaller.rc());
3612
AutoCaller imageCaller(pMedium);
3613
AssertComRCReturn(imageCaller.rc(), imageCaller.rc());
3615
// caller must hold the media tree write lock
3616
Assert(getMediaTreeLockHandle().isWriteLockOnCurrentThread());
3619
Utf8Str strLocationFull;
3620
ComObjPtr<Medium> pParent;
3622
AutoReadLock al(pMedium COMMA_LOCKVAL_SRC_POS);
3623
id = pMedium->getId();
3624
strLocationFull = pMedium->getLocationFull();
3625
pParent = pMedium->getParent();
3628
// work on DVDs or floppies list?
3629
ObjectsList<Medium> &all = (argType == DeviceType_DVD) ? m->allDVDImages : m->allFloppyImages;
3632
// lock the images lists (list + map) while checking for conflicts
3633
AutoWriteLock al(all.getLockHandle() COMMA_LOCKVAL_SRC_POS);
3635
Utf8Str strConflict;
3637
rc = checkMediaForConflicts(id,
3641
if (FAILED(rc)) return rc;
3645
if (strConflict.length())
3646
return setError(VBOX_E_INVALID_OBJECT_STATE,
3647
tr("Cannot register the image '%s' with UUID {%RTuuid} because a %s already exists"),
3648
strLocationFull.c_str(),
3650
strConflict.c_str());
3652
// add to the collection
3653
all.getList().push_back(pMedium);
3654
// access the list directly because we already locked the list above
3656
if (pllRegistriesThatNeedSaving)
3657
pMedium->addToRegistryIDList(*pllRegistriesThatNeedSaving);
3664
* Removes the given image from the CD/DVD or floppy image registry.
3666
* @param argImage Image object to remove.
3667
* @param argType Either DeviceType_DVD or DeviceType_Floppy.
3668
* @param pfNeedsGlobalSaveSettings Optional pointer to a bool that must have been initialized to false and that will be set to true
3669
* by this function if the caller should invoke VirtualBox::saveSettings() because the global settings have changed.
3671
* @note Caller must hold the media tree lock for writing; in addition, this locks @a argImage for reading
3673
HRESULT VirtualBox::unregisterImage(Medium *argImage,
3674
DeviceType_T argType,
3675
GuidList *pllRegistriesThatNeedSaving)
3677
AssertReturn(argImage != NULL, E_INVALIDARG);
3679
AutoCaller autoCaller(this);
3680
AssertComRCReturn(autoCaller.rc(), autoCaller.rc());
3682
AutoCaller imageCaller(argImage);
3683
AssertComRCReturn(imageCaller.rc(), imageCaller.rc());
3685
// caller must hold the media tree write lock
3686
Assert(getMediaTreeLockHandle().isWriteLockOnCurrentThread());
3689
ComObjPtr<Medium> pParent;
3691
AutoReadLock al(argImage COMMA_LOCKVAL_SRC_POS);
3692
id = argImage->getId();
3693
pParent = argImage->getParent();
3696
// work on DVDs or floppies list?
3697
ObjectsList<Medium> &all = (argType == DeviceType_DVD) ? m->allDVDImages : m->allFloppyImages;
3699
// access the list directly because the caller must have requested the lock
3700
all.getList().remove(argImage);
3704
if (pllRegistriesThatNeedSaving)
3705
argImage->addToRegistryIDList(*pllRegistriesThatNeedSaving);
3711
3647
* Little helper called from unregisterMachineMedia() to recursively add media to the given list,
3712
3648
* with children appearing before their parents.
3713
3649
* @param llMedia