VirtualBox

Ignore:
Timestamp:
Oct 27, 2008 2:04:18 PM (16 years ago)
Author:
vboxsync
Message:

Ported s2 branch (r37120:38456).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/ConsoleImpl.cpp

    r13556 r13580  
     1/* $Id$ */
     2
    13/** @file
    24 *
     
    57
    68/*
    7  * Copyright (C) 2006-2007 Sun Microsystems, Inc.
     9 * Copyright (C) 2006-2008 Sun Microsystems, Inc.
    810 *
    911 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    6062#include "Logging.h"
    6163
     64#include <VBox/com/array.h>
     65
    6266#include <iprt/string.h>
    6367#include <iprt/asm.h>
     
    187191        , mSetVMErrorCallback (NULL), mConfigConstructor (NULL), mStartPaused (false) {}
    188192
     193    ~VMPowerUpTask()
     194    {
     195        /* No null output parameters in IPC*/
     196        MediaState_T dummy;
     197
     198        /* if the locked media list is not empty, treat as a failure and
     199         * unlock all */
     200        for (LockedMedia::const_iterator it = lockedMedia.begin();
     201             it != lockedMedia.end(); ++ it)
     202        {
     203            if (it->second)
     204                it->first->UnlockWrite (&dummy);
     205            else
     206                it->first->UnlockRead (&dummy);
     207        }
     208    }
     209
    189210    PFNVMATERROR mSetVMErrorCallback;
    190211    PFNCFGMCONSTRUCTOR mConfigConstructor;
     
    192213    Console::SharedFolderDataMap mSharedFolders;
    193214    bool mStartPaused;
     215
     216    /**
     217     * Successfully locked media list. The 2nd value in the pair is true if the
     218     * medium is locked for writing and false if locked for reading.
     219     */
     220    typedef std::list <std::pair <ComPtr <IMedium>, bool > > LockedMedia;
     221    LockedMedia lockedMedia;
     222
     223    /** Media that need an accessibility check */
     224    typedef std::list <ComPtr <IMedium> > Media;
     225    Media mediaToCheck;
    194226};
    195227
     
    24812513        case DriveState_ImageMounted:
    24822514        {
    2483             ComPtr <IDVDImage> ImagePtr;
     2515            ComPtr <IDVDImage2> ImagePtr;
    24842516            rc = mDVDDrive->GetImage (ImagePtr.asOutParam());
    24852517            if (SUCCEEDED (rc))
    2486                 rc = ImagePtr->COMGETTER(FilePath) (Path.asOutParam());
     2518                rc = ImagePtr->COMGETTER(Location) (Path.asOutParam());
    24872519            break;
    24882520        }
     
    25882620        case DriveState_ImageMounted:
    25892621        {
    2590             ComPtr <IFloppyImage> ImagePtr;
     2622            ComPtr <IFloppyImage2> ImagePtr;
    25912623            rc = mFloppyDrive->GetImage (ImagePtr.asOutParam());
    25922624            if (SUCCEEDED (rc))
    2593                 rc = ImagePtr->COMGETTER(FilePath) (Path.asOutParam());
     2625                rc = ImagePtr->COMGETTER(Location) (Path.asOutParam());
    25942626            break;
    25952627        }
     
    42354267                        mMachineState);
    42364268
    4237     /*
    4238      * First check whether all disks are accessible. This is not a 100%
    4239      * bulletproof approach (race condition, it might become inaccessible
    4240      * right after the check) but it's convenient as it will cover 99.9%
    4241      * of the cases and here, we're able to provide meaningful error
    4242      * information.
    4243      */
    4244     ComPtr<IHardDiskAttachmentCollection> coll;
    4245     mMachine->COMGETTER(HardDiskAttachments)(coll.asOutParam());
    4246     ComPtr<IHardDiskAttachmentEnumerator> enumerator;
    4247     coll->Enumerate(enumerator.asOutParam());
    4248     BOOL fHasMore;
    4249     while (SUCCEEDED(enumerator->HasMore(&fHasMore)) && fHasMore)
    4250     {
    4251         ComPtr<IHardDiskAttachment> attach;
    4252         enumerator->GetNext(attach.asOutParam());
    4253         ComPtr<IHardDisk> hdd;
    4254         attach->COMGETTER(HardDisk)(hdd.asOutParam());
    4255         Assert(hdd);
    4256         BOOL fAccessible;
    4257         HRESULT rc = hdd->COMGETTER(AllAccessible)(&fAccessible);
    4258         CheckComRCReturnRC (rc);
    4259         if (!fAccessible)
    4260         {
    4261             Bstr loc;
    4262             hdd->COMGETTER(Location) (loc.asOutParam());
    4263             Bstr errMsg;
    4264             hdd->COMGETTER(LastAccessError) (errMsg.asOutParam());
    4265             return setError (E_FAIL,
    4266                 tr ("VM cannot start because the hard disk '%ls' is not accessible "
    4267                     "(%ls)"),
    4268                 loc.raw(), errMsg.raw());
    4269         }
    4270     }
    4271 
    4272     /* now perform the same check if a ISO is mounted */
    4273     ComPtr<IDVDDrive> dvdDrive;
    4274     mMachine->COMGETTER(DVDDrive)(dvdDrive.asOutParam());
    4275     ComPtr<IDVDImage> dvdImage;
    4276     dvdDrive->GetImage(dvdImage.asOutParam());
    4277     if (dvdImage)
    4278     {
    4279         BOOL fAccessible;
    4280         HRESULT rc = dvdImage->COMGETTER(Accessible)(&fAccessible);
    4281         CheckComRCReturnRC (rc);
    4282         if (!fAccessible)
    4283         {
    4284             Bstr filePath;
    4285             dvdImage->COMGETTER(FilePath)(filePath.asOutParam());
    4286             /// @todo (r=dmik) grab the last access error once
    4287             //  IDVDImage::lastAccessError is there
    4288             return setError (E_FAIL,
    4289                 tr ("The virtual machine could not be started because the DVD image '%ls' which is attached to it could not be found or could not be opened.  Please detach the image and try again"),
    4290                 filePath.raw());
    4291         }
    4292     }
    4293 
    4294     /* now perform the same check if a floppy is mounted */
    4295     ComPtr<IFloppyDrive> floppyDrive;
    4296     mMachine->COMGETTER(FloppyDrive)(floppyDrive.asOutParam());
    4297     ComPtr<IFloppyImage> floppyImage;
    4298     floppyDrive->GetImage(floppyImage.asOutParam());
    4299     if (floppyImage)
    4300     {
    4301         BOOL fAccessible;
    4302         HRESULT rc = floppyImage->COMGETTER(Accessible)(&fAccessible);
    4303         CheckComRCReturnRC (rc);
    4304         if (!fAccessible)
    4305         {
    4306             Bstr filePath;
    4307             floppyImage->COMGETTER(FilePath)(filePath.asOutParam());
    4308             /// @todo (r=dmik) grab the last access error once
    4309             //  IDVDImage::lastAccessError is there
    4310             return setError (E_FAIL,
    4311                 tr ("The virtual machine could not be started because the floppy image '%ls' which is attached to it could not be found or could not be opened.  Please detach the image and try again"),
    4312                 filePath.raw());
    4313         }
    4314     }
    4315 
    4316     /* now the network cards will undergo a quick consistency check */
     4269    HRESULT rc = S_OK;
     4270
     4271    /* the network cards will undergo a quick consistency check */
    43174272    for (ULONG slot = 0; slot < SchemaDefs::NetworkAdapterCount; slot ++)
    43184273    {
     
    43634318
    43644319    /* Read console data stored in the saved state file (if not yet done) */
    4365     {
    4366         HRESULT rc = loadDataFromSavedState();
    4367         CheckComRCReturnRC (rc);
    4368     }
     4320    rc = loadDataFromSavedState();
     4321    CheckComRCReturnRC (rc);
    43694322
    43704323    /* Check all types of shared folders and compose a single list */
     
    43944347    if (mMachineState == MachineState_Saved)
    43954348    {
    4396         HRESULT rc = mMachine->COMGETTER(StateFilePath) (savedStateFile.asOutParam());
     4349        rc = mMachine->COMGETTER(StateFilePath) (savedStateFile.asOutParam());
    43974350        CheckComRCReturnRC (rc);
    43984351        ComAssertRet (!!savedStateFile, E_FAIL);
     
    44134366    else
    44144367        progressDesc = tr ("Starting virtual machine");
    4415     progress->init (static_cast <IConsole *> (this),
    4416                     progressDesc, FALSE /* aCancelable */);
     4368    rc = progress->init (static_cast <IConsole *> (this),
     4369                         progressDesc, FALSE /* aCancelable */);
     4370    CheckComRCReturnRC (rc);
    44174371
    44184372    /* pass reference to caller if requested */
     
    44204374        progress.queryInterfaceTo (aProgress);
    44214375
    4422     /* setup task object and thread to carry out the operation asynchronously */
     4376    /* setup task object and thread to carry out the operation
     4377     * asynchronously */
     4378
    44234379    std::auto_ptr <VMPowerUpTask> task (new VMPowerUpTask (this, progress));
    44244380    ComAssertComRCRetRC (task->rc());
     
    44314387        task->mSavedStateFile = savedStateFile;
    44324388
    4433     HRESULT hrc = consoleInitReleaseLog (mMachine);
    4434     if (FAILED (hrc))
    4435         return hrc;
     4389    /* Lock all attached media in necessary mode. Note that until
     4390     * setMachineState() is called below, it is OUR responsibility to unlock
     4391     * media on failure (and VMPowerUpTask::lockedMedia is used for that). After
     4392     * the setMachineState() call, VBoxSVC (SessionMachine::setMachineState())
     4393     * will unlock all the media upon the appropriate state change. Note that
     4394     * media accessibility checks are performed on the powerup thread because
     4395     * they may block. */
     4396
     4397    MediaState_T mediaState;
     4398
     4399    /* lock all hard disks for writing and their parents for reading */
     4400    {
     4401        com::SafeIfaceArray <IHardDisk2Attachment> atts;
     4402        rc = mMachine->
     4403            COMGETTER(HardDisk2Attachments) (ComSafeArrayAsOutParam (atts));
     4404        CheckComRCReturnRC (rc);
     4405
     4406        for (size_t i = 0; i < atts.size(); ++ i)
     4407        {
     4408            ComPtr <IHardDisk2> hardDisk;
     4409            rc = atts [i]->COMGETTER(HardDisk) (hardDisk.asOutParam());
     4410            CheckComRCReturnRC (rc);
     4411
     4412            bool first = true;
     4413
     4414            while (!hardDisk.isNull())
     4415            {
     4416                if (first)
     4417                {
     4418                    rc = hardDisk->LockWrite (&mediaState);
     4419                    CheckComRCReturnRC (rc);
     4420
     4421                    task->lockedMedia.push_back (VMPowerUpTask::LockedMedia::
     4422                                                 value_type (hardDisk, true));
     4423                    first = false;
     4424                }
     4425                else
     4426                {
     4427                    rc = hardDisk->LockRead (&mediaState);
     4428                    CheckComRCReturnRC (rc);
     4429
     4430                    task->lockedMedia.push_back (VMPowerUpTask::LockedMedia::
     4431                                                 value_type (hardDisk, false));
     4432                }
     4433
     4434                if (mediaState == MediaState_Inaccessible)
     4435                    task->mediaToCheck.push_back (hardDisk);
     4436
     4437                ComPtr <IHardDisk2> parent;
     4438                rc = hardDisk->COMGETTER(Parent) (parent.asOutParam());
     4439                CheckComRCReturnRC (rc);
     4440                hardDisk = parent;
     4441            }
     4442        }
     4443    }
     4444    /* lock the DVD image for reading if mounted */
     4445    {
     4446        ComPtr <IDVDDrive> drive;
     4447        rc = mMachine->COMGETTER(DVDDrive) (drive.asOutParam());
     4448        CheckComRCReturnRC (rc);
     4449
     4450        DriveState_T driveState;
     4451        rc = drive->COMGETTER(State) (&driveState);
     4452        CheckComRCReturnRC (rc);
     4453
     4454        if (driveState == DriveState_ImageMounted)
     4455        {
     4456            ComPtr <IDVDImage2> image;
     4457            rc = drive->GetImage (image.asOutParam());
     4458            CheckComRCReturnRC (rc);
     4459
     4460            rc = image->LockRead (&mediaState);
     4461            CheckComRCReturnRC (rc);
     4462
     4463            task->lockedMedia.push_back (VMPowerUpTask::LockedMedia::
     4464                                         value_type (image, false));
     4465
     4466            if (mediaState == MediaState_Inaccessible)
     4467                task->mediaToCheck.push_back (image);
     4468        }
     4469    }
     4470    /* lock the floppy image for reading if mounted */
     4471    {
     4472        ComPtr <IFloppyDrive> drive;
     4473        rc = mMachine->COMGETTER(FloppyDrive) (drive.asOutParam());
     4474        CheckComRCReturnRC (rc);
     4475
     4476        DriveState_T driveState;
     4477        rc = drive->COMGETTER(State) (&driveState);
     4478        CheckComRCReturnRC (rc);
     4479
     4480        if (driveState == DriveState_ImageMounted)
     4481        {
     4482            ComPtr <IFloppyImage2> image;
     4483            rc = drive->GetImage (image.asOutParam());
     4484            CheckComRCReturnRC (rc);
     4485
     4486            rc = image->LockRead (&mediaState);
     4487            CheckComRCReturnRC (rc);
     4488
     4489            task->lockedMedia.push_back (VMPowerUpTask::LockedMedia::
     4490                                         value_type (image, false));
     4491
     4492            if (mediaState == MediaState_Inaccessible)
     4493                task->mediaToCheck.push_back (image);
     4494        }
     4495    }
     4496    /* SUCCEEDED locking all media */
     4497
     4498    rc = consoleInitReleaseLog (mMachine);
     4499    CheckComRCReturnRC (rc);
    44364500
    44374501    int vrc = RTThreadCreate (NULL, Console::powerUpThread, (void *) task.get(),
     
    44414505                       E_FAIL);
    44424506
     4507    /* clear the locked media list to prevent unlocking on task destruction as
     4508     * we are not going to fail after this point */
     4509    task->lockedMedia.clear();
     4510
    44434511    /* task is now owned by powerUpThread(), so release it */
    44444512    task.release();
     4513
     4514    /* finally, set the state: no right to fail in this method afterwards! */
    44454515
    44464516    if (mMachineState == MachineState_Saved)
     
    61216191    /* we ignore RT_SRC_POS_DECL arguments to avoid confusion of end-users */
    61226192    va_list va2;
    6123     va_copy(va2, args); /* Have to make a copy here or GCC will break. */
    6124     Utf8Str errorMsg = Utf8StrFmt (tr ("%N.\n"
    6125                                        "VBox status code: %d (%Vrc)"),
    6126                                    pszFormat, &va2, rc, rc);
    6127     va_end(va2);
    6128 
    6129     /* For now, this may be called only once. Ignore subsequent calls. */
    6130     if (!task->mErrorMsg.isNull())
    6131     {
    6132 #if !defined(DEBUG_bird)
    6133         AssertMsgFailed (("Cannot set error to '%s': it is already set to '%s'",
    6134                           errorMsg.raw(), task->mErrorMsg.raw()));
    6135 #endif
    6136         return;
    6137     }
    6138 
    6139     task->mErrorMsg = errorMsg;
     6193    va_copy (va2, args); /* Have to make a copy here or GCC will break. */
     6194
     6195    /* append to the existing error message if any */
     6196    if (!task->mErrorMsg.isEmpty())
     6197        task->mErrorMsg = Utf8StrFmt ("%s.\n%N (%Vrc)", task->mErrorMsg.raw(),
     6198                                      pszFormat, &va2, rc, rc);
     6199    else
     6200        task->mErrorMsg = Utf8StrFmt ("%N (%Vrc)",
     6201                                      pszFormat, &va2, rc, rc);
     6202
     6203    va_end (va2);
    61406204}
    61416205
     
    64326496#endif
    64336497
    6434     HRESULT hrc = S_OK;
     6498    HRESULT rc = S_OK;
    64356499    int vrc = VINF_SUCCESS;
    64366500
     
    64456509    /* Note: no need to use addCaller() because VMPowerUpTask does that */
    64466510
     6511    /* The lock is also used as a signal from the task initiator (which
     6512     * releases it only after RTThreadCreate()) that we can start the job */
    64476513    AutoWriteLock alock (console);
    64486514
     
    64506516    Assert (console->mpVM == NULL);
    64516517
    6452     do
    6453     {
     6518    try
     6519    {
     6520        {
     6521            ErrorInfoKeeper eik (true /* aIsNull */);
     6522            MultiResult mrc (S_OK);
     6523
     6524            /* perform a check of inaccessible media deferred in PowerUp() */
     6525            for (VMPowerUpTask::Media::const_iterator
     6526                 it = task->mediaToCheck.begin();
     6527                 it != task->mediaToCheck.end(); ++ it)
     6528            {
     6529                MediaState_T mediaState;
     6530                rc = (*it)->COMGETTER(State) (&mediaState);
     6531                CheckComRCThrowRC (rc);
     6532
     6533                Assert (mediaState == MediaState_LockedRead ||
     6534                        mediaState == MediaState_LockedWrite);
     6535
     6536                /* Note that we locked the medium already, so use the error
     6537                 * value to see if there was an accessibility failure */
     6538
     6539                Bstr error;
     6540                rc = (*it)->COMGETTER(LastAccessError) (error.asOutParam());
     6541                CheckComRCThrowRC (rc);
     6542
     6543                if (!error.isNull())
     6544                {
     6545                    Bstr loc;
     6546                    rc = (*it)->COMGETTER(Location) (loc.asOutParam());
     6547                    CheckComRCThrowRC (rc);
     6548
     6549                    /* collect multiple errors */
     6550                    eik.restore();
     6551
     6552                    /* be in sync with MediumBase::setStateError() */
     6553                    Assert (!error.isEmpty());
     6554                    mrc = setError (E_FAIL,
     6555                        tr ("Medium '%ls' is not accessible. %ls"),
     6556                        loc.raw(), error.raw());
     6557
     6558                    eik.fetch();
     6559                }
     6560            }
     6561
     6562            eik.restore();
     6563            CheckComRCThrowRC ((HRESULT) mrc);
     6564        }
     6565
    64546566#ifdef VBOX_WITH_VRDP
     6567
    64556568        /* Create the VRDP server. In case of headless operation, this will
    64566569         * also create the framebuffer, required at VM creation.
     
    64586571        ConsoleVRDPServer *server = console->consoleVRDPServer();
    64596572        Assert (server);
     6573
    64606574        /// @todo (dmik)
    64616575        //      does VRDP server call Console from the other thread?
     
    64646578        vrc = server->Launch();
    64656579        alock.enter();
     6580
    64666581        if (VBOX_FAILURE (vrc))
    64676582        {
     
    64886603            LogRel (("Failed to launch VRDP server (%Vrc), error message: '%s'\n",
    64896604                     vrc, errMsg.raw()));
    6490             hrc = setError (E_FAIL, errMsg);
    6491             break;
    6492         }
     6605            throw setError (E_FAIL, errMsg);
     6606        }
     6607
    64936608#endif /* VBOX_WITH_VRDP */
    64946609
     
    65546669                         ++ it)
    65556670                    {
    6556                         hrc = console->createSharedFolder ((*it).first, (*it).second);
    6557                         CheckComRCBreakRC (hrc);
     6671                        rc = console->createSharedFolder ((*it).first, (*it).second);
     6672                        CheckComRCBreakRC (rc);
    65586673                    }
    65596674
     
    65616676                    alock.enter();
    65626677
    6563                     CheckComRCBreakRC (hrc);
     6678                    CheckComRCBreakRC (rc);
    65646679                }
    65656680
     
    65676682                 * Capture USB devices.
    65686683                 */
    6569                 hrc = console->captureUSBDevices (pVM);
    6570                 CheckComRCBreakRC (hrc);
     6684                rc = console->captureUSBDevices (pVM);
     6685                CheckComRCBreakRC (rc);
    65716686
    65726687                /* leave the lock before a lengthy operation */
     
    66196734
    66206735            /*  On failure, destroy the VM */
    6621             if (FAILED (hrc) || VBOX_FAILURE (vrc))
     6736            if (FAILED (rc) || VBOX_FAILURE (vrc))
    66226737            {
    66236738                /* preserve existing error info */
     
    66266741                /* powerDown() will call VMR3Destroy() and do all necessary
    66276742                 * cleanup (VRDP, USB devices) */
    6628                 HRESULT hrc2 = console->powerDown();
    6629                 AssertComRC (hrc2);
     6743                HRESULT rc2 = console->powerDown();
     6744                AssertComRC (rc2);
    66306745            }
    66316746        }
     
    66386753        }
    66396754
    6640         if (SUCCEEDED (hrc) && VBOX_FAILURE (vrc))
     6755        if (SUCCEEDED (rc) && VBOX_FAILURE (vrc))
    66416756        {
    66426757            /* If VMR3Create() or one of the other calls in this function fail,
    66436758             * an appropriate error message has been set in task->mErrorMsg.
    6644              * However since that happens via a callback, the hrc status code in
     6759             * However since that happens via a callback, the rc status code in
    66456760             * this function is not updated.
    66466761             */
     
    66606775            /* Set the error message as the COM error.
    66616776             * Progress::notifyComplete() will pick it up later. */
    6662             hrc = setError (E_FAIL, task->mErrorMsg);
    6663             break;
    6664         }
    6665     }
    6666     while (0);
     6777            throw setError (E_FAIL, task->mErrorMsg);
     6778        }
     6779    }
     6780    catch (HRESULT aRC) { rc = aRC; }
    66676781
    66686782    if (console->mMachineState == MachineState_Starting ||
     
    66956809    alock.leave();
    66966810
    6697     if (SUCCEEDED (hrc))
     6811    if (SUCCEEDED (rc))
    66986812    {
    66996813        /* Notify the progress object of the success */
     
    67036817    {
    67046818        /* The progress object will fetch the current error info */
    6705         task->mProgress->notifyComplete (hrc);
    6706 
    6707         LogRel (("Power up failed (vrc=%Vrc, hrc=%Rhrc (%#08X))\n", vrc, hrc, hrc));
     6819        task->mProgress->notifyComplete (rc);
     6820
     6821        LogRel (("Power up failed (vrc=%Vrc, rc=%Rhrc (%#08X))\n", vrc, rc, rc));
    67086822    }
    67096823
     
    67276841 *  @return  VBox status code.
    67286842 */
    6729 static DECLCALLBACK(int) reconfigureVDI(PVM pVM, IHardDiskAttachment *hda, HRESULT *phrc)
     6843static DECLCALLBACK(int) reconfigureHardDisks(PVM pVM, IHardDisk2Attachment *hda,
     6844                                              HRESULT *phrc)
    67306845{
    67316846    LogFlowFunc (("pVM=%p hda=%p phrc=%p\n", pVM, hda, phrc));
     
    67336848    int             rc;
    67346849    HRESULT         hrc;
    6735     char           *psz = NULL;
    6736     BSTR            str = NULL;
     6850    Bstr            bstr;
    67376851    *phrc = S_OK;
    6738 #define STR_CONV()  do { rc = RTUtf16ToUtf8(str, &psz); RC_CHECK(); } while (0)
    6739 #define STR_FREE()  do { if (str) { SysFreeString(str); str = NULL; } if (psz) { RTStrFree(psz); psz = NULL; } } while (0)
    6740 #define RC_CHECK()  do { if (VBOX_FAILURE(rc)) { AssertMsgFailed(("rc=%Vrc\n", rc)); STR_FREE(); return rc; } } while (0)
    6741 #define H() do { if (FAILED(hrc)) { AssertMsgFailed(("hrc=%Rhrc (%#x)\n", hrc, hrc)); STR_FREE(); *phrc = hrc; return VERR_GENERAL_FAILURE; } } while (0)
     6852#define RC_CHECK()  do { if (VBOX_FAILURE(rc)) { AssertMsgFailed(("rc=%Vrc\n", rc)); return rc; } } while (0)
     6853#define H() do { if (FAILED(hrc)) { AssertMsgFailed(("hrc=%Rhrc (%#x)\n", hrc, hrc)); *phrc = hrc; return VERR_GENERAL_FAILURE; } } while (0)
    67426854
    67436855    /*
    67446856     * Figure out which IDE device this is.
    67456857     */
    6746     ComPtr<IHardDisk> hardDisk;
     6858    ComPtr<IHardDisk2> hardDisk;
    67476859    hrc = hda->COMGETTER(HardDisk)(hardDisk.asOutParam());                      H();
    67486860    StorageBus_T enmBus;
     
    67586870        case StorageBus_IDE:
    67596871        {
    6760             if (lChannel >= 2)
     6872            if (lChannel >= 2 || lChannel < 0)
    67616873            {
    67626874                AssertMsgFailed(("invalid controller channel number: %d\n", lChannel));
     
    67646876            }
    67656877
    6766             if (lDev >= 2)
     6878            if (lDev >= 2 || lDev < 0)
    67676879            {
    67686880                AssertMsgFailed(("invalid controller device number: %d\n", lDev));
    67696881                return VERR_GENERAL_FAILURE;
    67706882            }
     6883
    67716884            iLUN = 2*lChannel + lDev;
    6772         }
    6773         break;
     6885            break;
     6886        }
    67746887        case StorageBus_SATA:
     6888        {
    67756889            iLUN = lChannel;
    67766890            break;
     6891        }
    67776892        default:
     6893        {
    67786894            AssertMsgFailed(("invalid disk controller type: %d\n", enmBus));
    67796895            return VERR_GENERAL_FAILURE;
     6896        }
    67806897    }
    67816898
     
    67996916
    68006917        rc = CFGMR3InsertNode(pLunL0,   "AttachedDriver", &pLunL1);                 RC_CHECK();
    6801         rc = CFGMR3InsertString(pLunL1, "Driver",              "VBoxHDD");          RC_CHECK();
     6918        rc = CFGMR3InsertString(pLunL1, "Driver",              "VD");               RC_CHECK();
    68026919        rc = CFGMR3InsertNode(pLunL1,   "Config", &pCfg);                           RC_CHECK();
    68036920    }
     
    68076924        char *pszDriver;
    68086925        rc = CFGMR3QueryStringAlloc(pLunL1, "Driver", &pszDriver);                  RC_CHECK();
    6809         Assert(!strcmp(pszDriver, "VBoxHDD"));
     6926        Assert(!strcmp(pszDriver, "VD"));
    68106927        MMR3HeapFree(pszDriver);
    68116928#endif
     
    68176934        AssertReturn(pCfg, VERR_INTERNAL_ERROR);
    68186935
    6819         /* the image */
    6820         /// @todo (dmik) we temporarily use the location property to
    6821         //  determine the image file name. This is subject to change
    6822         //  when iSCSI disks are here (we should either query a
    6823         //  storage-specific interface from IHardDisk, or "standardize"
    6824         //  the location property)
    6825         hrc = hardDisk->COMGETTER(Location)(&str);                                  H();
    6826         STR_CONV();
    6827         char *pszPath;
    6828         rc = CFGMR3QueryStringAlloc(pCfg, "Path", &pszPath);                        RC_CHECK();
    6829         if (!strcmp(psz, pszPath))
    6830         {
    6831             /* parent images. */
    6832             ComPtr<IHardDisk> parentHardDisk = hardDisk;
    6833             for (PCFGMNODE pParent = pCfg;;)
     6936        /* the format */
     6937        hrc = hardDisk->COMGETTER(Format)(bstr.asOutParam());                       H();
     6938        char *pszFormat;
     6939        rc = CFGMR3QueryStringAlloc(pCfg, "Format", &pszFormat);                    RC_CHECK();
     6940        if (bstr == pszFormat)
     6941        {
     6942            /* the image */
     6943            hrc = hardDisk->COMGETTER(Location)(bstr.asOutParam());                     H();
     6944            char *pszPath;
     6945            rc = CFGMR3QueryStringAlloc(pCfg, "Path", &pszPath);                        RC_CHECK();
     6946            if (bstr == pszPath)
    68346947            {
    6835                 MMR3HeapFree(pszPath);
    6836                 pszPath = NULL;
    6837                 STR_FREE();
    6838 
    6839                 /* get parent */
    6840                 ComPtr<IHardDisk> curHardDisk;
    6841                 hrc = parentHardDisk->COMGETTER(Parent)(curHardDisk.asOutParam());  H();
    6842                 PCFGMNODE pCur;
    6843                 pCur = CFGMR3GetChild(pParent, "Parent");
    6844                 if (!pCur && !curHardDisk)
     6948                /* parent images. */
     6949                ComPtr<IHardDisk2> parentHardDisk = hardDisk;
     6950                for (PCFGMNODE pParent = pCfg;;)
    68456951                {
    6846                     /* no change */
    6847                     LogFlowFunc (("No change!\n"));
    6848                     return VINF_SUCCESS;
     6952                    MMR3HeapFree(pszPath);
     6953                    pszPath = NULL;
     6954
     6955                    MMR3HeapFree(pszFormat);
     6956                    pszFormat = NULL;
     6957
     6958                    /* get parent */
     6959                    ComPtr<IHardDisk2> curHardDisk;
     6960                    hrc = parentHardDisk->COMGETTER(Parent)(curHardDisk.asOutParam());  H();
     6961                    PCFGMNODE pCur;
     6962                    pCur = CFGMR3GetChild(pParent, "Parent");
     6963                    if (!pCur && !curHardDisk)
     6964                    {
     6965                        /* no change */
     6966                        LogFlowFunc (("No change!\n"));
     6967                        return VINF_SUCCESS;
     6968                    }
     6969                    if (!pCur || !curHardDisk)
     6970                        break;
     6971
     6972                    /* compare formats. */
     6973                    hrc = curHardDisk->COMGETTER(Format)(bstr.asOutParam());            H();
     6974                    rc = CFGMR3QueryStringAlloc(pCfg, "Format", &pszPath);              RC_CHECK();
     6975                    if (bstr != pszFormat)
     6976                        break;
     6977
     6978                    /* compare paths. */
     6979                    hrc = curHardDisk->COMGETTER(Location)(bstr.asOutParam());          H();
     6980                    rc = CFGMR3QueryStringAlloc(pCfg, "Path", &pszPath);                RC_CHECK();
     6981                    if (bstr != pszPath)
     6982                        break;
     6983
     6984                    /* next */
     6985                    pParent = pCur;
     6986                    parentHardDisk = curHardDisk;
    68496987                }
    6850                 if (!pCur || !curHardDisk)
    6851                     break;
    6852 
    6853                 /* compare paths. */
    6854                 /// @todo (dmik) we temporarily use the location property to
    6855                 //  determine the image file name. This is subject to change
    6856                 //  when iSCSI disks are here (we should either query a
    6857                 //  storage-specific interface from IHardDisk, or "standardize"
    6858                 //  the location property)
    6859                 hrc = curHardDisk->COMGETTER(Location)(&str);                       H();
    6860                 STR_CONV();
    6861                 rc = CFGMR3QueryStringAlloc(pCfg, "Path", &pszPath);                RC_CHECK();
    6862                 if (strcmp(psz, pszPath))
    6863                     break;
    6864 
    6865                 /* next */
    6866                 pParent = pCur;
    6867                 parentHardDisk = curHardDisk;
     6988
    68686989            }
    6869 
     6990            else
     6991                LogFlowFunc (("LUN#%d: old leaf location '%s'\n", iLUN, pszPath));
     6992
     6993            MMR3HeapFree(pszPath);
    68706994        }
    68716995        else
    6872             LogFlowFunc (("LUN#%d: old leaf image '%s'\n", iLUN, pszPath));
    6873 
    6874         MMR3HeapFree(pszPath);
    6875         STR_FREE();
     6996            LogFlowFunc (("LUN#%d: old leaf format '%s'\n", iLUN, pszFormat));
     6997
     6998        MMR3HeapFree(pszFormat);
    68766999
    68777000        /*
     
    68867009     * Create the driver configuration.
    68877010     */
    6888     /// @todo (dmik) we temporarily use the location property to
    6889     //  determine the image file name. This is subject to change
    6890     //  when iSCSI disks are here (we should either query a
    6891     //  storage-specific interface from IHardDisk, or "standardize"
    6892     //  the location property)
    6893     hrc = hardDisk->COMGETTER(Location)(&str);                                  H();
    6894     STR_CONV();
    6895     LogFlowFunc (("LUN#%d: leaf image '%s'\n", iLUN, psz));
    6896     rc = CFGMR3InsertString(pCfg, "Path", psz);                                 RC_CHECK();
    6897     STR_FREE();
     7011    hrc = hardDisk->COMGETTER(Format)(bstr.asOutParam());                       H();
     7012    LogFlowFunc (("LUN#%d: leaf format '%ls'\n", iLUN, bstr.raw()));
     7013    rc = CFGMR3InsertString(pCfg, "Format", Utf8Str(bstr));                     RC_CHECK();
     7014    hrc = hardDisk->COMGETTER(Location)(bstr.asOutParam());                     H();
     7015    LogFlowFunc (("LUN#%d: leaf location '%ls'\n", iLUN, bstr.raw()));
     7016    rc = CFGMR3InsertString(pCfg, "Path", Utf8Str(bstr));                       RC_CHECK();
    68987017    /* Create an inversed tree of parents. */
    6899     ComPtr<IHardDisk> parentHardDisk = hardDisk;
     7018    ComPtr<IHardDisk2> parentHardDisk = hardDisk;
    69007019    for (PCFGMNODE pParent = pCfg;;)
    69017020    {
    6902         ComPtr<IHardDisk> curHardDisk;
     7021        ComPtr<IHardDisk2> curHardDisk;
    69037022        hrc = parentHardDisk->COMGETTER(Parent)(curHardDisk.asOutParam());      H();
    69047023        if (!curHardDisk)
     
    69077026        PCFGMNODE pCur;
    69087027        rc = CFGMR3InsertNode(pParent, "Parent", &pCur);                        RC_CHECK();
    6909         /// @todo (dmik) we temporarily use the location property to
    6910         //  determine the image file name. This is subject to change
    6911         //  when iSCSI disks are here (we should either query a
    6912         //  storage-specific interface from IHardDisk, or "standardize"
    6913         //  the location property)
    6914         hrc = curHardDisk->COMGETTER(Location)(&str);                           H();
    6915         STR_CONV();
    6916         rc = CFGMR3InsertString(pCur,  "Path", psz);                            RC_CHECK();
    6917         STR_FREE();
     7028        hrc = curHardDisk->COMGETTER(Format)(bstr.asOutParam());                H();
     7029        rc = CFGMR3InsertString(pCur,  "Format", Utf8Str(bstr));                RC_CHECK();
     7030        hrc = curHardDisk->COMGETTER(Location)(bstr.asOutParam());              H();
     7031        rc = CFGMR3InsertString(pCur,  "Path", Utf8Str(bstr));                  RC_CHECK();
    69187032
    69197033        /* next */
     
    70017115        do
    70027116        {
    7003             LogFlowFunc (("Reattaching new differencing VDIs...\n"));
    7004 
    7005             ComPtr <IHardDiskAttachmentCollection> hdaColl;
    7006             rc = that->mMachine->COMGETTER(HardDiskAttachments) (hdaColl.asOutParam());
     7117            LogFlowFunc (("Reattaching new differencing hard disks...\n"));
     7118
     7119            com::SafeIfaceArray <IHardDisk2Attachment> atts;
     7120            rc = that->mMachine->
     7121                COMGETTER(HardDisk2Attachments) (ComSafeArrayAsOutParam (atts));
    70077122            if (FAILED (rc))
    70087123                break;
    7009             ComPtr <IHardDiskAttachmentEnumerator> hdaEn;
    7010             rc = hdaColl->Enumerate (hdaEn.asOutParam());
    7011             if (FAILED (rc))
    7012                 break;
    7013             BOOL more = FALSE;
    7014             while (SUCCEEDED (rc = hdaEn->HasMore (&more)) && more)
     7124            for (size_t i = 0; i < atts.size(); ++ i)
    70157125            {
    7016                 ComPtr <IHardDiskAttachment> hda;
    7017                 rc = hdaEn->GetNext (hda.asOutParam());
    7018                 if (FAILED (rc))
    7019                     break;
    7020 
    70217126                PVMREQ pReq;
    7022                 IHardDiskAttachment *pHda = hda;
    70237127                /*
    7024                  *  don't leave the lock since reconfigureVDI isn't going to
    7025                  *  access Console.
     7128                 *  don't leave the lock since reconfigureHardDisks isn't going
     7129                 *  to access Console.
    70267130                 */
    70277131                int vrc = VMR3ReqCall (that->mpVM, &pReq, RT_INDEFINITE_WAIT,
    7028                                        (PFNRT)reconfigureVDI, 3, that->mpVM,
    7029                                        pHda, &rc);
     7132                                       (PFNRT)reconfigureHardDisks, 3, that->mpVM,
     7133                                       atts [i], &rc);
    70307134                if (VBOX_SUCCESS (rc))
    70317135                    rc = pReq->iStatus;
Note: See TracChangeset for help on using the changeset viewer.

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