VBoxManageStorageController.cpp revision 0a90c7a0df11e88ee3ac85afb235d7acedbb0af7
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync * VBoxManage - The storage controller related commands.
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync * Copyright (C) 2006-2009 Sun Microsystems, Inc.
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync * available from http://www.virtualbox.org. This file is free software;
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync * you can redistribute it and/or modify it under the terms of the GNU
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync * General Public License (GPL) as published by the Free Software
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync * additional information or have any questions.
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync/*******************************************************************************
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync* Header Files *
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync*******************************************************************************/
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsyncusing namespace com;
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync///////////////////////////////////////////////////////////////////////////////
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsyncstatic const RTGETOPTDEF g_aStorageAttachOptions[] =
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync bool fRunTime = false;
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync return errorSyntax(USAGE_STORAGEATTACH, "Too few parameters");
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync return errorSyntax(USAGE_STORAGEATTACH, "Too many parameters");
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync RTGetOptInit (&GetState, a->argc, a->argv, g_aStorageAttachOptions,
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync RT_ELEMENTS(g_aStorageAttachOptions), 1, 0 /* fFlags */);
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync case 'm': // medium <none|emptydrive|uuid|filename|host:<drive>>
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync /* try to find the given machine */
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync CHECK_ERROR_RET (a->virtualBox, GetMachine (machineuuid, machine.asOutParam()), 1);
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync CHECK_ERROR_RET (a->virtualBox, FindMachine(Bstr(a->argv[0]), machine.asOutParam()), 1);
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync /* open a session for the VM */
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync rc = a->virtualBox->OpenSession(a->session, machineuuid);
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync /* try to open an existing session for the VM */
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync CHECK_ERROR_RET (a->virtualBox, OpenExistingSession (a->session, machineuuid), 1);
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync errorArgument("DVD/HardDisk Drives can't be changed while the VM is still running\n");
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync errorArgument("Drive passthrough state can't be changed while the VM is still running\n");
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync /* get the mutable session machine */
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync a->session->COMGETTER(Machine)(machine.asOutParam());
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync /* check if the storage controller is present */
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync rc = machine->GetStorageControllerByName(Bstr(pszCtl), storageCtl.asOutParam());
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync errorSyntax(USAGE_STORAGEATTACH, "Couldn't find the controller with the name: '%s'\n", pszCtl);
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync CHECK_ERROR (machine, DetachDevice(Bstr(pszCtl), port, device));
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync rc = machine->GetMediumAttachment(Bstr(pszCtl), port, device, mediumAttachment.asOutParam());
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync /* just unmount the floppy/dvd */
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync CHECK_ERROR (machine, MountMedium(Bstr(pszCtl), port, device, NULL));
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync errorArgument("No DVD/Floppy Drive attached to the controller '%s'"
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync "at the port: %u, device: %u", pszCtl, port, device);
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync CHECK_ERROR (storageCtl, COMGETTER(Bus)(&storageBus));
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync /* attach a empty floppy/dvd drive after removing previous attachment */
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync CHECK_ERROR (machine, AttachDevice(Bstr(pszCtl), port, device, deviceType, NULL));
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync errorSyntax(USAGE_STORAGEATTACH, "Argument --type not specified\n");
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync /* check if there is a dvd drive at the given location, if not attach one */
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync rc = machine->GetMediumAttachment(Bstr(pszCtl), port, device, mediumAttachement.asOutParam());
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync rc = machine->AttachDevice(Bstr(pszCtl), port, device, DeviceType_DVD, NULL);
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync rc = machine->AttachDevice(Bstr(pszCtl), port, device, DeviceType_DVD, NULL);
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync /* Attach/Detach the dvd medium now */
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync /* host drive? */
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync CHECK_ERROR (a->virtualBox, COMGETTER(Host)(host.asOutParam()));
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync rc = host->FindHostDVDDrive(Bstr(pszMedium + 5), dvdMedium.asOutParam());
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync /* 2nd try: try with the real name, important on Linux+libhal */
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync if (RT_FAILURE(RTPathReal(pszMedium + 5, szPathReal, sizeof(szPathReal))))
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync errorArgument("Invalid host DVD drive name \"%s\"", pszMedium + 5);
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync rc = host->FindHostDVDDrive(Bstr(szPathReal), dvdMedium.asOutParam());
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync errorArgument("Invalid host DVD drive name \"%s\"", pszMedium + 5);
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync /* first assume it's a UUID */
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync rc = a->virtualBox->GetDVDImage(uuid, dvdMedium.asOutParam());
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync /* must be a filename, check if it's in the collection */
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync rc = a->virtualBox->FindDVDImage(Bstr(pszMedium), dvdMedium.asOutParam());
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync /* not registered, do that on the fly */
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync CHECK_ERROR (a->virtualBox, OpenDVDImage(Bstr(pszMedium),
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync errorArgument("Invalid UUID or filename \"%s\"", pszMedium);
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync } while (0);
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync CHECK_ERROR (machine, MountMedium(Bstr(pszCtl), port, device, uuid));
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync /* if there is a dvd drive at the given location, remove it */
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync rc = machine->GetMediumAttachment(Bstr(pszCtl), port, device, mediumAttachement.asOutParam());
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync /* first guess is that it's a UUID */
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync rc = a->virtualBox->GetHardDisk(uuid, hardDisk.asOutParam());
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync /* not successful? Then it must be a filename */
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync rc = a->virtualBox->FindHardDisk(Bstr(pszMedium), hardDisk.asOutParam());
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync /* open the new hard disk object */
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync CHECK_ERROR (machine, AttachDevice(Bstr(pszCtl), port, device, DeviceType_HardDisk, uuid));
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync errorArgument("Invalid UUID or filename \"%s\"", pszMedium);
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync machine->GetMediumAttachment(Bstr(pszCtl), port, device, floppyAttachment.asOutParam());
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync CHECK_ERROR (machine, AttachDevice(Bstr(pszCtl), port, device, DeviceType_Floppy, NULL));
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync /* host drive? */
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync CHECK_ERROR (a->virtualBox, COMGETTER(Host)(host.asOutParam()));
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync rc = host->FindHostFloppyDrive(Bstr(pszMedium + 5), floppyMedium.asOutParam());
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync errorArgument("Invalid host floppy drive name \"%s\"", pszMedium + 5);
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync /* first assume it's a UUID */
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync rc = a->virtualBox->GetFloppyImage(uuid, floppyMedium.asOutParam());
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync /* must be a filename, check if it's in the collection */
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync rc = a->virtualBox->FindFloppyImage(Bstr(pszMedium), floppyMedium.asOutParam());
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync /* not registered, do that on the fly */
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync errorArgument("Invalid UUID or filename \"%s\"", pszMedium);
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync CHECK_ERROR (machine, MountMedium(Bstr(pszCtl), port, device, uuid));
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync errorArgument("Invalid --type argument '%s'", pszType);
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync CHECK_ERROR (machine, GetMediumAttachment(Bstr(pszCtl), port, device, mattach.asOutParam()));
0a90c7a0df11e88ee3ac85afb235d7acedbb0af7vboxsync CHECK_ERROR (machine, PassthroughDevice(Bstr(pszCtl), port, device, TRUE));
0a90c7a0df11e88ee3ac85afb235d7acedbb0af7vboxsync CHECK_ERROR (machine, PassthroughDevice(Bstr(pszCtl), port, device, FALSE));
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync errorArgument("Invalid --passthrough argument '%s'", pszPassThrough);
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync errorArgument("Couldn't find the controller attachment for the controller '%s'\n", pszCtl);
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync /* commit changes */
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync /* it's important to always close sessions */
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsyncstatic const RTGETOPTDEF g_aStorageControllerOptions[] =
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync { "--sataideemulation", 'e', RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_INDEX },
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync bool fRemoveCtl = false;
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync return errorSyntax(USAGE_STORAGECONTROLLER, "Too few parameters");
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync RTGetOptInit (&GetState, a->argc, a->argv, g_aStorageControllerOptions,
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync RT_ELEMENTS(g_aStorageControllerOptions), 1, 0 /* fFlags */);
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync case 'a': // controller bus type <ide/sata/scsi/floppy>
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync case 'c': // controller <lsilogic/buslogic/intelahci/piix3/piix4/ich6/i82078>
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync if ((GetState.uIndex < 1) && (GetState.uIndex > 4))
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync "Missing or Invalid SATA boot slot number in '%s'",
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync "Missing or Invalid SATA port number in '%s'",
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync errorGetOpt(USAGE_STORAGECONTROLLER, c, &ValueUnion);
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync /* try to find the given machine */
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync CHECK_ERROR_RET (a->virtualBox, GetMachine (machineuuid, machine.asOutParam()), 1);
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync CHECK_ERROR_RET (a->virtualBox, FindMachine(Bstr(a->argv[0]), machine.asOutParam()), 1);
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync /* open a session for the VM */
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync CHECK_ERROR_RET (a->virtualBox, OpenSession (a->session, machineuuid), 1);
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync /* get the mutable session machine */
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync a->session->COMGETTER(Machine)(machine.asOutParam());
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync /* it's important to always close sessions */
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync errorSyntax(USAGE_STORAGECONTROLLER, "Storage Controller Name not specified\n");
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync com::SafeIfaceArray<IMediumAttachment> mediumAttachments;
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync for (size_t i = 0; i < mediumAttachments.size(); ++ i)
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync ComPtr<IMediumAttachment> mediumAttach = mediumAttachments[i];
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync CHECK_ERROR (mediumAttach, COMGETTER(Port)(&port));
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync CHECK_ERROR (mediumAttach, COMGETTER(Device)(&device));
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync CHECK_ERROR (machine, DetachDevice(Bstr(pszCtl), port, device));
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync CHECK_ERROR (machine, RemoveStorageController(Bstr(pszCtl)));
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync errorArgument("Can't detach the devices connected to '%s' Controller\n"
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync CHECK_ERROR (machine, AddStorageController(Bstr(pszCtl), StorageBus_IDE, ctl.asOutParam()));
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync CHECK_ERROR (machine, AddStorageController(Bstr(pszCtl), StorageBus_SATA, ctl.asOutParam()));
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync CHECK_ERROR (machine, AddStorageController(Bstr(pszCtl), StorageBus_SCSI, ctl.asOutParam()));
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync CHECK_ERROR (machine, AddStorageController(Bstr(pszCtl), StorageBus_Floppy, ctl.asOutParam()));
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync errorArgument("Invalid --add argument '%s'", pszBusType);
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync CHECK_ERROR (machine, GetStorageControllerByName(Bstr(pszCtl), ctl.asOutParam()));
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync CHECK_ERROR (ctl, COMSETTER(ControllerType)(StorageControllerType_LsiLogic));
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync CHECK_ERROR (ctl, COMSETTER(ControllerType)(StorageControllerType_BusLogic));
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync CHECK_ERROR (ctl, COMSETTER(ControllerType)(StorageControllerType_IntelAhci));
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync CHECK_ERROR (ctl, COMSETTER(ControllerType)(StorageControllerType_PIIX3));
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync CHECK_ERROR (ctl, COMSETTER(ControllerType)(StorageControllerType_PIIX4));
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync CHECK_ERROR (ctl, COMSETTER(ControllerType)(StorageControllerType_ICH6));
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync CHECK_ERROR (ctl, COMSETTER(ControllerType)(StorageControllerType_I82078));
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync errorArgument("Invalid --type argument '%s'", pszCtlType);
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync errorArgument("Couldn't find the controller with the name: '%s'\n", pszCtl);
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync CHECK_ERROR (machine, GetStorageControllerByName(Bstr(pszCtl), ctl.asOutParam()));
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync CHECK_ERROR (ctl, COMSETTER(PortCount)(sataportcount));
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync errorArgument("Couldn't find the controller with the name: '%s'\n", pszCtl);
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync if ( (sataidedev != ~0U)
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync CHECK_ERROR (machine, GetStorageControllerByName(Bstr(pszCtl), ctl.asOutParam()));
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync CHECK_ERROR (ctl, SetIDEEmulationPort(satabootdev, sataidedev));
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync errorArgument("Couldn't find the controller with the name: '%s'\n", pszCtl);
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync /* commit changes */
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync /* it's important to always close sessions */
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync#endif /* !VBOX_ONLY_DOCS */