VirtualBox

Changeset 24526 in vbox for trunk/src


Ignore:
Timestamp:
Nov 9, 2009 7:34:28 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
54630
Message:

OVF: fix import and export of floppy and DVD attachments broken by medium change; fix export progress bars for media with differencing images

Location:
trunk/src/VBox/Main
Files:
3 edited

Legend:

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

    r24525 r24526  
    2828#include <iprt/sha.h>
    2929#include <iprt/manifest.h>
    30 
    31 #include "ovfreader.h"
    3230
    3331#include <VBox/param.h>
     
    759757struct MyHardDiskAttachment
    760758{
    761     Guid    uuid;
    762     ComPtr<IMachine> pMachine;
    763     Bstr    controllerType;
    764     int32_t lChannel;
    765     int32_t lDevice;
     759    Guid                uuid;
     760    ComPtr<IMachine>    pMachine;
     761    Bstr                controllerType;
     762    int32_t             lChannel;
     763    int32_t             lDevice;
    766764};
    767765
     
    14741472            if (vsdeHDCSATA.size() > 1)
    14751473                throw setError(VBOX_E_FILE_ERROR,
    1476                                tr("Too many SATA controllers in OVF; VirtualBox only supports one"));
     1474                               tr("Too many SATA controllers in OVF; import facility only supports one"));
    14771475            if (vsdeHDCSATA.size() > 0)
    14781476            {
     
    14961494            if (vsdeHDCSCSI.size() > 1)
    14971495                throw setError(VBOX_E_FILE_ERROR,
    1498                                tr("Too many SCSI controllers in OVF; VirtualBox only supports one"));
     1496                               tr("Too many SCSI controllers in OVF; import facility only supports one"));
    14991497            if (vsdeHDCSCSI.size() > 0)
    15001498            {
     
    16821680                        mhda.pMachine = pNewMachine;
    16831681
    1684                         switch (hdc.system)
    1685                         {
    1686                             case HardDiskController::IDE:
    1687                                 // For the IDE bus, the channel parameter can be either 0 or 1, to specify the primary
    1688                                 // or secondary IDE controller, respectively. For the primary controller of the IDE bus,
    1689                                 // the device number can be either 0 or 1, to specify the master or the slave device,
    1690                                 // respectively. For the secondary IDE controller, the device number is always 1 because
    1691                                 // the master device is reserved for the CD-ROM drive.
    1692                                 mhda.controllerType = Bstr("IDE Controller");
    1693                                 switch (vd.ulAddressOnParent)
    1694                                 {
    1695                                     case 0:     // interpret this as primary master
    1696                                         mhda.lChannel = (long)0;
    1697                                         mhda.lDevice = (long)0;
    1698                                     break;
    1699 
    1700                                     case 1:     // interpret this as primary slave
    1701                                         mhda.lChannel = (long)0;
    1702                                         mhda.lDevice = (long)1;
    1703                                     break;
    1704 
    1705                                     case 2:     // interpret this as secondary slave
    1706                                         mhda.lChannel = (long)1;
    1707                                         mhda.lDevice = (long)1;
    1708                                     break;
    1709 
    1710                                     default:
    1711                                         throw setError(VBOX_E_NOT_SUPPORTED,
    1712                                                        tr("Invalid channel %RI16 specified; IDE controllers support only 0, 1 or 2"), vd.ulAddressOnParent);
    1713                                     break;
    1714                                 }
    1715                             break;
    1716 
    1717                             case HardDiskController::SATA:
    1718                                 mhda.controllerType = Bstr("SATA Controller");
    1719                                 mhda.lChannel = (long)vd.ulAddressOnParent;
    1720                                 mhda.lDevice = (long)0;
    1721                             break;
    1722 
    1723                             case HardDiskController::SCSI:
    1724                                 mhda.controllerType = Bstr("SCSI Controller");
    1725                                 mhda.lChannel = (long)vd.ulAddressOnParent;
    1726                                 mhda.lDevice = (long)0;
    1727                             break;
    1728 
    1729                             default: break;
    1730                         }
     1682                        ConvertDiskAttachmentValues(hdc,
     1683                                                    vd.ulAddressOnParent,
     1684                                                    mhda.controllerType,        // Bstr
     1685                                                    mhda.lChannel,
     1686                                                    mhda.lDevice);
    17311687
    17321688                        Log(("Attaching disk %s to channel %d on device %d\n", vsdeHD->strVbox.c_str(), mhda.lChannel, mhda.lDevice));
     
    17621718            }
    17631719
    1764 #if 0  // @todo Implement CD-ROM import for 3.1 final
    17651720            // Add CD-ROMs to the appropriate controllers.
    17661721            std::list<VirtualSystemDescriptionEntry*> vsdeCDROM = vsdescThis->findByType(VirtualSystemDescriptionType_CDROM);
     
    17841739                        ++it)
    17851740                    {
    1786                         VirtualSystemDescriptionEntry *pVSDE = *it;
    1787 
    1788                         // @@todo
     1741                        // for now always attach to secondary master on IDE controller;
     1742                        // there seems to be no useful information in OVF where else to
     1743                        // attach it (@todo test with latest versions of OVF software)
     1744
     1745                        // find the IDE controller
     1746                        const HardDiskController *pController = NULL;
     1747                        for (ControllersMap::const_iterator it = vsysThis.mapControllers.begin();
     1748                             it != vsysThis.mapControllers.end();
     1749                             ++it)
     1750                        {
     1751                            if (it->second.system == HardDiskController::IDE)
     1752                            {
     1753                                pController = &it->second;
     1754                            }
     1755                        }
     1756
     1757                        if (!pController)
     1758                            throw setError(VBOX_E_FILE_ERROR,
     1759                                           tr("OVF wants a CD-ROM drive but cannot find IDE controller, which is required in this version of VirtualBox"));
     1760
     1761                        // this is for rollback later
     1762                        MyHardDiskAttachment mhda;
     1763                        mhda.uuid = newMachineId;
     1764                        mhda.pMachine = pNewMachine;
     1765
     1766                        ConvertDiskAttachmentValues(*pController,
     1767                                                    2,     // interpreted as secondary master
     1768                                                    mhda.controllerType,        // Bstr
     1769                                                    mhda.lChannel,
     1770                                                    mhda.lDevice);
     1771
     1772                        Log(("Attaching CD-ROM to channel %d on device %d\n", mhda.lChannel, mhda.lDevice));
     1773
     1774                        ComPtr<IMachine> sMachine;
     1775                        rc = session->COMGETTER(Machine)(sMachine.asOutParam());
     1776                        if (FAILED(rc)) throw rc;
     1777
     1778                        rc = sMachine->AttachDevice(mhda.controllerType,
     1779                                                    mhda.lChannel,
     1780                                                    mhda.lDevice,
     1781                                                    DeviceType_DVD,
     1782                                                    Bstr(""));
     1783                        if (FAILED(rc)) throw rc;
     1784
     1785                        llHardDiskAttachments.push_back(mhda);
     1786
     1787                        rc = sMachine->SaveSettings();
     1788                        if (FAILED(rc)) throw rc;
    17891789
    17901790                    } // end for (itHD = avsdeHDs.begin();
     
    18061806                }
    18071807            }
    1808 #endif
    18091808        }
    18101809        catch(HRESULT aRC)
     
    18811880
    18821881    return VINF_SUCCESS;
     1882}
     1883
     1884/**
     1885 * Helper that converts VirtualSystem attachment values into VirtualBox attachment values.
     1886 * Throws HRESULT values on errors!
     1887 *
     1888 * @param hdc
     1889 * @param vd
     1890 * @param mhda
     1891 */
     1892void Appliance::ConvertDiskAttachmentValues(const HardDiskController &hdc,
     1893                                            uint32_t ulAddressOnParent,
     1894                                            Bstr &controllerType,
     1895                                            int32_t &lChannel,
     1896                                            int32_t &lDevice)
     1897{
     1898    switch (hdc.system)
     1899    {
     1900        case HardDiskController::IDE:
     1901            // For the IDE bus, the channel parameter can be either 0 or 1, to specify the primary
     1902            // or secondary IDE controller, respectively. For the primary controller of the IDE bus,
     1903            // the device number can be either 0 or 1, to specify the master or the slave device,
     1904            // respectively. For the secondary IDE controller, the device number is always 1 because
     1905            // the master device is reserved for the CD-ROM drive.
     1906            controllerType = Bstr("IDE Controller");
     1907            switch (ulAddressOnParent)
     1908            {
     1909                case 0:     // interpret this as primary master
     1910                    lChannel = (long)0;
     1911                    lDevice = (long)0;
     1912                break;
     1913
     1914                case 1:     // interpret this as primary slave
     1915                    lChannel = (long)0;
     1916                    lDevice = (long)1;
     1917                break;
     1918
     1919                case 2:     // interpret this as secondary master
     1920                    lChannel = (long)1;
     1921                    lDevice = (long)0;
     1922                break;
     1923
     1924                case 3:     // interpret this as secondary slave
     1925                    lChannel = (long)1;
     1926                    lDevice = (long)1;
     1927                break;
     1928
     1929                default:
     1930                    throw setError(VBOX_E_NOT_SUPPORTED,
     1931                                    tr("Invalid channel %RI16 specified; IDE controllers support only 0, 1 or 2"), ulAddressOnParent);
     1932                break;
     1933            }
     1934        break;
     1935
     1936        case HardDiskController::SATA:
     1937            controllerType = Bstr("SATA Controller");
     1938            lChannel = (long)ulAddressOnParent;
     1939            lDevice = (long)0;
     1940        break;
     1941
     1942        case HardDiskController::SCSI:
     1943            controllerType = Bstr("SCSI Controller");
     1944            lChannel = (long)ulAddressOnParent;
     1945            lDevice = (long)0;
     1946        break;
     1947
     1948        default: break;
     1949    }
    18831950}
    18841951
     
    35683635
    35693636            /* CD Drive */
    3570             /* @todo: I can't disable the CDROM. So nothing to do for now */
    3571             /*
    35723637            if (vsysThis.fHasCdromDrive)
    3573                 pNewDesc->addEntry(VirtualSystemDescriptionType_CDROM, "", "", "");*/
     3638                pNewDesc->addEntry(VirtualSystemDescriptionType_CDROM, "", "", "");
    35743639
    35753640            /* Hard disk Controller */
     
    43204385        uint32_t cCPUs;
    43214386        uint32_t ulMemSizeMB;
    4322         BOOL fDVDEnabled = FALSE;
    4323         BOOL fFloppyEnabled = FALSE;
    43244387        BOOL fUSBEnabled;
    43254388        BOOL fAudioEnabled;
     
    43484411        // snapshotFolder?
    43494412        // VRDPServer?
    4350 
    4351 /// @todo FIXME // @todo mediumbranch
    4352 #if 0
    4353         // floppy
    4354         rc = mFloppyDrive->COMGETTER(Enabled)(&fFloppyEnabled);
    4355         if (FAILED(rc)) throw rc;
    4356 
    4357         // CD-ROM ?!?
    4358         // ComPtr<IDVDDrive> pDVDDrive;
    4359         fDVDEnabled = 1;
    4360 #endif
    43614413
    43624414        // this is more tricky so use the COM method
     
    44834535
    44844536//     <const name="HardDiskImage" value="9" />
     4537//     <const name="Floppy" value="18" />
     4538//     <const name="CDROM" value="19" />
     4539
    44854540        MediaData::AttachmentList::iterator itA;
    44864541        for (itA = mMediaData->mAttachments.begin();
     
    45024557
    45034558            StorageBus_T storageBus;
     4559            DeviceType_T deviceType;
    45044560            LONG lChannel;
    45054561            LONG lDevice;
     
    45084564            if (FAILED(rc)) throw rc;
    45094565
     4566            rc = pHDA->COMGETTER(Type)(&deviceType);
     4567            if (FAILED(rc)) throw rc;
     4568
    45104569            rc = pHDA->COMGETTER(Medium)(pMedium.asOutParam());
    45114570            if (FAILED(rc)) throw rc;
     
    45174576            if (FAILED(rc)) throw rc;
    45184577
    4519             Bstr bstrLocation;
    4520             Bstr bstrName;
    4521             if (pMedium) // @todo mediumbranch only for hard disks
     4578            Utf8Str strTargetVmdkName;
     4579            Utf8Str strLocation;
     4580            ULONG64 ullSize = 0;
     4581
     4582            if (    deviceType == DeviceType_HardDisk
     4583                 && pMedium
     4584               )
    45224585            {
     4586                Bstr bstrLocation;
    45234587                rc = pMedium->COMGETTER(Location)(bstrLocation.asOutParam());
    45244588                if (FAILED(rc)) throw rc;
     4589                strLocation = bstrLocation;
     4590
     4591                Bstr bstrName;
    45254592                rc = pMedium->COMGETTER(Name)(bstrName.asOutParam());
    45264593                if (FAILED(rc)) throw rc;
    45274594
     4595                strTargetVmdkName = bstrName;
     4596                strTargetVmdkName.stripExt();
     4597                strTargetVmdkName.append(".vmdk");
     4598
     4599                // we need the size of the image so we can give it to addEntry();
     4600                // later, on export, the progress weight will be based on this.
     4601                // pMedium can be a differencing image though; in that case, we
     4602                // need to use the size of the base instead.
     4603                ComPtr<IMedium> pBaseMedium;
     4604                rc = pMedium->COMGETTER(Base)(pBaseMedium.asOutParam());
     4605                        // returns pMedium if there are no diff images
     4606                if (FAILED(rc)) throw rc;
     4607
    45284608                // force reading state, or else size will be returned as 0
    45294609                MediumState_T ms;
    4530                 rc = pMedium->RefreshState(&ms);
     4610                rc = pBaseMedium->RefreshState(&ms);
    45314611                if (FAILED(rc)) throw rc;
    45324612
    4533                 ULONG64 ullSize;
    4534                 rc = pMedium->COMGETTER(Size)(&ullSize);
     4613                rc = pBaseMedium->COMGETTER(Size)(&ullSize);
    45354614                if (FAILED(rc)) throw rc;
    4536 
    4537                 // and how this translates to the virtual system
    4538                 int32_t lControllerVsys = 0;
    4539                 LONG lChannelVsys;
    4540 
    4541                 switch (storageBus)
    4542                 {
    4543                     case StorageBus_IDE:
    4544                         // this is the exact reverse to what we're doing in Appliance::taskThreadImportMachines,
    4545                         // and it must be updated when that is changed!
    4546 
    4547                         if (lChannel == 0 && lDevice == 0)      // primary master
    4548                             lChannelVsys = 0;
    4549                         else if (lChannel == 0 && lDevice == 1) // primary slave
    4550                             lChannelVsys = 1;
    4551                         else if (lChannel == 1 && lDevice == 1) // secondary slave; secondary master is always CDROM
    4552                             lChannelVsys = 2;
    4553                         else
    4554                             throw setError(VBOX_E_NOT_SUPPORTED,
    4555                                         tr("Cannot handle hard disk attachment: channel is %d, device is %d"), lChannel, lDevice);
    4556 
    4557                         lControllerVsys = lIDEControllerIndex;
    4558                     break;
    4559 
    4560                     case StorageBus_SATA:
    4561                         lChannelVsys = lChannel;        // should be between 0 and 29
    4562                         lControllerVsys = lSATAControllerIndex;
    4563                     break;
    4564 
    4565                     case StorageBus_SCSI:
    4566                         lChannelVsys = lChannel;        // should be between 0 and 15
    4567                         lControllerVsys = lSCSIControllerIndex;
    4568                     break;
    4569 
    4570                     default:
     4615            }
     4616
     4617            // and how this translates to the virtual system
     4618            int32_t lControllerVsys = 0;
     4619            LONG lChannelVsys;
     4620
     4621            switch (storageBus)
     4622            {
     4623                case StorageBus_IDE:
     4624                    // this is the exact reverse to what we're doing in Appliance::taskThreadImportMachines,
     4625                    // and it must be updated when that is changed!
     4626
     4627                    if (lChannel == 0 && lDevice == 0)      // primary master
     4628                        lChannelVsys = 0;
     4629                    else if (lChannel == 0 && lDevice == 1) // primary slave
     4630                        lChannelVsys = 1;
     4631                    else if (lChannel == 1 && lDevice == 0) // secondary master; by default this is the CD-ROM but as of VirtualBox 3.1 that can change
     4632                        lChannelVsys = 2;
     4633                    else if (lChannel == 1 && lDevice == 1) // secondary slave
     4634                        lChannelVsys = 3;
     4635                    else
    45714636                        throw setError(VBOX_E_NOT_SUPPORTED,
    4572                                     tr("Cannot handle hard disk attachment: storageBus is %d, channel is %d, device is %d"), storageBus, lChannel, lDevice);
    4573                     break;
    4574                 }
    4575 
    4576                 Utf8Str strTargetVmdkName(bstrName);
    4577                 strTargetVmdkName.stripExt();
    4578                 strTargetVmdkName.append(".vmdk");
    4579 
    4580                 pNewDesc->addEntry(VirtualSystemDescriptionType_HardDiskImage,
    4581                                 strTargetVmdkName,   // disk ID: let's use the name
    4582                                 strTargetVmdkName,   // OVF value:
    4583                                 Utf8Str(bstrLocation), // vbox value: media path
    4584                                 (uint32_t)(ullSize / _1M),
    4585                                 Utf8StrFmt("controller=%RI32;channel=%RI32", lControllerVsys, lChannelVsys));
     4637                                    tr("Cannot handle medium attachment: channel is %d, device is %d"), lChannel, lDevice);
     4638
     4639                    lControllerVsys = lIDEControllerIndex;
     4640                break;
     4641
     4642                case StorageBus_SATA:
     4643                    lChannelVsys = lChannel;        // should be between 0 and 29
     4644                    lControllerVsys = lSATAControllerIndex;
     4645                break;
     4646
     4647                case StorageBus_SCSI:
     4648                    lChannelVsys = lChannel;        // should be between 0 and 15
     4649                    lControllerVsys = lSCSIControllerIndex;
     4650                break;
     4651
     4652                case StorageBus_Floppy:
     4653                    lChannelVsys = 0;
     4654                    lControllerVsys = 0;
     4655                break;
     4656
     4657                default:
     4658                    throw setError(VBOX_E_NOT_SUPPORTED,
     4659                                tr("Cannot handle medium attachment: storageBus is %d, channel is %d, device is %d"), storageBus, lChannel, lDevice);
     4660                break;
     4661            }
     4662
     4663            Utf8StrFmt strExtra("controller=%RI32;channel=%RI32", lControllerVsys, lChannelVsys);
     4664            Utf8Str strEmpty;
     4665
     4666            switch (deviceType)
     4667            {
     4668                case DeviceType_HardDisk:
     4669                    Log(("Adding VirtualSystemDescriptionType_HardDiskImage, disk size: %RI64\n", ullSize));
     4670                    pNewDesc->addEntry(VirtualSystemDescriptionType_HardDiskImage,
     4671                                       strTargetVmdkName,   // disk ID: let's use the name
     4672                                       strTargetVmdkName,   // OVF value:
     4673                                       strLocation, // vbox value: media path
     4674                                       (uint32_t)(ullSize / _1M),
     4675                                       strExtra);
     4676                break;
     4677
     4678                case DeviceType_DVD:
     4679                    pNewDesc->addEntry(VirtualSystemDescriptionType_CDROM,
     4680                                       strEmpty,   // disk ID
     4681                                       strEmpty,   // OVF value
     4682                                       strEmpty, // vbox value
     4683                                       1,           // ulSize
     4684                                       strExtra);
     4685                break;
     4686
     4687                case DeviceType_Floppy:
     4688                    pNewDesc->addEntry(VirtualSystemDescriptionType_Floppy,
     4689                                       strEmpty,      // disk ID
     4690                                       strEmpty,      // OVF value
     4691                                       strEmpty,      // vbox value
     4692                                       1,       // ulSize
     4693                                       strExtra);
     4694                break;
    45864695            }
    45874696        }
    4588 
    4589         /* Floppy Drive */
    4590         if (fFloppyEnabled)  // @todo mediumbranch
    4591             pNewDesc->addEntry(VirtualSystemDescriptionType_Floppy, "", "", "");
    4592 
    4593         /* CD Drive */
    4594         if (fDVDEnabled) // @todo mediumbranch
    4595             pNewDesc->addEntry(VirtualSystemDescriptionType_CDROM, "", "", "");
    45964697
    45974698//     <const name="NetworkAdapter" />
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r24511 r24526  
    35233523      </li>
    35243524      <li>
     3525         "CDROM": a virtual CD-ROM drive. The matching item in aExtraConfigValue[] contains the same
     3526         attachment information as with "HardDiskImage" items.
     3527      </li>
     3528      <li>
     3529        "CDROM": a virtual floppy drive. The matching item in aExtraConfigValue[] contains the same
     3530        attachment information as with "HardDiskImage" items.
     3531      </li>
     3532      <li>
    35253533        "NetworkAdapter": a network adapter. The array item in aVBoxValues[] will specify the hardware
    35263534        for the network adapter, whereas the array item in aExtraConfigValues[] will have a string
     
    58075815        <desc>
    58085816          Size of buffer allocated by caller. If the buffer is too small,
    5809           the method fails. 
     5817          the method fails.
    58105818        </desc>
    58115819      </param>
     
    58775885        <desc>
    58785886          Size of buffer allocated by caller. If the buffer is too small,
    5879           the method fails. 
     5887          the method fails.
    58805888        </desc>
    58815889      </param>
  • trunk/src/VBox/Main/include/ApplianceImpl.h

    r23223 r24526  
    2828#include "VirtualBoxBase.h"
    2929
     30#include "ovfreader.h"
     31
    3032/* VBox forward declarations */
    3133class VirtualBox;
     
    117119    int importS3(TaskImportOVF *pTask);
    118120
     121    void ConvertDiskAttachmentValues(const HardDiskController &hdc,
     122                                     uint32_t ulAddressOnParent,
     123                                     Bstr &controllerType,
     124                                     int32_t &lChannel,
     125                                     int32_t &lDevice);
     126
    119127    HRESULT writeImpl(int aFormat, const LocationInfo &aLocInfo, ComObjPtr<Progress> &aProgress);
    120128
Note: See TracChangeset for help on using the changeset viewer.

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