VBoxManageStorageController.cpp revision 96788c1af55ead9aaa2d17035c3777f2ea73023c
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync/* $Id$ */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync/** @file
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync * VBoxManage - The storage controller related commands.
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync/*
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync * Copyright (C) 2006-2009 Sun Microsystems, Inc.
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync *
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync * available from http://www.virtualbox.org. This file is free software;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync * you can redistribute it and/or modify it under the terms of the GNU
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync * General Public License (GPL) as published by the Free Software
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync *
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync * additional information or have any questions.
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync#ifndef VBOX_ONLY_DOCS
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync/*******************************************************************************
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync* Header Files *
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync*******************************************************************************/
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync#include <VBox/com/com.h>
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync#include <VBox/com/array.h>
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync#include <VBox/com/ErrorInfo.h>
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync#include <VBox/com/errorprint.h>
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync#include <VBox/com/VirtualBox.h>
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync#include <iprt/path.h>
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync#include <iprt/param.h>
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync#include <iprt/string.h>
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync#include <iprt/ctype.h>
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync#include <iprt/stream.h>
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync#include <iprt/getopt.h>
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync#include <VBox/log.h>
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync#include "VBoxManage.h"
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsyncusing namespace com;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync// funcs
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync///////////////////////////////////////////////////////////////////////////////
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsyncstatic const RTGETOPTDEF g_aStorageAttachOptions[] =
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync{
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync { "--storagectl", 's', RTGETOPT_REQ_STRING },
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync { "--port", 'p', RTGETOPT_REQ_UINT32 },
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync { "--device", 'd', RTGETOPT_REQ_UINT32 },
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync { "--medium", 'm', RTGETOPT_REQ_STRING },
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync { "--type", 't', RTGETOPT_REQ_STRING },
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync { "--passthrough", 'h', RTGETOPT_REQ_STRING },
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync};
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsyncint handleStorageAttach(HandlerArg *a)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync{
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync int c;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync HRESULT rc = S_OK;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync ULONG port = ~0U;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync ULONG device = ~0U;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync bool fRunTime = false;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync const char *pszCtl = NULL;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync const char *pszType = NULL;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync const char *pszMedium = NULL;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync const char *pszPassThrough = NULL;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync Bstr machineuuid (a->argv[0]);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync RTGETOPTUNION ValueUnion;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync RTGETOPTSTATE GetState;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync ComPtr<IMachine> machine;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync ComPtr<IStorageController> storageCtl;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync ComPtr<ISystemProperties> systemProperties;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (a->argc < 9)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync return errorSyntax(USAGE_STORAGEATTACH, "Too few parameters");
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else if (a->argc > 13)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync return errorSyntax(USAGE_STORAGEATTACH, "Too many parameters");
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync RTGetOptInit(&GetState, a->argc, a->argv, g_aStorageAttachOptions,
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync RT_ELEMENTS(g_aStorageAttachOptions), 1, 0 /* fFlags */);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync while ( SUCCEEDED(rc)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync && (c = RTGetOpt(&GetState, &ValueUnion)))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync switch (c)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync case 's': // storage controller name
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (ValueUnion.psz)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync pszCtl = ValueUnion.psz;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = E_FAIL;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync break;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync case 'p': // port
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync port = ValueUnion.u32;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync break;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync case 'd': // device
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync device = ValueUnion.u32;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync break;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync case 'm': // medium <none|emptydrive|uuid|filename|host:<drive>>
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (ValueUnion.psz)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync pszMedium = ValueUnion.psz;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = E_FAIL;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync break;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync case 't': // type <dvddrive|hdd|fdd>
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (ValueUnion.psz)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync pszType = ValueUnion.psz;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = E_FAIL;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync break;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync case 'h': // passthrough <on|off>
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (ValueUnion.psz)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync pszPassThrough = ValueUnion.psz;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = E_FAIL;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync break;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync default:
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync errorGetOpt(USAGE_STORAGEATTACH, c, &ValueUnion);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = E_FAIL;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync break;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if ( FAILED(rc)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync || !pszCtl
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync || port == ~0U
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync || device == ~0U)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync errorGetOpt(USAGE_STORAGEATTACH, c, &ValueUnion);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync return 1;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* get the virtualbox system properties */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR_RET(a->virtualBox, COMGETTER(SystemProperties)(systemProperties.asOutParam()), 1);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* try to find the given machine */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (!Guid(machineuuid).isEmpty())
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR_RET(a->virtualBox, GetMachine(machineuuid, machine.asOutParam()), 1);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR_RET(a->virtualBox, FindMachine(Bstr(a->argv[0]), machine.asOutParam()), 1);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync machine->COMGETTER(Id)(machineuuid.asOutParam());
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* open a session for the VM */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = a->virtualBox->OpenSession(a->session, machineuuid);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (FAILED(rc))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* try to open an existing session for the VM */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR_RET(a->virtualBox, OpenExistingSession(a->session, machineuuid), 1);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync fRunTime = true;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if ( fRunTime
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync && ( !RTStrICmp(pszMedium, "none")
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync || !RTStrICmp(pszType, "hdd")))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync errorArgument("DVD/HardDisk Drives can't be changed while the VM is still running\n");
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync goto leave;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (fRunTime && pszPassThrough)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync errorArgument("Drive passthrough state can't be changed while the VM is still running\n");
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync goto leave;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* get the mutable session machine */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync a->session->COMGETTER(Machine)(machine.asOutParam());
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* check if the storage controller is present */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = machine->GetStorageControllerByName(Bstr(pszCtl), storageCtl.asOutParam());
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (FAILED(rc))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync errorSyntax(USAGE_STORAGEATTACH, "Couldn't find the controller with the name: '%s'\n", pszCtl);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync goto leave;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* for sata controller check if the port count is big enough
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync * to accomodate the current port which is being assigned
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync * else just increase the port count
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync ULONG ulPortCount = 0;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync ULONG ulMaxPortCount = 0;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(storageCtl, COMGETTER(MaxPortCount)(&ulMaxPortCount));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(storageCtl, COMGETTER(PortCount)(&ulPortCount));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if ( (ulPortCount != ulMaxPortCount)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync && (port >= ulPortCount)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync && (port < ulMaxPortCount))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(storageCtl, COMSETTER(PortCount)(port + 1));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (!RTStrICmp(pszMedium, "none"))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(machine, DetachDevice(Bstr(pszCtl), port, device));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else if (!RTStrICmp(pszMedium, "emptydrive"))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (fRunTime)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync ComPtr<IMediumAttachment> mediumAttachment;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = machine->GetMediumAttachment(Bstr(pszCtl), port, device, mediumAttachment.asOutParam());
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (SUCCEEDED(rc))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync DeviceType_T deviceType;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync mediumAttachment->COMGETTER(Type)(&deviceType);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if ( (deviceType == DeviceType_DVD)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync || (deviceType == DeviceType_Floppy))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* just unmount the floppy/dvd */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(machine, MountMedium(Bstr(pszCtl), port, device, Bstr(""), FALSE /* aForce */));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync errorArgument("No DVD/Floppy Drive attached to the controller '%s'"
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync "at the port: %u, device: %u", pszCtl, port, device);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync goto leave;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync errorArgument("No DVD/Floppy Drive attached to the controller '%s'"
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync "at the port: %u, device: %u", pszCtl, port, device);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync goto leave;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync StorageBus_T storageBus = StorageBus_Null;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync DeviceType_T deviceType = DeviceType_Null;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync com::SafeArray <DeviceType_T> saDeviceTypes;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync ULONG driveCheck = 0;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* check if the device type is supported by the controller */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(storageCtl, COMGETTER(Bus)(&storageBus));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(systemProperties, GetDeviceTypesForStorageBus(storageBus, ComSafeArrayAsOutParam(saDeviceTypes)));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync for (size_t i = 0; i < saDeviceTypes.size(); ++ i)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if ( (saDeviceTypes[i] == DeviceType_DVD)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync || (saDeviceTypes[i] == DeviceType_Floppy))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync driveCheck++;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (!driveCheck)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync errorArgument("The Attachment is not supported by the Storage Controller: '%s'", pszCtl);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync goto leave;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (storageBus == StorageBus_Floppy)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync deviceType = DeviceType_Floppy;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync deviceType = DeviceType_DVD;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* attach a empty floppy/dvd drive after removing previous attachment */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync machine->DetachDevice(Bstr(pszCtl), port, device);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(machine, AttachDevice(Bstr(pszCtl), port, device, deviceType, Bstr("")));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /*
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync * try to determine the type of the drive from the
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync * storage controller chipset, the attachment and
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync * the medium being attached
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync StorageControllerType_T ctlType = StorageControllerType_Null;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(storageCtl, COMGETTER(ControllerType)(&ctlType));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (ctlType == StorageControllerType_I82078)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /*
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync * floppy controller found so lets assume the medium
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync * given by the user is also a floppy image or floppy
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync * host drive
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync pszType = "fdd";
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /*
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync * for SATA/SCSI/IDE it is hard to tell if it is a harddisk or
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync * a dvd being attached so lets check if the medium attachment
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync * and the medium, both are of same type. if yes then we are
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync * sure of its type and don't need the user to enter it manually
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync * else ask the user for the type.
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync ComPtr<IMediumAttachment> mediumAttachement;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = machine->GetMediumAttachment(Bstr(pszCtl), port, device, mediumAttachement.asOutParam());
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (SUCCEEDED(rc))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync DeviceType_T deviceType;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync mediumAttachement->COMGETTER(Type)(&deviceType);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (deviceType == DeviceType_DVD)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync Bstr uuid(pszMedium);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync ComPtr<IMedium> dvdMedium;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* first assume it's a UUID */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = a->virtualBox->GetDVDImage(uuid, dvdMedium.asOutParam());
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (FAILED(rc) || !dvdMedium)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* must be a filename, check if it's in the collection */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync a->virtualBox->FindDVDImage(Bstr(pszMedium), dvdMedium.asOutParam());
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (dvdMedium)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /*
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync * ok so the medium and attachment both are DVD's so it is
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync * safe to assume that we are dealing with a DVD here
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync pszType = "dvddrive";
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else if (deviceType == DeviceType_HardDisk)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync Bstr uuid(pszMedium);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync ComPtr<IMedium> hardDisk;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* first assume it's a UUID */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = a->virtualBox->GetHardDisk(uuid, hardDisk.asOutParam());
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (FAILED(rc) || !hardDisk)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* must be a filename, check if it's in the collection */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync a->virtualBox->FindHardDisk(Bstr(pszMedium), hardDisk.asOutParam());
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (hardDisk)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /*
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync * ok so the medium and attachment both are hdd's so it is
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync * safe to assume that we are dealing with a hdd here
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync pszType = "hdd";
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* for all other cases lets ask the user what type of drive it is */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (!pszType)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync errorSyntax(USAGE_STORAGEATTACH, "Argument --type not specified\n");
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync goto leave;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* check if the device type is supported by the controller */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync StorageBus_T storageBus = StorageBus_Null;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync com::SafeArray <DeviceType_T> saDeviceTypes;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(storageCtl, COMGETTER(Bus)(&storageBus));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(systemProperties, GetDeviceTypesForStorageBus(storageBus, ComSafeArrayAsOutParam(saDeviceTypes)));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (SUCCEEDED(rc))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync ULONG driveCheck = 0;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync for (size_t i = 0; i < saDeviceTypes.size(); ++ i)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if ( !RTStrICmp(pszType, "dvddrive")
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync && (saDeviceTypes[i] == DeviceType_DVD))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync driveCheck++;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if ( !RTStrICmp(pszType, "hdd")
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync && (saDeviceTypes[i] == DeviceType_HardDisk))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync driveCheck++;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if ( !RTStrICmp(pszType, "fdd")
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync && (saDeviceTypes[i] == DeviceType_Floppy))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync driveCheck++;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (!driveCheck)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync errorArgument("The Attachment is not supported by the Storage Controller: '%s'", pszCtl);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync goto leave;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync goto leave;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (!RTStrICmp(pszType, "dvddrive"))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync Bstr uuid;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync ComPtr<IMedium> dvdMedium;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (!fRunTime)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync ComPtr<IMediumAttachment> mediumAttachement;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* check if there is a dvd drive at the given location, if not attach one */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = machine->GetMediumAttachment(Bstr(pszCtl), port, device, mediumAttachement.asOutParam());
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (SUCCEEDED(rc))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync DeviceType_T deviceType;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync mediumAttachement->COMGETTER(Type)(&deviceType);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (deviceType != DeviceType_DVD)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync machine->DetachDevice(Bstr(pszCtl), port, device);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = machine->AttachDevice(Bstr(pszCtl), port, device, DeviceType_DVD, Bstr(""));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = machine->AttachDevice(Bstr(pszCtl), port, device, DeviceType_DVD, Bstr(""));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* Attach/Detach the dvd medium now */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync do
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* host drive? */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (!RTStrNICmp(pszMedium, "host:", 5))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync ComPtr<IHost> host;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(a->virtualBox, COMGETTER(Host)(host.asOutParam()));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = host->FindHostDVDDrive(Bstr(pszMedium + 5), dvdMedium.asOutParam());
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (!dvdMedium)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* 2nd try: try with the real name, important on Linux+libhal */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync char szPathReal[RTPATH_MAX];
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (RT_FAILURE(RTPathReal(pszMedium + 5, szPathReal, sizeof(szPathReal))))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync errorArgument("Invalid host DVD drive name \"%s\"", pszMedium + 5);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = E_FAIL;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync break;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = host->FindHostDVDDrive(Bstr(szPathReal), dvdMedium.asOutParam());
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (!dvdMedium)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync errorArgument("Invalid host DVD drive name \"%s\"", pszMedium + 5);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = E_FAIL;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync break;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* first assume it's a UUID */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync uuid = pszMedium;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = a->virtualBox->GetDVDImage(uuid, dvdMedium.asOutParam());
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (FAILED(rc) || !dvdMedium)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* must be a filename, check if it's in the collection */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = a->virtualBox->FindDVDImage(Bstr(pszMedium), dvdMedium.asOutParam());
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* not registered, do that on the fly */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (!dvdMedium)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync Bstr emptyUUID;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(a->virtualBox, OpenDVDImage(Bstr(pszMedium),
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync emptyUUID, dvdMedium.asOutParam()));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (!dvdMedium)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync errorArgument("Invalid UUID or filename \"%s\"", pszMedium);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = E_FAIL;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync break;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync } while (0);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (dvdMedium)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync dvdMedium->COMGETTER(Id)(uuid.asOutParam());
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(machine, MountMedium(Bstr(pszCtl), port, device, uuid, FALSE /* aForce */));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else if ( !RTStrICmp(pszType, "hdd")
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync && !fRunTime)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync ComPtr<IMediumAttachment> mediumAttachement;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* if there is anything attached at the given location, remove it */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync machine->DetachDevice(Bstr(pszCtl), port, device);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* first guess is that it's a UUID */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync Bstr uuid(pszMedium);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync ComPtr<IMedium> hardDisk;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = a->virtualBox->GetHardDisk(uuid, hardDisk.asOutParam());
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* not successful? Then it must be a filename */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (!hardDisk)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = a->virtualBox->FindHardDisk(Bstr(pszMedium), hardDisk.asOutParam());
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (FAILED(rc))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* open the new hard disk object */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(a->virtualBox,
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync OpenHardDisk(Bstr(pszMedium),
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync AccessMode_ReadWrite, false, Bstr(""),
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync false, Bstr(""), hardDisk.asOutParam()));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (hardDisk)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync hardDisk->COMGETTER(Id)(uuid.asOutParam());
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(machine, AttachDevice(Bstr(pszCtl), port, device, DeviceType_HardDisk, uuid));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync errorArgument("Invalid UUID or filename \"%s\"", pszMedium);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = E_FAIL;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else if (!RTStrICmp(pszType, "fdd"))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync Bstr uuid;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync ComPtr<IMedium> floppyMedium;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync ComPtr<IMediumAttachment> floppyAttachment;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync machine->GetMediumAttachment(Bstr(pszCtl), port, device, floppyAttachment.asOutParam());
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if ( !fRunTime
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync && !floppyAttachment)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(machine, AttachDevice(Bstr(pszCtl), port, device, DeviceType_Floppy, Bstr("")));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* host drive? */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (!RTStrNICmp(pszMedium, "host:", 5))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync ComPtr<IHost> host;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(a->virtualBox, COMGETTER(Host)(host.asOutParam()));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = host->FindHostFloppyDrive(Bstr(pszMedium + 5), floppyMedium.asOutParam());
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (!floppyMedium)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync errorArgument("Invalid host floppy drive name \"%s\"", pszMedium + 5);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = E_FAIL;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* first assume it's a UUID */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync uuid = pszMedium;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = a->virtualBox->GetFloppyImage(uuid, floppyMedium.asOutParam());
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (FAILED(rc) || !floppyMedium)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* must be a filename, check if it's in the collection */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = a->virtualBox->FindFloppyImage(Bstr(pszMedium), floppyMedium.asOutParam());
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* not registered, do that on the fly */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (!floppyMedium)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync Bstr emptyUUID;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(a->virtualBox,
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync OpenFloppyImage(Bstr(pszMedium),
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync emptyUUID,
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync floppyMedium.asOutParam()));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (!floppyMedium)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync errorArgument("Invalid UUID or filename \"%s\"", pszMedium);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = E_FAIL;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (floppyMedium)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync floppyMedium->COMGETTER(Id)(uuid.asOutParam());
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(machine, MountMedium(Bstr(pszCtl), port, device, uuid, FALSE /* aForce */));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync errorArgument("Invalid --type argument '%s'", pszType);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = E_FAIL;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if ( pszPassThrough
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync && (SUCCEEDED(rc)))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync ComPtr<IMediumAttachment> mattach;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(machine, GetMediumAttachment(Bstr(pszCtl), port, device, mattach.asOutParam()));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (SUCCEEDED(rc))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (!RTStrICmp(pszPassThrough, "on"))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(machine, PassthroughDevice(Bstr(pszCtl), port, device, TRUE));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else if (!RTStrICmp(pszPassThrough, "off"))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(machine, PassthroughDevice(Bstr(pszCtl), port, device, FALSE));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync errorArgument("Invalid --passthrough argument '%s'", pszPassThrough);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = E_FAIL;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync errorArgument("Couldn't find the controller attachment for the controller '%s'\n", pszCtl);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = E_FAIL;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* commit changes */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (SUCCEEDED(rc))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(machine, SaveSettings());
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsyncleave:
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* it's important to always close sessions */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync a->session->Close();
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync return SUCCEEDED(rc) ? 0 : 1;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync}
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsyncstatic const RTGETOPTDEF g_aStorageControllerOptions[] =
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync{
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync { "--name", 'n', RTGETOPT_REQ_STRING },
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync { "--add", 'a', RTGETOPT_REQ_STRING },
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync { "--controller", 'c', RTGETOPT_REQ_STRING },
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync { "--sataideemulation", 'e', RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_INDEX },
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync { "--sataportcount", 'p', RTGETOPT_REQ_UINT32 },
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync { "--remove", 'r', RTGETOPT_REQ_NOTHING },
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync};
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsyncint handleStorageController(HandlerArg *a)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync{
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync int c;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync HRESULT rc = S_OK;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync const char *pszCtl = NULL;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync const char *pszBusType = NULL;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync const char *pszCtlType = NULL;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync ULONG satabootdev = ~0U;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync ULONG sataidedev = ~0U;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync ULONG sataportcount = ~0U;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync bool fRemoveCtl = false;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync Bstr machineuuid (a->argv[0]);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync ComPtr<IMachine> machine;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync RTGETOPTUNION ValueUnion;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync RTGETOPTSTATE GetState;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (a->argc < 4)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync return errorSyntax(USAGE_STORAGECONTROLLER, "Too few parameters");
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync RTGetOptInit (&GetState, a->argc, a->argv, g_aStorageControllerOptions,
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync RT_ELEMENTS(g_aStorageControllerOptions), 1, 0 /* fFlags */);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync while ( SUCCEEDED(rc)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync && (c = RTGetOpt(&GetState, &ValueUnion)))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync switch (c)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync case 'n': // controller name
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (ValueUnion.psz)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync pszCtl = ValueUnion.psz;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = E_FAIL;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync break;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync case 'a': // controller bus type <ide/sata/scsi/floppy>
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (ValueUnion.psz)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync pszBusType = ValueUnion.psz;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = E_FAIL;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync break;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync case 'c': // controller <lsilogic/buslogic/intelahci/piix3/piix4/ich6/i82078>
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (ValueUnion.psz)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync pszCtlType = ValueUnion.psz;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = E_FAIL;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync break;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync case 'e': // sataideemulation
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if ((GetState.uIndex < 1) && (GetState.uIndex > 4))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync return errorSyntax(USAGE_STORAGECONTROLLER,
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync "Missing or Invalid SATA boot slot number in '%s'",
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync GetState.pDef->pszLong);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if ((ValueUnion.u32 < 1) && (ValueUnion.u32 > 30))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync return errorSyntax(USAGE_STORAGECONTROLLER,
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync "Missing or Invalid SATA port number in '%s'",
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync GetState.pDef->pszLong);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync satabootdev = GetState.uIndex;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync sataidedev = ValueUnion.u32;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync break;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync case 'p': // sataportcount
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync sataportcount = ValueUnion.u32;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync break;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync case 'r': // remove controller
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync fRemoveCtl = true;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync break;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync default:
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync errorGetOpt(USAGE_STORAGECONTROLLER, c, &ValueUnion);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = E_FAIL;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync break;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (FAILED(rc))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync return 1;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* try to find the given machine */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (!Guid(machineuuid).isEmpty())
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR_RET(a->virtualBox, GetMachine (machineuuid, machine.asOutParam()), 1);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR_RET(a->virtualBox, FindMachine(Bstr(a->argv[0]), machine.asOutParam()), 1);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync machine->COMGETTER(Id)(machineuuid.asOutParam());
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* open a session for the VM */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR_RET(a->virtualBox, OpenSession (a->session, machineuuid), 1);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* get the mutable session machine */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync a->session->COMGETTER(Machine)(machine.asOutParam());
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (!pszCtl)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync /* it's important to always close sessions */
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync a->session->Close();
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync errorSyntax(USAGE_STORAGECONTROLLER, "Storage Controller Name not specified\n");
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync return 1;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (fRemoveCtl)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync com::SafeIfaceArray<IMediumAttachment> mediumAttachments;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(machine,
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync GetMediumAttachmentsOfController(Bstr(pszCtl),
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync ComSafeArrayAsOutParam(mediumAttachments)));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync for (size_t i = 0; i < mediumAttachments.size(); ++ i)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync ComPtr<IMediumAttachment> mediumAttach = mediumAttachments[i];
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync LONG port = 0;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync LONG device = 0;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(mediumAttach, COMGETTER(Port)(&port));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(mediumAttach, COMGETTER(Device)(&device));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(machine, DetachDevice(Bstr(pszCtl), port, device));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (SUCCEEDED(rc))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(machine, RemoveStorageController(Bstr(pszCtl)));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync errorArgument("Can't detach the devices connected to '%s' Controller\n"
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync "and thus its removal failed.", pszCtl);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (pszBusType)
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync ComPtr<IStorageController> ctl;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (!RTStrICmp(pszBusType, "ide"))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(machine, AddStorageController(Bstr(pszCtl), StorageBus_IDE, ctl.asOutParam()));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else if (!RTStrICmp(pszBusType, "sata"))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(machine, AddStorageController(Bstr(pszCtl), StorageBus_SATA, ctl.asOutParam()));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else if (!RTStrICmp(pszBusType, "scsi"))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(machine, AddStorageController(Bstr(pszCtl), StorageBus_SCSI, ctl.asOutParam()));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else if (!RTStrICmp(pszBusType, "floppy"))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(machine, AddStorageController(Bstr(pszCtl), StorageBus_Floppy, ctl.asOutParam()));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync errorArgument("Invalid --add argument '%s'", pszBusType);
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync rc = E_FAIL;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if ( pszCtlType
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync && SUCCEEDED(rc))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync ComPtr<IStorageController> ctl;
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(machine, GetStorageControllerByName(Bstr(pszCtl), ctl.asOutParam()));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (SUCCEEDED(rc))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync if (!RTStrICmp(pszCtlType, "lsilogic"))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_LsiLogic));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else if (!RTStrICmp(pszCtlType, "buslogic"))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_BusLogic));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else if (!RTStrICmp(pszCtlType, "intelahci"))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_IntelAhci));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else if (!RTStrICmp(pszCtlType, "piix3"))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_PIIX3));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else if (!RTStrICmp(pszCtlType, "piix4"))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_PIIX4));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else if (!RTStrICmp(pszCtlType, "ich6"))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_ICH6));
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync }
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync else if (!RTStrICmp(pszCtlType, "i82078"))
7a0d67332f33bc21290d63bc7c8150b0cf0a4b21vboxsync {
CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_I82078));
}
else
{
errorArgument("Invalid --type argument '%s'", pszCtlType);
rc = E_FAIL;
}
}
else
{
errorArgument("Couldn't find the controller with the name: '%s'\n", pszCtl);
rc = E_FAIL;
}
}
if ( (sataportcount != ~0U)
&& SUCCEEDED(rc))
{
ComPtr<IStorageController> ctl;
CHECK_ERROR(machine, GetStorageControllerByName(Bstr(pszCtl), ctl.asOutParam()));
if (SUCCEEDED(rc))
{
CHECK_ERROR(ctl, COMSETTER(PortCount)(sataportcount));
}
else
{
errorArgument("Couldn't find the controller with the name: '%s'\n", pszCtl);
rc = E_FAIL;
}
}
if ( (sataidedev != ~0U)
&& (satabootdev != ~0U)
&& SUCCEEDED(rc))
{
ComPtr<IStorageController> ctl;
CHECK_ERROR(machine, GetStorageControllerByName(Bstr(pszCtl), ctl.asOutParam()));
if (SUCCEEDED(rc))
{
CHECK_ERROR(ctl, SetIDEEmulationPort(satabootdev, sataidedev));
}
else
{
errorArgument("Couldn't find the controller with the name: '%s'\n", pszCtl);
rc = E_FAIL;
}
}
}
/* commit changes */
if (SUCCEEDED(rc))
CHECK_ERROR(machine, SaveSettings());
/* it's important to always close sessions */
a->session->Close();
return SUCCEEDED(rc) ? 0 : 1;
}
#endif /* !VBOX_ONLY_DOCS */