From f215e02bf85f68d3a6106c2a1f4f7f063f819064 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 11 Apr 2024 10:17:27 +0200 Subject: Adding upstream version 7.0.14-dfsg. Signed-off-by: Daniel Baumann --- .../Frontends/VBoxManage/VBoxManageModifyVM.cpp | 3646 ++++++++++++++++++++ 1 file changed, 3646 insertions(+) create mode 100644 src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp (limited to 'src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp') diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp new file mode 100644 index 00000000..4a360725 --- /dev/null +++ b/src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp @@ -0,0 +1,3646 @@ +/* $Id: VBoxManageModifyVM.cpp $ */ +/** @file + * VBoxManage - Implementation of modifyvm command. + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * SPDX-License-Identifier: GPL-3.0-only + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "VBoxManage.h" +#include "VBoxManageUtils.h" + +DECLARE_TRANSLATION_CONTEXT(ModifyVM); + +using namespace com; +/** @todo refine this after HDD changes; MSC 8.0/64 has trouble with handleModifyVM. */ +#if defined(_MSC_VER) +# pragma optimize("g", off) +# if _MSC_VER < RT_MSC_VER_VC120 +# pragma warning(disable:4748) +# endif +#endif + +enum +{ + MODIFYVM_NAME = 1000, + MODIFYVM_GROUPS, + MODIFYVM_DESCRIPTION, + MODIFYVM_OSTYPE, + MODIFYVM_ICONFILE, + MODIFYVM_MEMORY, + MODIFYVM_PAGEFUSION, + MODIFYVM_VRAM, + MODIFYVM_FIRMWARE, + MODIFYVM_ACPI, + MODIFYVM_IOAPIC, + MODIFYVM_PAE, + MODIFYVM_LONGMODE, + MODIFYVM_CPUID_PORTABILITY, + MODIFYVM_TFRESET, + MODIFYVM_APIC, + MODIFYVM_X2APIC, + MODIFYVM_PARAVIRTPROVIDER, + MODIFYVM_PARAVIRTDEBUG, + MODIFYVM_HWVIRTEX, + MODIFYVM_NESTEDPAGING, + MODIFYVM_LARGEPAGES, + MODIFYVM_VTXVPID, + MODIFYVM_VTXUX, + MODIFYVM_VIRT_VMSAVE_VMLOAD, + MODIFYVM_IBPB_ON_VM_EXIT, + MODIFYVM_IBPB_ON_VM_ENTRY, + MODIFYVM_SPEC_CTRL, + MODIFYVM_L1D_FLUSH_ON_SCHED, + MODIFYVM_L1D_FLUSH_ON_VM_ENTRY, + MODIFYVM_MDS_CLEAR_ON_SCHED, + MODIFYVM_MDS_CLEAR_ON_VM_ENTRY, + MODIFYVM_NESTED_HW_VIRT, + MODIFYVM_CPUS, + MODIFYVM_CPUHOTPLUG, + MODIFYVM_CPU_PROFILE, + MODIFYVM_PLUGCPU, + MODIFYVM_UNPLUGCPU, + MODIFYVM_SETCPUID, + MODIFYVM_DELCPUID, + MODIFYVM_DELCPUID_OLD, // legacy, different syntax from MODIFYVM_DELCPUID + MODIFYVM_DELALLCPUID, + MODIFYVM_GRAPHICSCONTROLLER, + MODIFYVM_MONITORCOUNT, + MODIFYVM_ACCELERATE3D, +#ifdef VBOX_WITH_VIDEOHWACCEL + MODIFYVM_ACCELERATE2DVIDEO, +#endif + MODIFYVM_BIOSLOGOFADEIN, + MODIFYVM_BIOSLOGOFADEOUT, + MODIFYVM_BIOSLOGODISPLAYTIME, + MODIFYVM_BIOSLOGOIMAGEPATH, + MODIFYVM_BIOSBOOTMENU, + MODIFYVM_BIOSAPIC, + MODIFYVM_BIOSSYSTEMTIMEOFFSET, + MODIFYVM_BIOSPXEDEBUG, + MODIFYVM_SYSTEMUUIDLE, + MODIFYVM_BOOT, + MODIFYVM_HDA, // deprecated + MODIFYVM_HDB, // deprecated + MODIFYVM_HDD, // deprecated + MODIFYVM_IDECONTROLLER, // deprecated + MODIFYVM_SATAPORTCOUNT, // deprecated + MODIFYVM_SATAPORT, // deprecated + MODIFYVM_SATA, // deprecated + MODIFYVM_SCSIPORT, // deprecated + MODIFYVM_SCSITYPE, // deprecated + MODIFYVM_SCSI, // deprecated + MODIFYVM_DVDPASSTHROUGH, // deprecated + MODIFYVM_DVD, // deprecated + MODIFYVM_FLOPPY, // deprecated + MODIFYVM_NICTRACEFILE, + MODIFYVM_NICTRACE, + MODIFYVM_NICPROPERTY, + MODIFYVM_NICTYPE, + MODIFYVM_NICSPEED, + MODIFYVM_NICBOOTPRIO, + MODIFYVM_NICPROMISC, + MODIFYVM_NICBWGROUP, + MODIFYVM_NIC, + MODIFYVM_CABLECONNECTED, + MODIFYVM_BRIDGEADAPTER, +#ifdef VBOX_WITH_CLOUD_NET + MODIFYVM_CLOUDNET, +#endif /* VBOX_WITH_CLOUD_NET */ + MODIFYVM_HOSTONLYADAPTER, +#ifdef VBOX_WITH_VMNET + MODIFYVM_HOSTONLYNET, +#endif /* VBOX_WITH_VMNET */ + MODIFYVM_INTNET, + MODIFYVM_GENERICDRV, + MODIFYVM_NATNETWORKNAME, + MODIFYVM_NATNET, + MODIFYVM_NATBINDIP, + MODIFYVM_NATSETTINGS, + MODIFYVM_NATPF, + MODIFYVM_NATALIASMODE, + MODIFYVM_NATTFTPPREFIX, + MODIFYVM_NATTFTPFILE, + MODIFYVM_NATTFTPSERVER, + MODIFYVM_NATDNSPASSDOMAIN, + MODIFYVM_NATDNSPROXY, + MODIFYVM_NATDNSHOSTRESOLVER, + MODIFYVM_NATLOCALHOSTREACHABLE, + MODIFYVM_MACADDRESS, + MODIFYVM_HIDPTR, + MODIFYVM_HIDKBD, + MODIFYVM_UARTMODE, + MODIFYVM_UARTTYPE, + MODIFYVM_UART, +#if defined(RT_OS_LINUX) || defined(RT_OS_WINDOWS) + MODIFYVM_LPTMODE, + MODIFYVM_LPT, +#endif + MODIFYVM_GUESTMEMORYBALLOON, + MODIFYVM_AUDIOCONTROLLER, + MODIFYVM_AUDIOCODEC, + MODIFYVM_AUDIODRIVER, + MODIFYVM_AUDIOENABLED, + MODIFYVM_AUDIO, /* Deprecated; remove in the next major version. */ + MODIFYVM_AUDIOIN, + MODIFYVM_AUDIOOUT, +#ifdef VBOX_WITH_SHARED_CLIPBOARD + MODIFYVM_CLIPBOARD_MODE, +# ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS + MODIFYVM_CLIPBOARD_FILE_TRANSFERS, +# endif +#endif + MODIFYVM_DRAGANDDROP, + MODIFYVM_VRDPPORT, /* VRDE: deprecated */ + MODIFYVM_VRDPADDRESS, /* VRDE: deprecated */ + MODIFYVM_VRDPAUTHTYPE, /* VRDE: deprecated */ + MODIFYVM_VRDPMULTICON, /* VRDE: deprecated */ + MODIFYVM_VRDPREUSECON, /* VRDE: deprecated */ + MODIFYVM_VRDPVIDEOCHANNEL, /* VRDE: deprecated */ + MODIFYVM_VRDPVIDEOCHANNELQUALITY, /* VRDE: deprecated */ + MODIFYVM_VRDP, /* VRDE: deprecated */ + MODIFYVM_VRDEPROPERTY, + MODIFYVM_VRDEPORT, + MODIFYVM_VRDEADDRESS, + MODIFYVM_VRDEAUTHTYPE, + MODIFYVM_VRDEAUTHLIBRARY, + MODIFYVM_VRDEMULTICON, + MODIFYVM_VRDEREUSECON, + MODIFYVM_VRDEVIDEOCHANNEL, + MODIFYVM_VRDEVIDEOCHANNELQUALITY, + MODIFYVM_VRDE_EXTPACK, + MODIFYVM_VRDE, + MODIFYVM_RTCUSEUTC, + MODIFYVM_USBRENAME, + MODIFYVM_USBXHCI, + MODIFYVM_USBEHCI, + MODIFYVM_USBOHCI, + MODIFYVM_SNAPSHOTFOLDER, + MODIFYVM_TELEPORTER_ENABLED, + MODIFYVM_TELEPORTER_PORT, + MODIFYVM_TELEPORTER_ADDRESS, + MODIFYVM_TELEPORTER_PASSWORD, + MODIFYVM_TELEPORTER_PASSWORD_FILE, + MODIFYVM_TRACING_ENABLED, + MODIFYVM_TRACING_CONFIG, + MODIFYVM_TRACING_ALLOW_VM_ACCESS, + MODIFYVM_HARDWARE_UUID, + MODIFYVM_HPET, + MODIFYVM_IOCACHE, + MODIFYVM_IOCACHESIZE, + MODIFYVM_CPU_EXECTUION_CAP, + MODIFYVM_AUTOSTART_ENABLED, + MODIFYVM_AUTOSTART_DELAY, + MODIFYVM_AUTOSTOP_TYPE, +#ifdef VBOX_WITH_PCI_PASSTHROUGH + MODIFYVM_ATTACH_PCI, + MODIFYVM_DETACH_PCI, +#endif +#ifdef VBOX_WITH_USB_CARDREADER + MODIFYVM_USBCARDREADER, +#endif +#ifdef VBOX_WITH_RECORDING + MODIFYVM_RECORDING, + MODIFYVM_RECORDING_FEATURES, + MODIFYVM_RECORDING_SCREENS, + MODIFYVM_RECORDING_FILENAME, + MODIFYVM_RECORDING_VIDEO_WIDTH, + MODIFYVM_RECORDING_VIDEO_HEIGHT, + MODIFYVM_RECORDING_VIDEO_RES, + MODIFYVM_RECORDING_VIDEO_RATE, + MODIFYVM_RECORDING_VIDEO_FPS, + MODIFYVM_RECORDING_MAXTIME, + MODIFYVM_RECORDING_MAXSIZE, + MODIFYVM_RECORDING_OPTIONS, +#endif + MODIFYVM_CHIPSET, +#if defined(VBOX_WITH_IOMMU_AMD) || defined(VBOX_WITH_IOMMU_INTEL) + MODIFYVM_IOMMU, +#endif +#if defined(VBOX_WITH_TPM) + MODIFYVM_TPM_LOCATION, + MODIFYVM_TPM_TYPE, +#endif + MODIFYVM_DEFAULTFRONTEND, + MODIFYVM_VMPROC_PRIORITY, + MODIFYVM_TESTING_ENABLED, + MODIFYVM_TESTING_MMIO, + MODIFYVM_TESTING_CFG_DWORD, + MODIFYVM_GUEST_DEBUG_PROVIDER, + MODIFYVM_GUEST_DEBUG_IO_PROVIDER, + MODIFYVM_GUEST_DEBUG_ADDRESS, + MODIFYVM_GUEST_DEBUG_PORT, +}; + +static const RTGETOPTDEF g_aModifyVMOptions[] = +{ + OPT1("--name", MODIFYVM_NAME, RTGETOPT_REQ_STRING), + OPT1("--groups", MODIFYVM_GROUPS, RTGETOPT_REQ_STRING), + OPT1("--description", MODIFYVM_DESCRIPTION, RTGETOPT_REQ_STRING), + OPT2("--os-type", "--ostype", MODIFYVM_OSTYPE, RTGETOPT_REQ_STRING), + OPT2("--icon-file", "--iconfile", MODIFYVM_ICONFILE, RTGETOPT_REQ_STRING), + OPT1("--memory", MODIFYVM_MEMORY, RTGETOPT_REQ_UINT32), + OPT2("--page-fusion", "--pagefusion", MODIFYVM_PAGEFUSION, RTGETOPT_REQ_BOOL_ONOFF), + OPT1("--vram", MODIFYVM_VRAM, RTGETOPT_REQ_UINT32), + OPT1("--firmware", MODIFYVM_FIRMWARE, RTGETOPT_REQ_STRING), + OPT1("--acpi", MODIFYVM_ACPI, RTGETOPT_REQ_BOOL_ONOFF), + OPT1("--ioapic", MODIFYVM_IOAPIC, RTGETOPT_REQ_BOOL_ONOFF), + OPT1("--pae", MODIFYVM_PAE, RTGETOPT_REQ_BOOL_ONOFF), + OPT2("--long-mode", "--longmode", MODIFYVM_LONGMODE, RTGETOPT_REQ_BOOL_ONOFF), + OPT1("--cpuid-portability-level", MODIFYVM_CPUID_PORTABILITY, RTGETOPT_REQ_UINT32), + OPT2("--triple-fault-reset", "--triplefaultreset", MODIFYVM_TFRESET, RTGETOPT_REQ_BOOL_ONOFF), + OPT1("--apic", MODIFYVM_APIC, RTGETOPT_REQ_BOOL_ONOFF), + OPT1("--x2apic", MODIFYVM_X2APIC, RTGETOPT_REQ_BOOL_ONOFF), + OPT2("--paravirt-provider", "--paravirtprovider", MODIFYVM_PARAVIRTPROVIDER, RTGETOPT_REQ_STRING), + OPT2("--paravirt-debug", "--paravirtdebug", MODIFYVM_PARAVIRTDEBUG, RTGETOPT_REQ_STRING), + OPT1("--hwvirtex", MODIFYVM_HWVIRTEX, RTGETOPT_REQ_BOOL_ONOFF), + OPT2("--nested-paging", "--nestedpaging", MODIFYVM_NESTEDPAGING, RTGETOPT_REQ_BOOL_ONOFF), + OPT2("--large-pages", "--largepages", MODIFYVM_LARGEPAGES, RTGETOPT_REQ_BOOL_ONOFF), + OPT2("--vtx-vpid", "--vtxvpid", MODIFYVM_VTXVPID, RTGETOPT_REQ_BOOL_ONOFF), + OPT2("--vtx-ux", "--vtxux", MODIFYVM_VTXUX, RTGETOPT_REQ_BOOL_ONOFF), + OPT1("--virt-vmsave-vmload", MODIFYVM_VIRT_VMSAVE_VMLOAD, RTGETOPT_REQ_BOOL_ONOFF), + OPT1("--ibpb-on-vm-exit", MODIFYVM_IBPB_ON_VM_EXIT, RTGETOPT_REQ_BOOL_ONOFF), + OPT1("--ibpb-on-vm-entry", MODIFYVM_IBPB_ON_VM_ENTRY, RTGETOPT_REQ_BOOL_ONOFF), + OPT1("--spec-ctrl", MODIFYVM_SPEC_CTRL, RTGETOPT_REQ_BOOL_ONOFF), + OPT1("--l1d-flush-on-sched", MODIFYVM_L1D_FLUSH_ON_SCHED, RTGETOPT_REQ_BOOL_ONOFF), + OPT1("--l1d-flush-on-vm-entry", MODIFYVM_L1D_FLUSH_ON_VM_ENTRY, RTGETOPT_REQ_BOOL_ONOFF), + OPT1("--mds-clear-on-sched", MODIFYVM_MDS_CLEAR_ON_SCHED, RTGETOPT_REQ_BOOL_ONOFF), + OPT1("--mds-clear-on-vm-entry", MODIFYVM_MDS_CLEAR_ON_VM_ENTRY, RTGETOPT_REQ_BOOL_ONOFF), + OPT1("--nested-hw-virt", MODIFYVM_NESTED_HW_VIRT, RTGETOPT_REQ_BOOL_ONOFF), + OPT2("--cpuid-set", "--cpuidset", MODIFYVM_SETCPUID, RTGETOPT_REQ_UINT32_OPTIONAL_PAIR | RTGETOPT_FLAG_HEX), + OPT1("--cpuid-remove", MODIFYVM_DELCPUID, RTGETOPT_REQ_UINT32_OPTIONAL_PAIR | RTGETOPT_FLAG_HEX), + OPT1("--cpuidremove", MODIFYVM_DELCPUID_OLD, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_HEX), /* legacy - syntax differs */ + OPT2("--cpuid-remove-all", "--cpuidremoveall", MODIFYVM_DELALLCPUID, RTGETOPT_REQ_NOTHING), + OPT1("--cpus", MODIFYVM_CPUS, RTGETOPT_REQ_UINT32), + OPT2("--cpu-hotplug", "--cpuhotplug", MODIFYVM_CPUHOTPLUG, RTGETOPT_REQ_BOOL_ONOFF), + OPT1("--cpu-profile", MODIFYVM_CPU_PROFILE, RTGETOPT_REQ_STRING), + OPT2("--plug-cpu", "--plugcpu", MODIFYVM_PLUGCPU, RTGETOPT_REQ_UINT32), + OPT2("--unplug-cpu", "--unplugcpu", MODIFYVM_UNPLUGCPU, RTGETOPT_REQ_UINT32), + OPT2("--cpu-execution-cap", "--cpuexecutioncap", MODIFYVM_CPU_EXECTUION_CAP, RTGETOPT_REQ_UINT32), + OPT2("--rtc-use-utc", "--rtcuseutc", MODIFYVM_RTCUSEUTC, RTGETOPT_REQ_BOOL_ONOFF), + OPT2("--graphicscontroller", "--graphicscontroller", MODIFYVM_GRAPHICSCONTROLLER, RTGETOPT_REQ_STRING), + OPT2("--monitor-count", "--monitorcount", MODIFYVM_MONITORCOUNT, RTGETOPT_REQ_UINT32), + OPT2("--accelerate-3d", "--accelerate3d", MODIFYVM_ACCELERATE3D, RTGETOPT_REQ_BOOL_ONOFF), +#ifdef VBOX_WITH_VIDEOHWACCEL + OPT2("--accelerate-2d-video", "--accelerate2dvideo", MODIFYVM_ACCELERATE2DVIDEO, RTGETOPT_REQ_BOOL_ONOFF), +#endif + OPT2("--bios-logo-fade-in", "--bioslogofadein", MODIFYVM_BIOSLOGOFADEIN, RTGETOPT_REQ_BOOL_ONOFF), + OPT2("--bios-logo-fade-out", "--bioslogofadeout", MODIFYVM_BIOSLOGOFADEOUT, RTGETOPT_REQ_BOOL_ONOFF), + OPT2("--bios-logo-display-time", "--bioslogodisplaytime", MODIFYVM_BIOSLOGODISPLAYTIME, RTGETOPT_REQ_UINT32), + OPT2("--bios-logo-image-path", "--bioslogoimagepath", MODIFYVM_BIOSLOGOIMAGEPATH, RTGETOPT_REQ_STRING), + OPT2("--bios-boot-menu", "--biosbootmenu", MODIFYVM_BIOSBOOTMENU, RTGETOPT_REQ_STRING), + OPT2("--bios-system-time-offset", "--biossystemtimeoffset", MODIFYVM_BIOSSYSTEMTIMEOFFSET, RTGETOPT_REQ_INT64), + OPT2("--bios-apic", "--biosapic", MODIFYVM_BIOSAPIC, RTGETOPT_REQ_STRING), + OPT2("--bios-pxe-debug", "--biospxedebug", MODIFYVM_BIOSPXEDEBUG, RTGETOPT_REQ_BOOL_ONOFF), + OPT2("--system-uuid-le", "--system-uuid-le", MODIFYVM_SYSTEMUUIDLE, RTGETOPT_REQ_BOOL_ONOFF), + OPT1("--boot", MODIFYVM_BOOT, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX), + OPT1("--hda", MODIFYVM_HDA, RTGETOPT_REQ_STRING), /* deprecated */ + OPT1("--hdb", MODIFYVM_HDB, RTGETOPT_REQ_STRING), /* deprecated */ + OPT1("--hdd", MODIFYVM_HDD, RTGETOPT_REQ_STRING), /* deprecated */ + OPT2("--idec-ontroller", "--idecontroller", MODIFYVM_IDECONTROLLER, RTGETOPT_REQ_STRING), /* deprecated */ + OPT2("--sata-port-count", "--sataportcount", MODIFYVM_SATAPORTCOUNT, RTGETOPT_REQ_UINT32), /* deprecated */ + OPT2("--sata-port", "--sataport", MODIFYVM_SATAPORT, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX), /* deprecated */ + OPT1("--sata", MODIFYVM_SATA, RTGETOPT_REQ_STRING), /* deprecated */ + OPT2("--scsi-port", "--scsiport", MODIFYVM_SCSIPORT, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX), /* deprecated */ + OPT2("--scsi-type", "--scsitype", MODIFYVM_SCSITYPE, RTGETOPT_REQ_STRING), /* deprecated */ + OPT1("--scsi", MODIFYVM_SCSI, RTGETOPT_REQ_STRING), /* deprecated */ + OPT2("--dvd-pass-through", "--dvdpassthrough", MODIFYVM_DVDPASSTHROUGH, RTGETOPT_REQ_STRING), /* deprecated */ + OPT1("--dvd", MODIFYVM_DVD, RTGETOPT_REQ_STRING), /* deprecated */ + OPT1("--floppy", MODIFYVM_FLOPPY, RTGETOPT_REQ_STRING), /* deprecated */ + OPT2("--nic-trace-file", "--nictracefile", MODIFYVM_NICTRACEFILE, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX), + OPT2("--nic-trace", "--nictrace", MODIFYVM_NICTRACE, RTGETOPT_REQ_BOOL_ONOFF | RTGETOPT_FLAG_INDEX), + OPT2("--nic-property", "--nicproperty", MODIFYVM_NICPROPERTY, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX), + OPT2("--nic-type", "--nictype", MODIFYVM_NICTYPE, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX), + OPT2("--nic-speed", "--nicspeed", MODIFYVM_NICSPEED, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_INDEX), + OPT2("--nic-boot-prio", "--nicbootprio", MODIFYVM_NICBOOTPRIO, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_INDEX), + OPT2("--nic-promisc", "--nicpromisc", MODIFYVM_NICPROMISC, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX), + OPT2("--nic-bandwidth-group", "--nicbandwidthgroup", MODIFYVM_NICBWGROUP, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX), + OPT1("--nic", MODIFYVM_NIC, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX), + OPT2("--cable-connected", "--cableconnected", MODIFYVM_CABLECONNECTED, RTGETOPT_REQ_BOOL_ONOFF | RTGETOPT_FLAG_INDEX), + OPT2("--bridge-adapter", "--bridgeadapter", MODIFYVM_BRIDGEADAPTER, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX), +#ifdef VBOX_WITH_CLOUD_NET + OPT2("--cloud-network", "--cloudnetwork", MODIFYVM_CLOUDNET, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX), +#endif /* VBOX_WITH_CLOUD_NET */ + OPT2("--host-only-adapter", "--hostonlyadapter", MODIFYVM_HOSTONLYADAPTER, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX), +#ifdef VBOX_WITH_VMNET + OPT2("--host-only-net", "--hostonlynet", MODIFYVM_HOSTONLYNET, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX), +#endif + OPT1("--intnet", MODIFYVM_INTNET, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX), + OPT2("--nic-generic-drv", "--nicgenericdrv", MODIFYVM_GENERICDRV, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX), + OPT2("--nat-network", "--natnetwork", MODIFYVM_NATNETWORKNAME, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX), + OPT2("--nat-net", "--natnet", MODIFYVM_NATNET, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX), + OPT2("--nat-bind-ip", "--natbindip", MODIFYVM_NATBINDIP, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX), + OPT2("--nat-settings", "--natsettings", MODIFYVM_NATSETTINGS, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX), + OPT2("--nat-pf", "--natpf", MODIFYVM_NATPF, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX), + OPT2("--nat-alias-mode", "--nataliasmode", MODIFYVM_NATALIASMODE, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX), + OPT2("--nat-tftp-prefix", "--nattftpprefix", MODIFYVM_NATTFTPPREFIX, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX), + OPT2("--nat-tftp-file", "--nattftpfile", MODIFYVM_NATTFTPFILE, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX), + OPT2("--nat-tftp-server", "--nattftpserver", MODIFYVM_NATTFTPSERVER, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX), + OPT2("--nat-dns-pass-domain", "--natdnspassdomain", MODIFYVM_NATDNSPASSDOMAIN, RTGETOPT_REQ_BOOL_ONOFF | RTGETOPT_FLAG_INDEX), + OPT2("--nat-dns-proxy", "--natdnsproxy", MODIFYVM_NATDNSPROXY, RTGETOPT_REQ_BOOL_ONOFF | RTGETOPT_FLAG_INDEX), + OPT2("--nat-dns-host-resolver", "--natdnshostresolver", MODIFYVM_NATDNSHOSTRESOLVER, RTGETOPT_REQ_BOOL_ONOFF | RTGETOPT_FLAG_INDEX), + OPT2("--nat-localhostreachable", "--natlocalhostreachable", MODIFYVM_NATLOCALHOSTREACHABLE, RTGETOPT_REQ_BOOL_ONOFF | RTGETOPT_FLAG_INDEX), + OPT2("--mac-address", "--macaddress", MODIFYVM_MACADDRESS, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX), + OPT1("--mouse", MODIFYVM_HIDPTR, RTGETOPT_REQ_STRING), + OPT1("--keyboard", MODIFYVM_HIDKBD, RTGETOPT_REQ_STRING), + OPT2("--uart-mode", "--uartmode", MODIFYVM_UARTMODE, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX), + OPT2("--uart-type", "--uarttype", MODIFYVM_UARTTYPE, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX), + OPT1("--uart", MODIFYVM_UART, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX), +#if defined(RT_OS_LINUX) || defined(RT_OS_WINDOWS) + OPT2("--lpt-mode", "--lptmode", MODIFYVM_LPTMODE, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX), + OPT1("--lpt", MODIFYVM_LPT, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX), +#endif + OPT2("--guest-memory-balloon", "--guestmemoryballoon", MODIFYVM_GUESTMEMORYBALLOON, RTGETOPT_REQ_UINT32), + OPT2("--audio-controller", "--audiocontroller", MODIFYVM_AUDIOCONTROLLER, RTGETOPT_REQ_STRING), + OPT2("--audio-codec", "--audiocodec", MODIFYVM_AUDIOCODEC, RTGETOPT_REQ_STRING), + OPT1("--audio", MODIFYVM_AUDIO, RTGETOPT_REQ_STRING), + OPT2("--audio-driver", "--audiodriver", MODIFYVM_AUDIODRIVER, RTGETOPT_REQ_STRING), + OPT2("--audio-enabled", "--audioenabled", MODIFYVM_AUDIOENABLED, RTGETOPT_REQ_BOOL_ONOFF), + OPT2("--audio-in", "--audioin", MODIFYVM_AUDIOIN, RTGETOPT_REQ_BOOL_ONOFF), + OPT2("--audio-out", "--audioout", MODIFYVM_AUDIOOUT, RTGETOPT_REQ_BOOL_ONOFF), +#ifdef VBOX_WITH_SHARED_CLIPBOARD + OPT1("--clipboard-mode", MODIFYVM_CLIPBOARD_MODE, RTGETOPT_REQ_STRING), + OPT1("--clipboard", MODIFYVM_CLIPBOARD_MODE, RTGETOPT_REQ_STRING), /* deprecated */ +# ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS + OPT1("--clipboard-file-transfers", MODIFYVM_CLIPBOARD_FILE_TRANSFERS, RTGETOPT_REQ_STRING), +# endif +#endif + OPT2("--drag-and-drop", "--draganddrop", MODIFYVM_DRAGANDDROP, RTGETOPT_REQ_STRING), + OPT2("--vrdp-port", "--vrdpport", MODIFYVM_VRDPPORT, RTGETOPT_REQ_STRING), /* deprecated */ + OPT2("--vrdp-address", "--vrdpaddress", MODIFYVM_VRDPADDRESS, RTGETOPT_REQ_STRING), /* deprecated */ + OPT2("--vrdp-auth-type", "--vrdpauthtype", MODIFYVM_VRDPAUTHTYPE, RTGETOPT_REQ_STRING), /* deprecated */ + OPT2("--vrdp-multi-con", "--vrdpmulticon", MODIFYVM_VRDPMULTICON, RTGETOPT_REQ_BOOL_ONOFF), /* deprecated */ + OPT2("--vrdp-reuse-con", "--vrdpreusecon", MODIFYVM_VRDPREUSECON, RTGETOPT_REQ_BOOL_ONOFF), /* deprecated */ + OPT2("--vrdp-video-channel", "--vrdpvideochannel", MODIFYVM_VRDPVIDEOCHANNEL, RTGETOPT_REQ_BOOL_ONOFF), /* deprecated */ + OPT2("--vrdp-video-channel-quality", "--vrdpvideochannelquality",MODIFYVM_VRDPVIDEOCHANNELQUALITY, RTGETOPT_REQ_STRING), /* deprecated */ + OPT1("--vrdp", MODIFYVM_VRDP, RTGETOPT_REQ_BOOL_ONOFF), /* deprecated */ + OPT2("--vrde-property", "--vrdeproperty", MODIFYVM_VRDEPROPERTY, RTGETOPT_REQ_STRING), + OPT2("--vrde-port", "--vrdeport", MODIFYVM_VRDEPORT, RTGETOPT_REQ_STRING), + OPT2("--vrde-address", "--vrdeaddress", MODIFYVM_VRDEADDRESS, RTGETOPT_REQ_STRING), + OPT2("--vrde-auth-type", "--vrdeauthtype", MODIFYVM_VRDEAUTHTYPE, RTGETOPT_REQ_STRING), + OPT2("--vrde-auth-library", "--vrdeauthlibrary", MODIFYVM_VRDEAUTHLIBRARY, RTGETOPT_REQ_STRING), + OPT2("--vrde-multi-con", "--vrdemulticon", MODIFYVM_VRDEMULTICON, RTGETOPT_REQ_BOOL_ONOFF), + OPT2("--vrde-reuse-con", "--vrdereusecon", MODIFYVM_VRDEREUSECON, RTGETOPT_REQ_BOOL_ONOFF), + OPT2("--vrde-video-channel", "--vrdevideochannel", MODIFYVM_VRDEVIDEOCHANNEL, RTGETOPT_REQ_BOOL_ONOFF), + OPT2("--vrde-video-channel-quality", "--vrdevideochannelquality",MODIFYVM_VRDEVIDEOCHANNELQUALITY, RTGETOPT_REQ_STRING), + OPT2("--vrde-extpack", "--vrdeextpack", MODIFYVM_VRDE_EXTPACK, RTGETOPT_REQ_STRING), + OPT1("--vrde", MODIFYVM_VRDE, RTGETOPT_REQ_BOOL_ONOFF), + OPT2("--usb-rename", "--usbrename", MODIFYVM_USBRENAME, RTGETOPT_REQ_STRING), + OPT2("--usb-xhci", "--usbxhci", MODIFYVM_USBXHCI, RTGETOPT_REQ_BOOL_ONOFF), + OPT2("--usb-ehci", "--usbehci", MODIFYVM_USBEHCI, RTGETOPT_REQ_BOOL_ONOFF), + OPT2("--usb-ohci", "--usbohci", MODIFYVM_USBOHCI, RTGETOPT_REQ_BOOL_ONOFF), + OPT1("--usb", MODIFYVM_USBOHCI, RTGETOPT_REQ_BOOL_ONOFF), /* deprecated */ + OPT2("--snapshot-folder", "--snapshotfolder", MODIFYVM_SNAPSHOTFOLDER, RTGETOPT_REQ_STRING), + OPT1("--teleporter", MODIFYVM_TELEPORTER_ENABLED, RTGETOPT_REQ_BOOL_ONOFF), + OPT2("--teleporter-enabled", "--teleporterenabled", MODIFYVM_TELEPORTER_ENABLED, RTGETOPT_REQ_BOOL_ONOFF), /* deprecated */ + OPT2("--teleporter-port", "--teleporterport", MODIFYVM_TELEPORTER_PORT, RTGETOPT_REQ_UINT32), + OPT2("--teleporter-address", "--teleporteraddress", MODIFYVM_TELEPORTER_ADDRESS, RTGETOPT_REQ_STRING), + OPT2("--teleporter-password", "--teleporterpassword", MODIFYVM_TELEPORTER_PASSWORD, RTGETOPT_REQ_STRING), + OPT2("--teleporter-password-file", "--teleporterpasswordfile", MODIFYVM_TELEPORTER_PASSWORD_FILE, RTGETOPT_REQ_STRING), + OPT1("--tracing-enabled", MODIFYVM_TRACING_ENABLED, RTGETOPT_REQ_BOOL_ONOFF), + OPT1("--tracing-config", MODIFYVM_TRACING_CONFIG, RTGETOPT_REQ_STRING), + OPT1("--tracing-allow-vm-access", MODIFYVM_TRACING_ALLOW_VM_ACCESS, RTGETOPT_REQ_BOOL_ONOFF), + OPT2("--hardware-uuid", "--hardwareuuid", MODIFYVM_HARDWARE_UUID, RTGETOPT_REQ_STRING), + OPT1("--hpet", MODIFYVM_HPET, RTGETOPT_REQ_BOOL_ONOFF), + OPT1("--iocache", MODIFYVM_IOCACHE, RTGETOPT_REQ_BOOL_ONOFF), + OPT2("--iocache-size", "--iocachesize", MODIFYVM_IOCACHESIZE, RTGETOPT_REQ_UINT32), + OPT1("--chipset", MODIFYVM_CHIPSET, RTGETOPT_REQ_STRING), +#if defined(VBOX_WITH_IOMMU_AMD) || defined(VBOX_WITH_IOMMU_INTEL) + OPT1("--iommu", MODIFYVM_IOMMU, RTGETOPT_REQ_STRING), +#endif +#if defined(VBOX_WITH_TPM) + OPT1("--tpm-type", MODIFYVM_TPM_TYPE, RTGETOPT_REQ_STRING), + OPT1("--tpm-location", MODIFYVM_TPM_LOCATION, RTGETOPT_REQ_STRING), +#endif +#ifdef VBOX_WITH_RECORDING + OPT1("--recording", MODIFYVM_RECORDING, RTGETOPT_REQ_BOOL_ONOFF), + OPT2("--recording-screens", "--recordingscreens", MODIFYVM_RECORDING_SCREENS, RTGETOPT_REQ_STRING), + OPT2("--recording-file", "--recordingfile", MODIFYVM_RECORDING_FILENAME, RTGETOPT_REQ_STRING), + OPT2("--recording-max-time", "--recordingmaxtime", MODIFYVM_RECORDING_MAXTIME, RTGETOPT_REQ_INT32), + OPT2("--recording-max-size", "--recordingmaxsize", MODIFYVM_RECORDING_MAXSIZE, RTGETOPT_REQ_INT32), + OPT2("--recording-opts", "--recordingopts", MODIFYVM_RECORDING_OPTIONS, RTGETOPT_REQ_STRING), + OPT2("--recording-options", "--recordingoptions", MODIFYVM_RECORDING_OPTIONS, RTGETOPT_REQ_STRING), + OPT2("--recording-video-res", "--recordingvideores", MODIFYVM_RECORDING_VIDEO_RES, RTGETOPT_REQ_STRING), + OPT2("--recording-video-resolution", "--recordingvideoresolution",MODIFYVM_RECORDING_VIDEO_RES, RTGETOPT_REQ_STRING), + OPT2("--recording-video-rate", "--recordingvideorate", MODIFYVM_RECORDING_VIDEO_RATE, RTGETOPT_REQ_UINT32), + OPT2("--recording-video-fps", "--recordingvideofps", MODIFYVM_RECORDING_VIDEO_FPS, RTGETOPT_REQ_UINT32), +#endif + OPT1("--autostart-enabled", MODIFYVM_AUTOSTART_ENABLED, RTGETOPT_REQ_BOOL_ONOFF), + OPT1("--autostart-delay", MODIFYVM_AUTOSTART_DELAY, RTGETOPT_REQ_UINT32), + OPT1("--autostop-type", MODIFYVM_AUTOSTOP_TYPE, RTGETOPT_REQ_STRING), +#ifdef VBOX_WITH_PCI_PASSTHROUGH + OPT2("--pci-attach", "--pciattach", MODIFYVM_ATTACH_PCI, RTGETOPT_REQ_STRING), + OPT2("--pci-detach", "--pcidetach", MODIFYVM_DETACH_PCI, RTGETOPT_REQ_STRING), +#endif +#ifdef VBOX_WITH_USB_CARDREADER + OPT2("--usb-card-reader", "--usbcardreader", MODIFYVM_USBCARDREADER, RTGETOPT_REQ_BOOL_ONOFF), +#endif + OPT2("--default-frontend", "--defaultfrontend", MODIFYVM_DEFAULTFRONTEND, RTGETOPT_REQ_STRING), + OPT1("--vm-process-priority", MODIFYVM_VMPROC_PRIORITY, RTGETOPT_REQ_STRING), + OPT1("--testing-enabled", MODIFYVM_TESTING_ENABLED, RTGETOPT_REQ_BOOL_ONOFF), + OPT1("--testing-mmio", MODIFYVM_TESTING_MMIO, RTGETOPT_REQ_BOOL_ONOFF), + OPT1("--testing-cfg-dword", MODIFYVM_TESTING_CFG_DWORD, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_INDEX), + OPT1("--guest-debug-provider", MODIFYVM_GUEST_DEBUG_PROVIDER, RTGETOPT_REQ_STRING), + OPT1("--guest-debug-io-provider", MODIFYVM_GUEST_DEBUG_IO_PROVIDER, RTGETOPT_REQ_STRING), + OPT1("--guest-debug-address", MODIFYVM_GUEST_DEBUG_ADDRESS, RTGETOPT_REQ_STRING), + OPT1("--guest-debug-port", MODIFYVM_GUEST_DEBUG_PORT, RTGETOPT_REQ_UINT32), +}; + +static void vrdeWarningDeprecatedOption(const char *pszOption) +{ + RTStrmPrintf(g_pStdErr, ModifyVM::tr("Warning: '--vrdp%s' is deprecated. Use '--vrde%s'.\n"), pszOption, pszOption); +} + + +/** + * Wrapper around IMachine::SetExtraData that does the error reporting. + * + * @returns COM result code. + * @param rSessionMachine The IMachine. + * @param pszVariable The variable to set. + * @param pszValue The value to set. To delete pass empty string, not + * NULL. + */ +static HRESULT setExtraData(ComPtr &rSessionMachine, const char *pszVariable, const char *pszValue) +{ + HRESULT hrc = rSessionMachine->SetExtraData(Bstr(pszVariable).raw(), Bstr(pszValue).raw()); + if (FAILED(hrc)) + { + char *pszContext = RTStrAPrintf2("IMachine::SetExtraData('%s', '%s')", pszVariable, pszValue); + com::GlueHandleComError(rSessionMachine, pszContext, hrc, __FILE__, __LINE__); + RTStrFree(pszContext); + } + return hrc; +} + + +#ifdef VBOX_WITH_PCI_PASSTHROUGH +/** Parse PCI address in format 01:02.03 and convert it to the numeric representation. */ +static int32_t parsePci(const char* szPciAddr) +{ + uint8_t aVals[3] = {0, 0, 0}; + + char *pszNext; + int vrc = RTStrToUInt8Ex(pszNext, &pszNext, 16, &aVals[0]); + if (RT_FAILURE(vrc) || pszNext == NULL || *pszNext != ':') + return -1; + + vrc = RTStrToUInt8Ex(pszNext+1, &pszNext, 16, &aVals[1]); + if (RT_FAILURE(vrc) || pszNext == NULL || *pszNext != '.') + return -1; + + vrc = RTStrToUInt8Ex(pszNext+1, &pszNext, 16, &aVals[2]); + if (RT_FAILURE(vrc) || pszNext == NULL) + return -1; + + return (aVals[0] << 8) | (aVals[1] << 3) | (aVals[2] << 0); +} +#endif + +void parseGroups(const char *pcszGroups, com::SafeArray *pGroups) +{ + while (pcszGroups) + { + char *pComma = RTStrStr(pcszGroups, ","); + if (pComma) + { + Bstr(pcszGroups, pComma - pcszGroups).detachTo(pGroups->appendedRaw()); + pcszGroups = pComma + 1; + } + else + { + Bstr(pcszGroups).detachTo(pGroups->appendedRaw()); + pcszGroups = NULL; + } + } +} + +#ifdef VBOX_WITH_RECORDING +int parseScreens(const char *pcszScreens, com::SafeArray *pScreens) +{ + if (!RTStrICmp(pcszScreens, "all")) + { + for (uint32_t i = 0; i < pScreens->size(); i++) + (*pScreens)[i] = TRUE; + return VINF_SUCCESS; + } + if (!RTStrICmp(pcszScreens, "none")) + { + for (uint32_t i = 0; i < pScreens->size(); i++) + (*pScreens)[i] = FALSE; + return VINF_SUCCESS; + } + while (pcszScreens && *pcszScreens) + { + char *pszNext; + uint32_t iScreen; + int vrc = RTStrToUInt32Ex(pcszScreens, &pszNext, 0, &iScreen); + if (RT_FAILURE(vrc)) + return VERR_PARSE_ERROR; + if (iScreen >= pScreens->size()) + return VERR_PARSE_ERROR; + if (pszNext && *pszNext) + { + pszNext = RTStrStripL(pszNext); + if (*pszNext != ',') + return VERR_PARSE_ERROR; + pszNext++; + } + (*pScreens)[iScreen] = true; + pcszScreens = pszNext; + } + return VINF_SUCCESS; +} +#endif + +static int parseNum(uint32_t uIndex, unsigned cMaxIndex, const char *pszName) +{ + if ( uIndex >= 1 + && uIndex <= cMaxIndex) + return uIndex; + errorArgument(ModifyVM::tr("Invalid %s number %u"), pszName, uIndex); + return 0; +} + +VMProcPriority_T nameToVMProcPriority(const char *pszName) +{ + if (!RTStrICmp(pszName, "default")) + return VMProcPriority_Default; + if (!RTStrICmp(pszName, "flat")) + return VMProcPriority_Flat; + if (!RTStrICmp(pszName, "low")) + return VMProcPriority_Low; + if (!RTStrICmp(pszName, "normal")) + return VMProcPriority_Normal; + if (!RTStrICmp(pszName, "high")) + return VMProcPriority_High; + + return VMProcPriority_Invalid; +} + +RTEXITCODE handleModifyVM(HandlerArg *a) +{ + int c; + HRESULT hrc; + Bstr name; + + /* VM ID + at least one parameter. Parameter arguments are checked + * individually. */ + if (a->argc < 2) + return errorSyntax(ModifyVM::tr("Not enough parameters")); + + /* try to find the given sessionMachine */ + ComPtr machine; + CHECK_ERROR_RET(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(), + machine.asOutParam()), RTEXITCODE_FAILURE); + + + /* Get the number of network adapters */ + ULONG NetworkAdapterCount = getMaxNics(a->virtualBox, machine); + + /* open a session for the VM */ + CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Write), RTEXITCODE_FAILURE); + + /* get the mutable session sessionMachine */ + ComPtr sessionMachine; + CHECK_ERROR_RET(a->session, COMGETTER(Machine)(sessionMachine.asOutParam()), RTEXITCODE_FAILURE); + + ComPtr biosSettings; + sessionMachine->COMGETTER(BIOSSettings)(biosSettings.asOutParam()); + + ComPtr pGraphicsAdapter; + sessionMachine->COMGETTER(GraphicsAdapter)(pGraphicsAdapter.asOutParam()); + + RTGETOPTSTATE GetOptState; + RTGetOptInit(&GetOptState, a->argc, a->argv, g_aModifyVMOptions, + RT_ELEMENTS(g_aModifyVMOptions), 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS); + + RTGETOPTUNION ValueUnion; + while ( SUCCEEDED (hrc) + && (c = RTGetOpt(&GetOptState, &ValueUnion))) + { + switch (c) + { + case MODIFYVM_NAME: + { + CHECK_ERROR(sessionMachine, COMSETTER(Name)(Bstr(ValueUnion.psz).raw())); + break; + } + case MODIFYVM_GROUPS: + { + com::SafeArray groups; + parseGroups(ValueUnion.psz, &groups); + CHECK_ERROR(sessionMachine, COMSETTER(Groups)(ComSafeArrayAsInParam(groups))); + break; + } + case MODIFYVM_DESCRIPTION: + { + CHECK_ERROR(sessionMachine, COMSETTER(Description)(Bstr(ValueUnion.psz).raw())); + break; + } + case MODIFYVM_OSTYPE: + { + CHECK_ERROR(sessionMachine, COMSETTER(OSTypeId)(Bstr(ValueUnion.psz).raw())); + break; + } + + case MODIFYVM_ICONFILE: + { + RTFILE iconFile; + int vrc = RTFileOpen(&iconFile, ValueUnion.psz, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE); + if (RT_FAILURE(vrc)) + { + RTMsgError(ModifyVM::tr("Cannot open file \"%s\": %Rrc"), ValueUnion.psz, vrc); + hrc = E_FAIL; + break; + } + uint64_t cbSize; + vrc = RTFileQuerySize(iconFile, &cbSize); + if (RT_FAILURE(vrc)) + { + RTMsgError(ModifyVM::tr("Cannot get size of file \"%s\": %Rrc"), ValueUnion.psz, vrc); + hrc = E_FAIL; + break; + } + if (cbSize > _256K) + { + RTMsgError(ModifyVM::tr("File \"%s\" is bigger than 256KByte"), ValueUnion.psz); + hrc = E_FAIL; + break; + } + SafeArray icon((size_t)cbSize); + hrc = RTFileRead(iconFile, icon.raw(), (size_t)cbSize, NULL); + if (RT_FAILURE(vrc)) + { + RTMsgError(ModifyVM::tr("Cannot read contents of file \"%s\": %Rrc"), ValueUnion.psz, vrc); + hrc = E_FAIL; + break; + } + RTFileClose(iconFile); + CHECK_ERROR(sessionMachine, COMSETTER(Icon)(ComSafeArrayAsInParam(icon))); + break; + } + + case MODIFYVM_MEMORY: + { + CHECK_ERROR(sessionMachine, COMSETTER(MemorySize)(ValueUnion.u32)); + break; + } + + case MODIFYVM_PAGEFUSION: + { + CHECK_ERROR(sessionMachine, COMSETTER(PageFusionEnabled)(ValueUnion.f)); + break; + } + + case MODIFYVM_VRAM: + { + CHECK_ERROR(pGraphicsAdapter, COMSETTER(VRAMSize)(ValueUnion.u32)); + break; + } + + case MODIFYVM_FIRMWARE: + { + if (!RTStrICmp(ValueUnion.psz, "efi")) + { + CHECK_ERROR(sessionMachine, COMSETTER(FirmwareType)(FirmwareType_EFI)); + } + else if (!RTStrICmp(ValueUnion.psz, "efi32")) + { + CHECK_ERROR(sessionMachine, COMSETTER(FirmwareType)(FirmwareType_EFI32)); + } + else if (!RTStrICmp(ValueUnion.psz, "efi64")) + { + CHECK_ERROR(sessionMachine, COMSETTER(FirmwareType)(FirmwareType_EFI64)); + } + else if (!RTStrICmp(ValueUnion.psz, "efidual")) + { + CHECK_ERROR(sessionMachine, COMSETTER(FirmwareType)(FirmwareType_EFIDUAL)); + } + else if (!RTStrICmp(ValueUnion.psz, "bios")) + { + CHECK_ERROR(sessionMachine, COMSETTER(FirmwareType)(FirmwareType_BIOS)); + } + else + { + errorArgument(ModifyVM::tr("Invalid --firmware argument '%s'"), ValueUnion.psz); + hrc = E_FAIL; + } + break; + } + + case MODIFYVM_ACPI: + { + CHECK_ERROR(biosSettings, COMSETTER(ACPIEnabled)(ValueUnion.f)); + break; + } + + case MODIFYVM_IOAPIC: + { + CHECK_ERROR(biosSettings, COMSETTER(IOAPICEnabled)(ValueUnion.f)); + break; + } + + case MODIFYVM_PAE: + { + CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_PAE, ValueUnion.f)); + break; + } + + case MODIFYVM_LONGMODE: + { + CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_LongMode, ValueUnion.f)); + break; + } + + case MODIFYVM_CPUID_PORTABILITY: + { + CHECK_ERROR(sessionMachine, COMSETTER(CPUIDPortabilityLevel)(ValueUnion.u32)); + break; + } + + case MODIFYVM_TFRESET: + { + CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_TripleFaultReset, ValueUnion.f)); + break; + } + + case MODIFYVM_APIC: + { + CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_APIC, ValueUnion.f)); + break; + } + + case MODIFYVM_X2APIC: + { + CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_X2APIC, ValueUnion.f)); + break; + } + + case MODIFYVM_PARAVIRTPROVIDER: + { + if ( !RTStrICmp(ValueUnion.psz, "none") + || !RTStrICmp(ValueUnion.psz, "disabled")) + CHECK_ERROR(sessionMachine, COMSETTER(ParavirtProvider)(ParavirtProvider_None)); + else if (!RTStrICmp(ValueUnion.psz, "default")) + CHECK_ERROR(sessionMachine, COMSETTER(ParavirtProvider)(ParavirtProvider_Default)); + else if (!RTStrICmp(ValueUnion.psz, "legacy")) + CHECK_ERROR(sessionMachine, COMSETTER(ParavirtProvider)(ParavirtProvider_Legacy)); + else if (!RTStrICmp(ValueUnion.psz, "minimal")) + CHECK_ERROR(sessionMachine, COMSETTER(ParavirtProvider)(ParavirtProvider_Minimal)); + else if (!RTStrICmp(ValueUnion.psz, "hyperv")) + CHECK_ERROR(sessionMachine, COMSETTER(ParavirtProvider)(ParavirtProvider_HyperV)); + else if (!RTStrICmp(ValueUnion.psz, "kvm")) + CHECK_ERROR(sessionMachine, COMSETTER(ParavirtProvider)(ParavirtProvider_KVM)); + else + { + errorArgument(ModifyVM::tr("Invalid --paravirtprovider argument '%s'"), ValueUnion.psz); + hrc = E_FAIL; + } + break; + } + + case MODIFYVM_PARAVIRTDEBUG: + { + CHECK_ERROR(sessionMachine, COMSETTER(ParavirtDebug)(Bstr(ValueUnion.psz).raw())); + break; + } + + case MODIFYVM_HWVIRTEX: + { + CHECK_ERROR(sessionMachine, SetHWVirtExProperty(HWVirtExPropertyType_Enabled, ValueUnion.f)); + break; + } + + case MODIFYVM_SETCPUID: + { + uint32_t const idx = c == MODIFYVM_SETCPUID ? ValueUnion.PairU32.uFirst : ValueUnion.u32; + uint32_t const idxSub = c == MODIFYVM_SETCPUID ? ValueUnion.PairU32.uSecond : UINT32_MAX; + uint32_t aValue[4]; + for (unsigned i = 0; i < 4; i++) + { + int vrc = RTGetOptFetchValue(&GetOptState, &ValueUnion, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_HEX); + if (RT_FAILURE(vrc)) + return errorSyntax(ModifyVM::tr("Missing or invalid argument to '%s'"), + GetOptState.pDef->pszLong); + aValue[i] = ValueUnion.u32; + } + CHECK_ERROR(sessionMachine, SetCPUIDLeaf(idx, idxSub, aValue[0], aValue[1], aValue[2], aValue[3])); + break; + } + + case MODIFYVM_DELCPUID: + CHECK_ERROR(sessionMachine, RemoveCPUIDLeaf(ValueUnion.PairU32.uFirst, ValueUnion.PairU32.uSecond)); + break; + + case MODIFYVM_DELCPUID_OLD: + CHECK_ERROR(sessionMachine, RemoveCPUIDLeaf(ValueUnion.u32, UINT32_MAX)); + break; + + case MODIFYVM_DELALLCPUID: + { + CHECK_ERROR(sessionMachine, RemoveAllCPUIDLeaves()); + break; + } + + case MODIFYVM_NESTEDPAGING: + { + CHECK_ERROR(sessionMachine, SetHWVirtExProperty(HWVirtExPropertyType_NestedPaging, ValueUnion.f)); + break; + } + + case MODIFYVM_LARGEPAGES: + { + CHECK_ERROR(sessionMachine, SetHWVirtExProperty(HWVirtExPropertyType_LargePages, ValueUnion.f)); + break; + } + + case MODIFYVM_VTXVPID: + { + CHECK_ERROR(sessionMachine, SetHWVirtExProperty(HWVirtExPropertyType_VPID, ValueUnion.f)); + break; + } + + case MODIFYVM_VTXUX: + { + CHECK_ERROR(sessionMachine, SetHWVirtExProperty(HWVirtExPropertyType_UnrestrictedExecution, ValueUnion.f)); + break; + } + + case MODIFYVM_VIRT_VMSAVE_VMLOAD: + CHECK_ERROR(sessionMachine, SetHWVirtExProperty(HWVirtExPropertyType_VirtVmsaveVmload, ValueUnion.f)); + break; + + case MODIFYVM_IBPB_ON_VM_EXIT: + CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_IBPBOnVMExit, ValueUnion.f)); + break; + + case MODIFYVM_IBPB_ON_VM_ENTRY: + CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_IBPBOnVMEntry, ValueUnion.f)); + break; + + case MODIFYVM_SPEC_CTRL: + CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_SpecCtrl, ValueUnion.f)); + break; + + case MODIFYVM_L1D_FLUSH_ON_SCHED: + CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_L1DFlushOnEMTScheduling, ValueUnion.f)); + break; + + case MODIFYVM_L1D_FLUSH_ON_VM_ENTRY: + CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_L1DFlushOnVMEntry, ValueUnion.f)); + break; + + case MODIFYVM_MDS_CLEAR_ON_SCHED: + CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_MDSClearOnEMTScheduling, ValueUnion.f)); + break; + + case MODIFYVM_MDS_CLEAR_ON_VM_ENTRY: + CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_MDSClearOnVMEntry, ValueUnion.f)); + break; + + case MODIFYVM_NESTED_HW_VIRT: + CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_HWVirt, ValueUnion.f)); + break; + + case MODIFYVM_CPUS: + { + CHECK_ERROR(sessionMachine, COMSETTER(CPUCount)(ValueUnion.u32)); + break; + } + + case MODIFYVM_RTCUSEUTC: + { + CHECK_ERROR(sessionMachine, COMSETTER(RTCUseUTC)(ValueUnion.f)); + break; + } + + case MODIFYVM_CPUHOTPLUG: + { + CHECK_ERROR(sessionMachine, COMSETTER(CPUHotPlugEnabled)(ValueUnion.f)); + break; + } + + case MODIFYVM_CPU_PROFILE: + { + CHECK_ERROR(sessionMachine, COMSETTER(CPUProfile)(Bstr(ValueUnion.psz).raw())); + break; + } + + case MODIFYVM_PLUGCPU: + { + CHECK_ERROR(sessionMachine, HotPlugCPU(ValueUnion.u32)); + break; + } + + case MODIFYVM_UNPLUGCPU: + { + CHECK_ERROR(sessionMachine, HotUnplugCPU(ValueUnion.u32)); + break; + } + + case MODIFYVM_CPU_EXECTUION_CAP: + { + CHECK_ERROR(sessionMachine, COMSETTER(CPUExecutionCap)(ValueUnion.u32)); + break; + } + + case MODIFYVM_GRAPHICSCONTROLLER: + { + if ( !RTStrICmp(ValueUnion.psz, "none") + || !RTStrICmp(ValueUnion.psz, "disabled")) + CHECK_ERROR(pGraphicsAdapter, COMSETTER(GraphicsControllerType)(GraphicsControllerType_Null)); + else if ( !RTStrICmp(ValueUnion.psz, "vboxvga") + || !RTStrICmp(ValueUnion.psz, "vbox") + || !RTStrICmp(ValueUnion.psz, "vga") + || !RTStrICmp(ValueUnion.psz, "vesa")) + CHECK_ERROR(pGraphicsAdapter, COMSETTER(GraphicsControllerType)(GraphicsControllerType_VBoxVGA)); +#ifdef VBOX_WITH_VMSVGA + else if ( !RTStrICmp(ValueUnion.psz, "vmsvga") + || !RTStrICmp(ValueUnion.psz, "vmware")) + CHECK_ERROR(pGraphicsAdapter, COMSETTER(GraphicsControllerType)(GraphicsControllerType_VMSVGA)); + else if ( !RTStrICmp(ValueUnion.psz, "vboxsvga") + || !RTStrICmp(ValueUnion.psz, "svga")) + CHECK_ERROR(pGraphicsAdapter, COMSETTER(GraphicsControllerType)(GraphicsControllerType_VBoxSVGA)); +#endif + else + { + errorArgument(ModifyVM::tr("Invalid --graphicscontroller argument '%s'"), ValueUnion.psz); + hrc = E_FAIL; + } + break; + } + + case MODIFYVM_MONITORCOUNT: + { + CHECK_ERROR(pGraphicsAdapter, COMSETTER(MonitorCount)(ValueUnion.u32)); + break; + } + + case MODIFYVM_ACCELERATE3D: + { + CHECK_ERROR(pGraphicsAdapter, COMSETTER(Accelerate3DEnabled)(ValueUnion.f)); + break; + } + +#ifdef VBOX_WITH_VIDEOHWACCEL + case MODIFYVM_ACCELERATE2DVIDEO: + { + CHECK_ERROR(pGraphicsAdapter, COMSETTER(Accelerate2DVideoEnabled)(ValueUnion.f)); + break; + } +#endif + + case MODIFYVM_BIOSLOGOFADEIN: + { + CHECK_ERROR(biosSettings, COMSETTER(LogoFadeIn)(ValueUnion.f)); + break; + } + + case MODIFYVM_BIOSLOGOFADEOUT: + { + CHECK_ERROR(biosSettings, COMSETTER(LogoFadeOut)(ValueUnion.f)); + break; + } + + case MODIFYVM_BIOSLOGODISPLAYTIME: + { + CHECK_ERROR(biosSettings, COMSETTER(LogoDisplayTime)(ValueUnion.u32)); + break; + } + + case MODIFYVM_BIOSLOGOIMAGEPATH: + { + CHECK_ERROR(biosSettings, COMSETTER(LogoImagePath)(Bstr(ValueUnion.psz).raw())); + break; + } + + case MODIFYVM_BIOSBOOTMENU: + { + if (!RTStrICmp(ValueUnion.psz, "disabled")) + { + CHECK_ERROR(biosSettings, COMSETTER(BootMenuMode)(BIOSBootMenuMode_Disabled)); + } + else if (!RTStrICmp(ValueUnion.psz, "menuonly")) + { + CHECK_ERROR(biosSettings, COMSETTER(BootMenuMode)(BIOSBootMenuMode_MenuOnly)); + } + else if (!RTStrICmp(ValueUnion.psz, "messageandmenu")) + { + CHECK_ERROR(biosSettings, COMSETTER(BootMenuMode)(BIOSBootMenuMode_MessageAndMenu)); + } + else + { + errorArgument(ModifyVM::tr("Invalid --biosbootmenu argument '%s'"), ValueUnion.psz); + hrc = E_FAIL; + } + break; + } + + case MODIFYVM_BIOSAPIC: + { + if (!RTStrICmp(ValueUnion.psz, "disabled")) + { + CHECK_ERROR(biosSettings, COMSETTER(APICMode)(APICMode_Disabled)); + } + else if ( !RTStrICmp(ValueUnion.psz, "apic") + || !RTStrICmp(ValueUnion.psz, "lapic") + || !RTStrICmp(ValueUnion.psz, "xapic")) + { + CHECK_ERROR(biosSettings, COMSETTER(APICMode)(APICMode_APIC)); + } + else if (!RTStrICmp(ValueUnion.psz, "x2apic")) + { + CHECK_ERROR(biosSettings, COMSETTER(APICMode)(APICMode_X2APIC)); + } + else + { + errorArgument(ModifyVM::tr("Invalid --biosapic argument '%s'"), ValueUnion.psz); + hrc = E_FAIL; + } + break; + } + + case MODIFYVM_BIOSSYSTEMTIMEOFFSET: + { + CHECK_ERROR(biosSettings, COMSETTER(TimeOffset)(ValueUnion.i64)); + break; + } + + case MODIFYVM_BIOSPXEDEBUG: + { + CHECK_ERROR(biosSettings, COMSETTER(PXEDebugEnabled)(ValueUnion.f)); + break; + } + + case MODIFYVM_SYSTEMUUIDLE: + { + CHECK_ERROR(biosSettings, COMSETTER(SMBIOSUuidLittleEndian)(ValueUnion.f)); + break; + } + + case MODIFYVM_BOOT: + { + if (!RTStrICmp(ValueUnion.psz, "none")) + { + CHECK_ERROR(sessionMachine, SetBootOrder(GetOptState.uIndex, DeviceType_Null)); + } + else if (!RTStrICmp(ValueUnion.psz, "floppy")) + { + CHECK_ERROR(sessionMachine, SetBootOrder(GetOptState.uIndex, DeviceType_Floppy)); + } + else if (!RTStrICmp(ValueUnion.psz, "dvd")) + { + CHECK_ERROR(sessionMachine, SetBootOrder(GetOptState.uIndex, DeviceType_DVD)); + } + else if (!RTStrICmp(ValueUnion.psz, "disk")) + { + CHECK_ERROR(sessionMachine, SetBootOrder(GetOptState.uIndex, DeviceType_HardDisk)); + } + else if (!RTStrICmp(ValueUnion.psz, "net")) + { + CHECK_ERROR(sessionMachine, SetBootOrder(GetOptState.uIndex, DeviceType_Network)); + } + else + return errorArgument(ModifyVM::tr("Invalid boot device '%s'"), ValueUnion.psz); + break; + } + + case MODIFYVM_HDA: // deprecated + case MODIFYVM_HDB: // deprecated + case MODIFYVM_HDD: // deprecated + case MODIFYVM_SATAPORT: // deprecated + { + uint32_t u1 = 0, u2 = 0; + Bstr bstrController = L"IDE Controller"; + + switch (c) + { + case MODIFYVM_HDA: // deprecated + u1 = 0; + break; + + case MODIFYVM_HDB: // deprecated + u1 = 0; + u2 = 1; + break; + + case MODIFYVM_HDD: // deprecated + u1 = 1; + u2 = 1; + break; + + case MODIFYVM_SATAPORT: // deprecated + u1 = GetOptState.uIndex; + bstrController = L"SATA"; + break; + } + + if (!RTStrICmp(ValueUnion.psz, "none")) + { + sessionMachine->DetachDevice(bstrController.raw(), u1, u2); + } + else + { + ComPtr hardDisk; + hrc = openMedium(a, ValueUnion.psz, DeviceType_HardDisk, + AccessMode_ReadWrite, hardDisk, + false /* fForceNewUuidOnOpen */, + false /* fSilent */); + if (FAILED(hrc)) + break; + if (hardDisk) + { + CHECK_ERROR(sessionMachine, AttachDevice(bstrController.raw(), + u1, u2, + DeviceType_HardDisk, + hardDisk)); + } + else + hrc = E_FAIL; + } + break; + } + + case MODIFYVM_IDECONTROLLER: // deprecated + { + ComPtr storageController; + CHECK_ERROR(sessionMachine, GetStorageControllerByName(Bstr("IDE Controller").raw(), + storageController.asOutParam())); + + if (!RTStrICmp(ValueUnion.psz, "PIIX3")) + { + CHECK_ERROR(storageController, COMSETTER(ControllerType)(StorageControllerType_PIIX3)); + } + else if (!RTStrICmp(ValueUnion.psz, "PIIX4")) + { + CHECK_ERROR(storageController, COMSETTER(ControllerType)(StorageControllerType_PIIX4)); + } + else if (!RTStrICmp(ValueUnion.psz, "ICH6")) + { + CHECK_ERROR(storageController, COMSETTER(ControllerType)(StorageControllerType_ICH6)); + } + else + { + errorArgument(ModifyVM::tr("Invalid --idecontroller argument '%s'"), ValueUnion.psz); + hrc = E_FAIL; + } + break; + } + + case MODIFYVM_SATAPORTCOUNT: // deprecated + { + ComPtr SataCtl; + CHECK_ERROR(sessionMachine, GetStorageControllerByName(Bstr("SATA").raw(), + SataCtl.asOutParam())); + + if (SUCCEEDED(hrc) && ValueUnion.u32 > 0) + CHECK_ERROR(SataCtl, COMSETTER(PortCount)(ValueUnion.u32)); + break; + } + + case MODIFYVM_SATA: // deprecated + { + if (!RTStrICmp(ValueUnion.psz, "on") || !RTStrICmp(ValueUnion.psz, "enable")) + { + ComPtr ctl; + CHECK_ERROR(sessionMachine, AddStorageController(Bstr("SATA").raw(), + StorageBus_SATA, + ctl.asOutParam())); + CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_IntelAhci)); + } + else if (!RTStrICmp(ValueUnion.psz, "off") || !RTStrICmp(ValueUnion.psz, "disable")) + CHECK_ERROR(sessionMachine, RemoveStorageController(Bstr("SATA").raw())); + else + return errorArgument(ModifyVM::tr("Invalid --usb argument '%s'"), ValueUnion.psz); + break; + } + + case MODIFYVM_SCSIPORT: // deprecated + { + if (!RTStrICmp(ValueUnion.psz, "none")) + { + hrc = sessionMachine->DetachDevice(Bstr("LsiLogic").raw(), + GetOptState.uIndex, 0); + if (FAILED(hrc)) + CHECK_ERROR(sessionMachine, DetachDevice(Bstr("BusLogic").raw(), + GetOptState.uIndex, 0)); + } + else + { + ComPtr hardDisk; + hrc = openMedium(a, ValueUnion.psz, DeviceType_HardDisk, + AccessMode_ReadWrite, hardDisk, + false /* fForceNewUuidOnOpen */, + false /* fSilent */); + if (FAILED(hrc)) + break; + if (hardDisk) + { + hrc = sessionMachine->AttachDevice(Bstr("LsiLogic").raw(), + GetOptState.uIndex, 0, + DeviceType_HardDisk, + hardDisk); + if (FAILED(hrc)) + CHECK_ERROR(sessionMachine, + AttachDevice(Bstr("BusLogic").raw(), + GetOptState.uIndex, 0, + DeviceType_HardDisk, + hardDisk)); + } + else + hrc = E_FAIL; + } + break; + } + + case MODIFYVM_SCSITYPE: // deprecated + { + ComPtr ctl; + + if (!RTStrICmp(ValueUnion.psz, "LsiLogic")) + { + hrc = sessionMachine->RemoveStorageController(Bstr("BusLogic").raw()); + if (FAILED(hrc)) + CHECK_ERROR(sessionMachine, RemoveStorageController(Bstr("LsiLogic").raw())); + + CHECK_ERROR(sessionMachine, + AddStorageController(Bstr("LsiLogic").raw(), + StorageBus_SCSI, + ctl.asOutParam())); + + if (SUCCEEDED(hrc)) + CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_LsiLogic)); + } + else if (!RTStrICmp(ValueUnion.psz, "BusLogic")) + { + hrc = sessionMachine->RemoveStorageController(Bstr("LsiLogic").raw()); + if (FAILED(hrc)) + CHECK_ERROR(sessionMachine, RemoveStorageController(Bstr("BusLogic").raw())); + + CHECK_ERROR(sessionMachine, + AddStorageController(Bstr("BusLogic").raw(), + StorageBus_SCSI, + ctl.asOutParam())); + + if (SUCCEEDED(hrc)) + CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_BusLogic)); + } + else + return errorArgument(ModifyVM::tr("Invalid --scsitype argument '%s'"), ValueUnion.psz); + break; + } + + case MODIFYVM_SCSI: // deprecated + { + if (!RTStrICmp(ValueUnion.psz, "on") || !RTStrICmp(ValueUnion.psz, "enable")) + { + ComPtr ctl; + + CHECK_ERROR(sessionMachine, AddStorageController(Bstr("BusLogic").raw(), + StorageBus_SCSI, + ctl.asOutParam())); + if (SUCCEEDED(hrc)) + CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_BusLogic)); + } + else if (!RTStrICmp(ValueUnion.psz, "off") || !RTStrICmp(ValueUnion.psz, "disable")) + { + hrc = sessionMachine->RemoveStorageController(Bstr("BusLogic").raw()); + if (FAILED(hrc)) + CHECK_ERROR(sessionMachine, RemoveStorageController(Bstr("LsiLogic").raw())); + } + break; + } + + case MODIFYVM_DVDPASSTHROUGH: // deprecated + { + CHECK_ERROR(sessionMachine, PassthroughDevice(Bstr("IDE Controller").raw(), + 1, 0, + !RTStrICmp(ValueUnion.psz, "on"))); + break; + } + + case MODIFYVM_DVD: // deprecated + { + ComPtr dvdMedium; + + /* unmount? */ + if (!RTStrICmp(ValueUnion.psz, "none")) + { + /* nothing to do, NULL object will cause unmount */ + } + /* host drive? */ + else if (!RTStrNICmp(ValueUnion.psz, RT_STR_TUPLE("host:"))) + { + ComPtr host; + CHECK_ERROR(a->virtualBox, COMGETTER(Host)(host.asOutParam())); + hrc = host->FindHostDVDDrive(Bstr(ValueUnion.psz + 5).raw(), + dvdMedium.asOutParam()); + if (!dvdMedium) + { + /* 2nd try: try with the real name, important on Linux+libhal */ + char szPathReal[RTPATH_MAX]; + if (RT_FAILURE(RTPathReal(ValueUnion.psz + 5, szPathReal, sizeof(szPathReal)))) + { + errorArgument(ModifyVM::tr("Invalid host DVD drive name \"%s\""), ValueUnion.psz + 5); + hrc = E_FAIL; + break; + } + hrc = host->FindHostDVDDrive(Bstr(szPathReal).raw(), + dvdMedium.asOutParam()); + if (!dvdMedium) + { + errorArgument(ModifyVM::tr("Invalid host DVD drive name \"%s\""), ValueUnion.psz + 5); + hrc = E_FAIL; + break; + } + } + } + else + { + hrc = openMedium(a, ValueUnion.psz, DeviceType_DVD, + AccessMode_ReadOnly, dvdMedium, + false /* fForceNewUuidOnOpen */, + false /* fSilent */); + if (FAILED(hrc)) + break; + if (!dvdMedium) + { + hrc = E_FAIL; + break; + } + } + + CHECK_ERROR(sessionMachine, MountMedium(Bstr("IDE Controller").raw(), + 1, 0, + dvdMedium, + FALSE /* aForce */)); + break; + } + + case MODIFYVM_FLOPPY: // deprecated + { + ComPtr floppyMedium; + ComPtr floppyAttachment; + sessionMachine->GetMediumAttachment(Bstr("Floppy Controller").raw(), + 0, 0, floppyAttachment.asOutParam()); + + /* disable? */ + if (!RTStrICmp(ValueUnion.psz, "disabled")) + { + /* disable the controller */ + if (floppyAttachment) + CHECK_ERROR(sessionMachine, DetachDevice(Bstr("Floppy Controller").raw(), + 0, 0)); + } + else + { + /* enable the controller */ + if (!floppyAttachment) + CHECK_ERROR(sessionMachine, AttachDeviceWithoutMedium(Bstr("Floppy Controller").raw(), + 0, 0, + DeviceType_Floppy)); + + /* unmount? */ + if ( !RTStrICmp(ValueUnion.psz, "none") + || !RTStrICmp(ValueUnion.psz, "empty")) // deprecated + { + /* nothing to do, NULL object will cause unmount */ + } + /* host drive? */ + else if (!RTStrNICmp(ValueUnion.psz, RT_STR_TUPLE("host:"))) + { + ComPtr host; + CHECK_ERROR(a->virtualBox, COMGETTER(Host)(host.asOutParam())); + hrc = host->FindHostFloppyDrive(Bstr(ValueUnion.psz + 5).raw(), + floppyMedium.asOutParam()); + if (!floppyMedium) + { + errorArgument(ModifyVM::tr("Invalid host floppy drive name \"%s\""), ValueUnion.psz + 5); + hrc = E_FAIL; + break; + } + } + else + { + hrc = openMedium(a, ValueUnion.psz, DeviceType_Floppy, + AccessMode_ReadWrite, floppyMedium, + false /* fForceNewUuidOnOpen */, + false /* fSilent */); + if (FAILED(hrc)) + break; + if (!floppyMedium) + { + hrc = E_FAIL; + break; + } + } + CHECK_ERROR(sessionMachine, MountMedium(Bstr("Floppy Controller").raw(), + 0, 0, + floppyMedium, + FALSE /* aForce */)); + } + break; + } + + case MODIFYVM_NICTRACEFILE: + { + + if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC")) + break; + + ComPtr nic; + CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam())); + ASSERT(nic); + + CHECK_ERROR(nic, COMSETTER(TraceFile)(Bstr(ValueUnion.psz).raw())); + break; + } + + case MODIFYVM_NICTRACE: + { + if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC")) + break; + + ComPtr nic; + CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam())); + ASSERT(nic); + + CHECK_ERROR(nic, COMSETTER(TraceEnabled)(ValueUnion.f)); + break; + } + + case MODIFYVM_NICPROPERTY: + { + if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC")) + break; + + ComPtr nic; + CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam())); + ASSERT(nic); + + if (nic) + { + /* Parse 'name=value' */ + char *pszProperty = RTStrDup(ValueUnion.psz); + if (pszProperty) + { + char *pDelimiter = strchr(pszProperty, '='); + if (pDelimiter) + { + *pDelimiter = '\0'; + + Bstr bstrName = pszProperty; + Bstr bstrValue = &pDelimiter[1]; + CHECK_ERROR(nic, SetProperty(bstrName.raw(), bstrValue.raw())); + } + else + { + errorArgument(ModifyVM::tr("Invalid --nicproperty%d argument '%s'"), GetOptState.uIndex, ValueUnion.psz); + hrc = E_FAIL; + } + RTStrFree(pszProperty); + } + else + { + RTStrmPrintf(g_pStdErr, ModifyVM::tr("Error: Failed to allocate memory for --nicproperty%d '%s'\n"), + GetOptState.uIndex, ValueUnion.psz); + hrc = E_FAIL; + } + } + break; + } + case MODIFYVM_NICTYPE: + { + if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC")) + break; + + ComPtr nic; + CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam())); + ASSERT(nic); + + if (!RTStrICmp(ValueUnion.psz, "Am79C970A")) + { + CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_Am79C970A)); + } + else if (!RTStrICmp(ValueUnion.psz, "Am79C973")) + { + CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_Am79C973)); + } + else if (!RTStrICmp(ValueUnion.psz, "Am79C960")) + { + CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_Am79C960)); + } +#ifdef VBOX_WITH_E1000 + else if (!RTStrICmp(ValueUnion.psz, "82540EM")) + { + CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_I82540EM)); + } + else if (!RTStrICmp(ValueUnion.psz, "82543GC")) + { + CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_I82543GC)); + } + else if (!RTStrICmp(ValueUnion.psz, "82545EM")) + { + CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_I82545EM)); + } +#endif +#ifdef VBOX_WITH_VIRTIO + else if (!RTStrICmp(ValueUnion.psz, "virtio")) + { + CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_Virtio)); + } +#endif /* VBOX_WITH_VIRTIO */ + else if (!RTStrICmp(ValueUnion.psz, "NE1000")) + { + CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_NE1000)); + } + else if (!RTStrICmp(ValueUnion.psz, "NE2000")) + { + CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_NE2000)); + } + else if (!RTStrICmp(ValueUnion.psz, "WD8003")) + { + CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_WD8003)); + } + else if (!RTStrICmp(ValueUnion.psz, "WD8013")) + { + CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_WD8013)); + } + else if (!RTStrICmp(ValueUnion.psz, "3C503")) + { + CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_ELNK2)); + } + else if (!RTStrICmp(ValueUnion.psz, "3C501")) + { + CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_ELNK1)); + } + else + { + errorArgument(ModifyVM::tr("Invalid NIC type '%s' specified for NIC %u"), + ValueUnion.psz, GetOptState.uIndex); + hrc = E_FAIL; + } + break; + } + + case MODIFYVM_NICSPEED: + { + if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC")) + break; + + ComPtr nic; + CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam())); + ASSERT(nic); + + CHECK_ERROR(nic, COMSETTER(LineSpeed)(ValueUnion.u32)); + break; + } + + case MODIFYVM_NICBOOTPRIO: + { + if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC")) + break; + + ComPtr nic; + CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam())); + ASSERT(nic); + + /* Somewhat arbitrary limitation - we can pass a list of up to 4 PCI devices + * to the PXE ROM, hence only boot priorities 1-4 are allowed (in addition to + * 0 for the default lowest priority). + */ + if (ValueUnion.u32 > 4) + { + errorArgument(ModifyVM::tr("Invalid boot priority '%u' specfied for NIC %u"), ValueUnion.u32, GetOptState.uIndex); + hrc = E_FAIL; + } + else + { + CHECK_ERROR(nic, COMSETTER(BootPriority)(ValueUnion.u32)); + } + break; + } + + case MODIFYVM_NICPROMISC: + { + NetworkAdapterPromiscModePolicy_T enmPromiscModePolicy; + if (!RTStrICmp(ValueUnion.psz, "deny")) + enmPromiscModePolicy = NetworkAdapterPromiscModePolicy_Deny; + else if ( !RTStrICmp(ValueUnion.psz, "allow-vms") + || !RTStrICmp(ValueUnion.psz, "allow-network")) + enmPromiscModePolicy = NetworkAdapterPromiscModePolicy_AllowNetwork; + else if (!RTStrICmp(ValueUnion.psz, "allow-all")) + enmPromiscModePolicy = NetworkAdapterPromiscModePolicy_AllowAll; + else + { + errorArgument(ModifyVM::tr("Unknown promiscuous mode policy '%s'"), ValueUnion.psz); + hrc = E_INVALIDARG; + break; + } + + if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC")) + break; + + ComPtr nic; + CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam())); + ASSERT(nic); + + CHECK_ERROR(nic, COMSETTER(PromiscModePolicy)(enmPromiscModePolicy)); + break; + } + + case MODIFYVM_NICBWGROUP: + { + if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC")) + break; + + ComPtr nic; + CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam())); + ASSERT(nic); + + if (!RTStrICmp(ValueUnion.psz, "none")) + { + /* Just remove the bandwidth group. */ + CHECK_ERROR(nic, COMSETTER(BandwidthGroup)(NULL)); + } + else + { + ComPtr bwCtrl; + ComPtr bwGroup; + + CHECK_ERROR(sessionMachine, COMGETTER(BandwidthControl)(bwCtrl.asOutParam())); + + if (SUCCEEDED(hrc)) + { + CHECK_ERROR(bwCtrl, GetBandwidthGroup(Bstr(ValueUnion.psz).raw(), bwGroup.asOutParam())); + if (SUCCEEDED(hrc)) + { + CHECK_ERROR(nic, COMSETTER(BandwidthGroup)(bwGroup)); + } + } + } + break; + } + + case MODIFYVM_NIC: + { + if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC")) + break; + + ComPtr nic; + CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam())); + ASSERT(nic); + + /* + * Check if the NIC is already enabled. Do not try to + * enable it if it already is. That makes a + * difference for saved VMs for which you can change + * the NIC attachment, but can't change the NIC + * enabled status (yes, the setter also should not + * freak out about a no-op request). + */ + BOOL fEnabled;; + CHECK_ERROR(nic, COMGETTER(Enabled)(&fEnabled)); + + if (!RTStrICmp(ValueUnion.psz, "none")) + { + if (RT_BOOL(fEnabled)) + CHECK_ERROR(nic, COMSETTER(Enabled)(FALSE)); + } + else if (!RTStrICmp(ValueUnion.psz, "null")) + { + if (!fEnabled) + CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE)); + CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_Null)); + } + else if (!RTStrICmp(ValueUnion.psz, "nat")) + { + if (!fEnabled) + CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE)); + CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_NAT)); + } + else if ( !RTStrICmp(ValueUnion.psz, "bridged") + || !RTStrICmp(ValueUnion.psz, "hostif")) /* backward compatibility */ + { + if (!fEnabled) + CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE)); + CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_Bridged)); + } + else if (!RTStrICmp(ValueUnion.psz, "intnet")) + { + if (!fEnabled) + CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE)); + CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_Internal)); + } + else if (!RTStrICmp(ValueUnion.psz, "hostonly")) + { + if (!fEnabled) + CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE)); + CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_HostOnly)); + } +#ifdef VBOX_WITH_VMNET + else if (!RTStrICmp(ValueUnion.psz, "hostonlynet")) + { + if (!fEnabled) + CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE)); + CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_HostOnlyNetwork)); + } +#endif /* VBOX_WITH_VMNET */ + else if (!RTStrICmp(ValueUnion.psz, "generic")) + { + if (!fEnabled) + CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE)); + CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_Generic)); + } + else if (!RTStrICmp(ValueUnion.psz, "natnetwork")) + { + if (!fEnabled) + CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE)); + CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_NATNetwork)); + } +#ifdef VBOX_WITH_CLOUD_NET + else if (!RTStrICmp(ValueUnion.psz, "cloud")) + { + if (!fEnabled) + CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE)); + CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_Cloud)); + } +#endif /* VBOX_WITH_CLOUD_NET */ + else + { + errorArgument(ModifyVM::tr("Invalid type '%s' specfied for NIC %u"), ValueUnion.psz, GetOptState.uIndex); + hrc = E_FAIL; + } + break; + } + + case MODIFYVM_CABLECONNECTED: + { + if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC")) + break; + + ComPtr nic; + CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam())); + ASSERT(nic); + + CHECK_ERROR(nic, COMSETTER(CableConnected)(ValueUnion.f)); + break; + } + + case MODIFYVM_BRIDGEADAPTER: + { + if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC")) + break; + + ComPtr nic; + CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam())); + ASSERT(nic); + + /* remove it? */ + if (!RTStrICmp(ValueUnion.psz, "none")) + { + CHECK_ERROR(nic, COMSETTER(BridgedInterface)(Bstr().raw())); + } + else + { + CHECK_ERROR(nic, COMSETTER(BridgedInterface)(Bstr(ValueUnion.psz).raw())); + verifyHostNetworkInterfaceName(a->virtualBox, ValueUnion.psz, + HostNetworkInterfaceType_Bridged); + } + break; + } + +#ifdef VBOX_WITH_CLOUD_NET + case MODIFYVM_CLOUDNET: + { + if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC")) + break; + + ComPtr nic; + CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam())); + ASSERT(nic); + + /* remove it? */ + if (!RTStrICmp(ValueUnion.psz, "none")) + { + CHECK_ERROR(nic, COMSETTER(CloudNetwork)(Bstr().raw())); + } + else + { + CHECK_ERROR(nic, COMSETTER(CloudNetwork)(Bstr(ValueUnion.psz).raw())); + } + break; + } +#endif /* VBOX_WITH_CLOUD_NET */ + + case MODIFYVM_HOSTONLYADAPTER: + { + if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC")) + break; + + ComPtr nic; + CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam())); + ASSERT(nic); + + /* remove it? */ + if (!RTStrICmp(ValueUnion.psz, "none")) + { + CHECK_ERROR(nic, COMSETTER(HostOnlyInterface)(Bstr().raw())); + } + else + { + CHECK_ERROR(nic, COMSETTER(HostOnlyInterface)(Bstr(ValueUnion.psz).raw())); + verifyHostNetworkInterfaceName(a->virtualBox, ValueUnion.psz, + HostNetworkInterfaceType_HostOnly); + } + break; + } + +#ifdef VBOX_WITH_VMNET + case MODIFYVM_HOSTONLYNET: + { + if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC")) + break; + + ComPtr nic; + CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam())); + ASSERT(nic); + + /* remove it? */ + if (!RTStrICmp(ValueUnion.psz, "none")) + { + CHECK_ERROR(nic, COMSETTER(HostOnlyNetwork)(Bstr().raw())); + } + else + { + CHECK_ERROR(nic, COMSETTER(HostOnlyNetwork)(Bstr(ValueUnion.psz).raw())); + } + break; + } +#endif /* VBOX_WITH_VMNET */ + + case MODIFYVM_INTNET: + { + if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC")) + break; + + ComPtr nic; + CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam())); + ASSERT(nic); + + /* remove it? */ + if (!RTStrICmp(ValueUnion.psz, "none")) + { + CHECK_ERROR(nic, COMSETTER(InternalNetwork)(Bstr().raw())); + } + else + { + CHECK_ERROR(nic, COMSETTER(InternalNetwork)(Bstr(ValueUnion.psz).raw())); + } + break; + } + + case MODIFYVM_GENERICDRV: + { + if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC")) + break; + + ComPtr nic; + CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam())); + ASSERT(nic); + + CHECK_ERROR(nic, COMSETTER(GenericDriver)(Bstr(ValueUnion.psz).raw())); + break; + } + + case MODIFYVM_NATNETWORKNAME: + { + if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC")) + break; + + ComPtr nic; + CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam())); + ASSERT(nic); + + CHECK_ERROR(nic, COMSETTER(NATNetwork)(Bstr(ValueUnion.psz).raw())); + break; + } + + case MODIFYVM_NATNET: + { + if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC")) + break; + + ComPtr nic; + CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam())); + ASSERT(nic); + + ComPtr engine; + CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam())); + + const char *psz = ValueUnion.psz; + if (!RTStrICmp("default", psz)) + psz = ""; + + CHECK_ERROR(engine, COMSETTER(Network)(Bstr(psz).raw())); + break; + } + + case MODIFYVM_NATBINDIP: + { + if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC")) + break; + + ComPtr nic; + CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam())); + ASSERT(nic); + + ComPtr engine; + CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam())); + + CHECK_ERROR(engine, COMSETTER(HostIP)(Bstr(ValueUnion.psz).raw())); + break; + } + +#define ITERATE_TO_NEXT_TERM(ch) \ + do { \ + while (*ch != ',') \ + { \ + if (*ch == 0) \ + { \ + return errorSyntax(ModifyVM::tr("Missing or invalid argument to '%s'"), \ + GetOptState.pDef->pszLong); \ + } \ + ch++; \ + } \ + *ch = '\0'; \ + ch++; \ + } while(0) + + case MODIFYVM_NATSETTINGS: + { + ComPtr nic; + ComPtr engine; + char *strMtu; + char *strSockSnd; + char *strSockRcv; + char *strTcpSnd; + char *strTcpRcv; + char *strRaw = RTStrDup(ValueUnion.psz); + char *ch = strRaw; + strMtu = RTStrStrip(ch); + ITERATE_TO_NEXT_TERM(ch); + strSockSnd = RTStrStrip(ch); + ITERATE_TO_NEXT_TERM(ch); + strSockRcv = RTStrStrip(ch); + ITERATE_TO_NEXT_TERM(ch); + strTcpSnd = RTStrStrip(ch); + ITERATE_TO_NEXT_TERM(ch); + strTcpRcv = RTStrStrip(ch); + + if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC")) + break; + + CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam())); + ASSERT(nic); + + CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam())); + CHECK_ERROR(engine, SetNetworkSettings(RTStrToUInt32(strMtu), RTStrToUInt32(strSockSnd), RTStrToUInt32(strSockRcv), + RTStrToUInt32(strTcpSnd), RTStrToUInt32(strTcpRcv))); + break; + } + + + case MODIFYVM_NATPF: + { + if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC")) + break; + + ComPtr nic; + CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam())); + ASSERT(nic); + + ComPtr engine; + CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam())); + + /* format name:proto:hostip:hostport:guestip:guestport*/ + if (RTStrCmp(ValueUnion.psz, "delete") != 0) + { + char *strName; + char *strProto; + char *strHostIp; + char *strHostPort; + char *strGuestIp; + char *strGuestPort; + char *strRaw = RTStrDup(ValueUnion.psz); + char *ch = strRaw; + strName = RTStrStrip(ch); + ITERATE_TO_NEXT_TERM(ch); + strProto = RTStrStrip(ch); + ITERATE_TO_NEXT_TERM(ch); + strHostIp = RTStrStrip(ch); + ITERATE_TO_NEXT_TERM(ch); + strHostPort = RTStrStrip(ch); + ITERATE_TO_NEXT_TERM(ch); + strGuestIp = RTStrStrip(ch); + ITERATE_TO_NEXT_TERM(ch); + strGuestPort = RTStrStrip(ch); + NATProtocol_T proto; + if (RTStrICmp(strProto, "udp") == 0) + proto = NATProtocol_UDP; + else if (RTStrICmp(strProto, "tcp") == 0) + proto = NATProtocol_TCP; + else + { + errorArgument(ModifyVM::tr("Invalid proto '%s' specfied for NIC %u"), ValueUnion.psz, GetOptState.uIndex); + hrc = E_FAIL; + break; + } + CHECK_ERROR(engine, AddRedirect(Bstr(strName).raw(), proto, + Bstr(strHostIp).raw(), + RTStrToUInt16(strHostPort), + Bstr(strGuestIp).raw(), + RTStrToUInt16(strGuestPort))); + } + else + { + /* delete NAT Rule operation */ + int vrc; + vrc = RTGetOptFetchValue(&GetOptState, &ValueUnion, RTGETOPT_REQ_STRING); + if (RT_FAILURE(vrc)) + return errorSyntax(ModifyVM::tr("Not enough parameters")); + CHECK_ERROR(engine, RemoveRedirect(Bstr(ValueUnion.psz).raw())); + } + break; + } + #undef ITERATE_TO_NEXT_TERM + case MODIFYVM_NATALIASMODE: + { + ComPtr nic; + ComPtr engine; + uint32_t aliasMode = 0; + + CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam())); + ASSERT(nic); + + CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam())); + if (RTStrCmp(ValueUnion.psz, "default") == 0) + aliasMode = 0; + else + { + char *token = (char *)ValueUnion.psz; + while (token) + { + if (RTStrNCmp(token, RT_STR_TUPLE("log")) == 0) + aliasMode |= NATAliasMode_AliasLog; + else if (RTStrNCmp(token, RT_STR_TUPLE("proxyonly")) == 0) + aliasMode |= NATAliasMode_AliasProxyOnly; + else if (RTStrNCmp(token, RT_STR_TUPLE("sameports")) == 0) + aliasMode |= NATAliasMode_AliasUseSamePorts; + token = RTStrStr(token, ","); + if (token == NULL) + break; + token++; + } + } + CHECK_ERROR(engine, COMSETTER(AliasMode)(aliasMode)); + break; + } + + case MODIFYVM_NATTFTPPREFIX: + { + if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC")) + break; + + ComPtr nic; + CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam())); + ASSERT(nic); + + ComPtr engine; + CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam())); + + CHECK_ERROR(engine, COMSETTER(TFTPPrefix)(Bstr(ValueUnion.psz).raw())); + break; + } + + case MODIFYVM_NATTFTPFILE: + { + if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC")) + break; + + ComPtr nic; + CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam())); + ASSERT(nic); + + ComPtr engine; + CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam())); + + CHECK_ERROR(engine, COMSETTER(TFTPBootFile)(Bstr(ValueUnion.psz).raw())); + break; + } + + case MODIFYVM_NATTFTPSERVER: + { + if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC")) + break; + + ComPtr nic; + CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam())); + ASSERT(nic); + + ComPtr engine; + CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam())); + + CHECK_ERROR(engine, COMSETTER(TFTPNextServer)(Bstr(ValueUnion.psz).raw())); + break; + } + case MODIFYVM_NATDNSPASSDOMAIN: + { + if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC")) + break; + + ComPtr nic; + CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam())); + ASSERT(nic); + + ComPtr engine; + CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam())); + + CHECK_ERROR(engine, COMSETTER(DNSPassDomain)(ValueUnion.f)); + break; + } + + case MODIFYVM_NATDNSPROXY: + { + if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC")) + break; + + ComPtr nic; + CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam())); + ASSERT(nic); + + ComPtr engine; + CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam())); + + CHECK_ERROR(engine, COMSETTER(DNSProxy)(ValueUnion.f)); + break; + } + + case MODIFYVM_NATDNSHOSTRESOLVER: + { + if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC")) + break; + + ComPtr nic; + CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam())); + ASSERT(nic); + + ComPtr engine; + CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam())); + + CHECK_ERROR(engine, COMSETTER(DNSUseHostResolver)(ValueUnion.f)); + break; + } + + case MODIFYVM_NATLOCALHOSTREACHABLE: + { + if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC")) + break; + + ComPtr nic; + CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam())); + ASSERT(nic); + + ComPtr engine; + CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam())); + + CHECK_ERROR(engine, COMSETTER(LocalhostReachable)(ValueUnion.f)); + break; + } + + case MODIFYVM_MACADDRESS: + { + if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC")) + break; + + ComPtr nic; + CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam())); + ASSERT(nic); + + /* generate one? */ + if (!RTStrICmp(ValueUnion.psz, "auto")) + { + CHECK_ERROR(nic, COMSETTER(MACAddress)(Bstr().raw())); + } + else + { + CHECK_ERROR(nic, COMSETTER(MACAddress)(Bstr(ValueUnion.psz).raw())); + } + break; + } + + case MODIFYVM_HIDPTR: + { + bool fEnableUsb = false; + if (!RTStrICmp(ValueUnion.psz, "ps2")) + { + CHECK_ERROR(sessionMachine, COMSETTER(PointingHIDType)(PointingHIDType_PS2Mouse)); + } + else if (!RTStrICmp(ValueUnion.psz, "usb")) + { + CHECK_ERROR(sessionMachine, COMSETTER(PointingHIDType)(PointingHIDType_USBMouse)); + if (SUCCEEDED(hrc)) + fEnableUsb = true; + } + else if (!RTStrICmp(ValueUnion.psz, "usbtablet")) + { + CHECK_ERROR(sessionMachine, COMSETTER(PointingHIDType)(PointingHIDType_USBTablet)); + if (SUCCEEDED(hrc)) + fEnableUsb = true; + } + else if (!RTStrICmp(ValueUnion.psz, "usbmultitouch")) + { + CHECK_ERROR(sessionMachine, COMSETTER(PointingHIDType)(PointingHIDType_USBMultiTouch)); + if (SUCCEEDED(hrc)) + fEnableUsb = true; + } + else if (!RTStrICmp(ValueUnion.psz, "usbmtscreenpluspad")) + { + CHECK_ERROR(sessionMachine, COMSETTER(PointingHIDType)(PointingHIDType_USBMultiTouchScreenPlusPad)); + if (SUCCEEDED(hrc)) + fEnableUsb = true; + } + else if (!RTStrICmp(ValueUnion.psz, "none")) + { + CHECK_ERROR(sessionMachine, COMSETTER(PointingHIDType)(PointingHIDType_None)); + } + else + { + errorArgument(ModifyVM::tr("Invalid type '%s' specfied for pointing device"), ValueUnion.psz); + hrc = E_FAIL; + } + if (fEnableUsb) + { + /* Make sure either the OHCI or xHCI controller is enabled. */ + ULONG cOhciCtrls = 0; + ULONG cXhciCtrls = 0; + hrc = sessionMachine->GetUSBControllerCountByType(USBControllerType_OHCI, &cOhciCtrls); + if (SUCCEEDED(hrc)) { + hrc = sessionMachine->GetUSBControllerCountByType(USBControllerType_XHCI, &cXhciCtrls); + if ( SUCCEEDED(hrc) + && cOhciCtrls + cXhciCtrls == 0) + { + /* If there's nothing, enable OHCI (always available). */ + ComPtr UsbCtl; + CHECK_ERROR(sessionMachine, AddUSBController(Bstr("OHCI").raw(), USBControllerType_OHCI, + UsbCtl.asOutParam())); + } + } + } + break; + } + + case MODIFYVM_HIDKBD: + { + bool fEnableUsb = false; + if (!RTStrICmp(ValueUnion.psz, "ps2")) + { + CHECK_ERROR(sessionMachine, COMSETTER(KeyboardHIDType)(KeyboardHIDType_PS2Keyboard)); + } + else if (!RTStrICmp(ValueUnion.psz, "usb")) + { + CHECK_ERROR(sessionMachine, COMSETTER(KeyboardHIDType)(KeyboardHIDType_USBKeyboard)); + if (SUCCEEDED(hrc)) + fEnableUsb = true; + } + else if (!RTStrICmp(ValueUnion.psz, "none")) + { + CHECK_ERROR(sessionMachine, COMSETTER(KeyboardHIDType)(KeyboardHIDType_None)); + if (SUCCEEDED(hrc)) + fEnableUsb = true; + } + else + { + errorArgument(ModifyVM::tr("Invalid type '%s' specfied for keyboard"), ValueUnion.psz); + hrc = E_FAIL; + } + if (fEnableUsb) + { + /* Make sure either the OHCI or xHCI controller is enabled. */ + ULONG cOhciCtrls = 0; + ULONG cXhciCtrls = 0; + hrc = sessionMachine->GetUSBControllerCountByType(USBControllerType_OHCI, &cOhciCtrls); + if (SUCCEEDED(hrc)) { + hrc = sessionMachine->GetUSBControllerCountByType(USBControllerType_XHCI, &cXhciCtrls); + if ( SUCCEEDED(hrc) + && cOhciCtrls + cXhciCtrls == 0) + { + /* If there's nothing, enable OHCI (always available). */ + ComPtr UsbCtl; + CHECK_ERROR(sessionMachine, AddUSBController(Bstr("OHCI").raw(), USBControllerType_OHCI, + UsbCtl.asOutParam())); + } + } + } + break; + } + + case MODIFYVM_UARTMODE: + { + ComPtr uart; + + CHECK_ERROR_BREAK(sessionMachine, GetSerialPort(GetOptState.uIndex - 1, uart.asOutParam())); + ASSERT(uart); + + if (!RTStrICmp(ValueUnion.psz, "disconnected")) + { + CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_Disconnected)); + } + else if ( !RTStrICmp(ValueUnion.psz, "server") + || !RTStrICmp(ValueUnion.psz, "client") + || !RTStrICmp(ValueUnion.psz, "tcpserver") + || !RTStrICmp(ValueUnion.psz, "tcpclient") + || !RTStrICmp(ValueUnion.psz, "file")) + { + const char *pszMode = ValueUnion.psz; + + int vrc = RTGetOptFetchValue(&GetOptState, &ValueUnion, RTGETOPT_REQ_STRING); + if (RT_FAILURE(vrc)) + return errorSyntax(ModifyVM::tr("Missing or invalid argument to '%s'"), + GetOptState.pDef->pszLong); + + CHECK_ERROR(uart, COMSETTER(Path)(Bstr(ValueUnion.psz).raw())); + + if (!RTStrICmp(pszMode, "server")) + { + CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_HostPipe)); + CHECK_ERROR(uart, COMSETTER(Server)(TRUE)); + } + else if (!RTStrICmp(pszMode, "client")) + { + CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_HostPipe)); + CHECK_ERROR(uart, COMSETTER(Server)(FALSE)); + } + else if (!RTStrICmp(pszMode, "tcpserver")) + { + CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_TCP)); + CHECK_ERROR(uart, COMSETTER(Server)(TRUE)); + } + else if (!RTStrICmp(pszMode, "tcpclient")) + { + CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_TCP)); + CHECK_ERROR(uart, COMSETTER(Server)(FALSE)); + } + else if (!RTStrICmp(pszMode, "file")) + { + CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_RawFile)); + } + } + else + { + CHECK_ERROR(uart, COMSETTER(Path)(Bstr(ValueUnion.psz).raw())); + CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_HostDevice)); + } + break; + } + + case MODIFYVM_UARTTYPE: + { + ComPtr uart; + + CHECK_ERROR_BREAK(sessionMachine, GetSerialPort(GetOptState.uIndex - 1, uart.asOutParam())); + ASSERT(uart); + + if (!RTStrICmp(ValueUnion.psz, "16450")) + { + CHECK_ERROR(uart, COMSETTER(UartType)(UartType_U16450)); + } + else if (!RTStrICmp(ValueUnion.psz, "16550A")) + { + CHECK_ERROR(uart, COMSETTER(UartType)(UartType_U16550A)); + } + else if (!RTStrICmp(ValueUnion.psz, "16750")) + { + CHECK_ERROR(uart, COMSETTER(UartType)(UartType_U16750)); + } + else + return errorSyntax(ModifyVM::tr("Invalid argument to '%s'"), + GetOptState.pDef->pszLong); + break; + } + + case MODIFYVM_UART: + { + ComPtr uart; + + CHECK_ERROR_BREAK(sessionMachine, GetSerialPort(GetOptState.uIndex - 1, uart.asOutParam())); + ASSERT(uart); + + if (!RTStrICmp(ValueUnion.psz, "off") || !RTStrICmp(ValueUnion.psz, "disable")) + CHECK_ERROR(uart, COMSETTER(Enabled)(FALSE)); + else + { + const char *pszIOBase = ValueUnion.psz; + uint32_t uVal = 0; + + int vrc = RTGetOptFetchValue(&GetOptState, &ValueUnion, RTGETOPT_REQ_UINT32) != MODIFYVM_UART; + if (RT_FAILURE(vrc)) + return errorSyntax(ModifyVM::tr("Missing or invalid argument to '%s'"), + GetOptState.pDef->pszLong); + + CHECK_ERROR(uart, COMSETTER(IRQ)(ValueUnion.u32)); + + vrc = RTStrToUInt32Ex(pszIOBase, NULL, 0, &uVal); + if (vrc != VINF_SUCCESS || uVal == 0) + return errorArgument(ModifyVM::tr("Error parsing UART I/O base '%s'"), pszIOBase); + CHECK_ERROR(uart, COMSETTER(IOBase)(uVal)); + + CHECK_ERROR(uart, COMSETTER(Enabled)(TRUE)); + } + break; + } + +#if defined(RT_OS_LINUX) || defined(RT_OS_WINDOWS) + case MODIFYVM_LPTMODE: + { + ComPtr lpt; + + CHECK_ERROR_BREAK(sessionMachine, GetParallelPort(GetOptState.uIndex - 1, lpt.asOutParam())); + ASSERT(lpt); + + CHECK_ERROR(lpt, COMSETTER(Path)(Bstr(ValueUnion.psz).raw())); + break; + } + + case MODIFYVM_LPT: + { + ComPtr lpt; + + CHECK_ERROR_BREAK(sessionMachine, GetParallelPort(GetOptState.uIndex - 1, lpt.asOutParam())); + ASSERT(lpt); + + if (!RTStrICmp(ValueUnion.psz, "off") || !RTStrICmp(ValueUnion.psz, "disable")) + CHECK_ERROR(lpt, COMSETTER(Enabled)(FALSE)); + else + { + const char *pszIOBase = ValueUnion.psz; + uint32_t uVal = 0; + + int vrc = RTGetOptFetchValue(&GetOptState, &ValueUnion, RTGETOPT_REQ_UINT32) != MODIFYVM_LPT; + if (RT_FAILURE(vrc)) + return errorSyntax(ModifyVM::tr("Missing or invalid argument to '%s'"), + GetOptState.pDef->pszLong); + + CHECK_ERROR(lpt, COMSETTER(IRQ)(ValueUnion.u32)); + + vrc = RTStrToUInt32Ex(pszIOBase, NULL, 0, &uVal); + if (vrc != VINF_SUCCESS || uVal == 0) + return errorArgument(ModifyVM::tr("Error parsing LPT I/O base '%s'"), pszIOBase); + CHECK_ERROR(lpt, COMSETTER(IOBase)(uVal)); + + CHECK_ERROR(lpt, COMSETTER(Enabled)(TRUE)); + } + break; + } +#endif + + case MODIFYVM_GUESTMEMORYBALLOON: + { + CHECK_ERROR(sessionMachine, COMSETTER(MemoryBalloonSize)(ValueUnion.u32)); + break; + } + + case MODIFYVM_AUDIOCONTROLLER: + { + ComPtr audioSettings; + CHECK_ERROR_BREAK(sessionMachine, COMGETTER(AudioSettings)(audioSettings.asOutParam())); + ComPtr audioAdapter; + CHECK_ERROR_BREAK(audioSettings, COMGETTER(Adapter)(audioAdapter.asOutParam())); + ASSERT(audioAdapter); + + if (!RTStrICmp(ValueUnion.psz, "sb16")) + CHECK_ERROR(audioAdapter, COMSETTER(AudioController)(AudioControllerType_SB16)); + else if (!RTStrICmp(ValueUnion.psz, "ac97")) + CHECK_ERROR(audioAdapter, COMSETTER(AudioController)(AudioControllerType_AC97)); + else if (!RTStrICmp(ValueUnion.psz, "hda")) + CHECK_ERROR(audioAdapter, COMSETTER(AudioController)(AudioControllerType_HDA)); + else + { + errorArgument(ModifyVM::tr("Invalid --audiocontroller argument '%s'"), ValueUnion.psz); + hrc = E_FAIL; + } + break; + } + + case MODIFYVM_AUDIOCODEC: + { + ComPtr audioSettings; + CHECK_ERROR_BREAK(sessionMachine, COMGETTER(AudioSettings)(audioSettings.asOutParam())); + ComPtr audioAdapter; + CHECK_ERROR_BREAK(audioSettings, COMGETTER(Adapter)(audioAdapter.asOutParam())); + ASSERT(audioAdapter); + + if (!RTStrICmp(ValueUnion.psz, "sb16")) + CHECK_ERROR(audioAdapter, COMSETTER(AudioCodec)(AudioCodecType_SB16)); + else if (!RTStrICmp(ValueUnion.psz, "stac9700")) + CHECK_ERROR(audioAdapter, COMSETTER(AudioCodec)(AudioCodecType_STAC9700)); + else if (!RTStrICmp(ValueUnion.psz, "ad1980")) + CHECK_ERROR(audioAdapter, COMSETTER(AudioCodec)(AudioCodecType_AD1980)); + else if (!RTStrICmp(ValueUnion.psz, "stac9221")) + CHECK_ERROR(audioAdapter, COMSETTER(AudioCodec)(AudioCodecType_STAC9221)); + else + { + errorArgument(ModifyVM::tr("Invalid --audiocodec argument '%s'"), ValueUnion.psz); + hrc = E_FAIL; + } + break; + } + + case MODIFYVM_AUDIODRIVER: + RT_FALL_THROUGH(); + case MODIFYVM_AUDIO: /** @todo Deprecated; remove. */ + { + if (c == MODIFYVM_AUDIO) + RTStrmPrintf(g_pStdErr, + ModifyVM::tr("Warning: --audio is deprecated and will be removed soon. Use --audio-driver instead!\n")); + + ComPtr audioSettings; + CHECK_ERROR_BREAK(sessionMachine, COMGETTER(AudioSettings)(audioSettings.asOutParam())); + ComPtr audioAdapter; + CHECK_ERROR_BREAK(audioSettings, COMGETTER(Adapter)(audioAdapter.asOutParam())); + ASSERT(audioAdapter); + /* disable? */ + if ( !RTStrICmp(ValueUnion.psz, "none") + || !RTStrICmp(ValueUnion.psz, "null")) + CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_Null)); + else if (!RTStrICmp(ValueUnion.psz, "default")) + CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_Default)); +#ifdef RT_OS_WINDOWS +# ifdef VBOX_WITH_WINMM + else if (!RTStrICmp(ValueUnion.psz, "winmm")) + CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_WinMM)); +# endif + else if (!RTStrICmp(ValueUnion.psz, "dsound")) + CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_DirectSound)); + else if (!RTStrICmp(ValueUnion.psz, "was")) + CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_WAS)); +#endif /* RT_OS_WINDOWS */ +#ifdef VBOX_WITH_AUDIO_OSS + else if (!RTStrICmp(ValueUnion.psz, "oss")) + CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_OSS)); +#endif +#ifdef VBOX_WITH_AUDIO_ALSA + else if (!RTStrICmp(ValueUnion.psz, "alsa")) + CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_ALSA)); +#endif +#ifdef VBOX_WITH_AUDIO_PULSE + else if (!RTStrICmp(ValueUnion.psz, "pulse")) + CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_Pulse)); +#endif +#ifdef RT_OS_DARWIN + else if (!RTStrICmp(ValueUnion.psz, "coreaudio")) + CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_CoreAudio)); +#endif /* !RT_OS_DARWIN */ + else + { + errorArgument(ModifyVM::tr("Invalid %s argument '%s'"), + c == MODIFYVM_AUDIO ? "--audio" : "--audio-driver", ValueUnion.psz); + hrc = E_FAIL; + } + + if ( SUCCEEDED(hrc) + && c == MODIFYVM_AUDIO) /* To keep the original behavior until we remove the command. */ + CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(RTStrICmp(ValueUnion.psz, "none") == false ? false : true)); + + break; + } + + case MODIFYVM_AUDIOENABLED: + { + ComPtr audioSettings; + CHECK_ERROR_BREAK(sessionMachine, COMGETTER(AudioSettings)(audioSettings.asOutParam())); + ComPtr audioAdapter; + CHECK_ERROR_BREAK(audioSettings, COMGETTER(Adapter)(audioAdapter.asOutParam())); + ASSERT(audioAdapter); + + CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(ValueUnion.f)); + break; + } + + case MODIFYVM_AUDIOIN: + { + ComPtr audioSettings; + CHECK_ERROR_BREAK(sessionMachine, COMGETTER(AudioSettings)(audioSettings.asOutParam())); + ComPtr audioAdapter; + CHECK_ERROR_BREAK(audioSettings, COMGETTER(Adapter)(audioAdapter.asOutParam())); + ASSERT(audioAdapter); + + CHECK_ERROR(audioAdapter, COMSETTER(EnabledIn)(ValueUnion.f)); + break; + } + + case MODIFYVM_AUDIOOUT: + { + ComPtr audioSettings; + CHECK_ERROR_BREAK(sessionMachine, COMGETTER(AudioSettings)(audioSettings.asOutParam())); + ComPtr audioAdapter; + CHECK_ERROR_BREAK(audioSettings, COMGETTER(Adapter)(audioAdapter.asOutParam())); + ASSERT(audioAdapter); + + CHECK_ERROR(audioAdapter, COMSETTER(EnabledOut)(ValueUnion.f)); + break; + } + +#ifdef VBOX_WITH_SHARED_CLIPBOARD + case MODIFYVM_CLIPBOARD_MODE: + { + ClipboardMode_T mode = ClipboardMode_Disabled; /* Shut up MSC */ + if (!RTStrICmp(ValueUnion.psz, "disabled")) + mode = ClipboardMode_Disabled; + else if (!RTStrICmp(ValueUnion.psz, "hosttoguest")) + mode = ClipboardMode_HostToGuest; + else if (!RTStrICmp(ValueUnion.psz, "guesttohost")) + mode = ClipboardMode_GuestToHost; + else if (!RTStrICmp(ValueUnion.psz, "bidirectional")) + mode = ClipboardMode_Bidirectional; + else + { + errorArgument(ModifyVM::tr("Invalid --clipboard-mode argument '%s'"), ValueUnion.psz); + hrc = E_FAIL; + } + if (SUCCEEDED(hrc)) + { + CHECK_ERROR(sessionMachine, COMSETTER(ClipboardMode)(mode)); + } + break; + } + +# ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS + case MODIFYVM_CLIPBOARD_FILE_TRANSFERS: + { + BOOL fEnabled = false; /* Shut up MSC */ + if (!RTStrICmp(ValueUnion.psz, "enabled")) + fEnabled = true; + else if (!RTStrICmp(ValueUnion.psz, "disabled")) + fEnabled = false; + else + { + errorArgument(ModifyVM::tr("Invalid --clipboard-file-transfers argument '%s'"), ValueUnion.psz); + hrc = E_FAIL; + } + if (SUCCEEDED(hrc)) + { + CHECK_ERROR(sessionMachine, COMSETTER(ClipboardFileTransfersEnabled)(fEnabled)); + } + break; + } +# endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */ +#endif /* VBOX_WITH_SHARED_CLIPBOARD */ + + case MODIFYVM_DRAGANDDROP: + { + DnDMode_T mode = DnDMode_Disabled; /* Shut up MSC */ + if (!RTStrICmp(ValueUnion.psz, "disabled")) + mode = DnDMode_Disabled; + else if (!RTStrICmp(ValueUnion.psz, "hosttoguest")) + mode = DnDMode_HostToGuest; + else if (!RTStrICmp(ValueUnion.psz, "guesttohost")) + mode = DnDMode_GuestToHost; + else if (!RTStrICmp(ValueUnion.psz, "bidirectional")) + mode = DnDMode_Bidirectional; + else + { + errorArgument(ModifyVM::tr("Invalid --draganddrop argument '%s'"), ValueUnion.psz); + hrc = E_FAIL; + } + if (SUCCEEDED(hrc)) + { + CHECK_ERROR(sessionMachine, COMSETTER(DnDMode)(mode)); + } + break; + } + + case MODIFYVM_VRDE_EXTPACK: + { + ComPtr vrdeServer; + sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam()); + ASSERT(vrdeServer); + + if (vrdeServer) + { + if (RTStrICmp(ValueUnion.psz, "default") != 0) + { + Bstr bstr(ValueUnion.psz); + CHECK_ERROR(vrdeServer, COMSETTER(VRDEExtPack)(bstr.raw())); + } + else + CHECK_ERROR(vrdeServer, COMSETTER(VRDEExtPack)(Bstr().raw())); + } + break; + } + + case MODIFYVM_VRDEPROPERTY: + { + ComPtr vrdeServer; + sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam()); + ASSERT(vrdeServer); + + if (vrdeServer) + { + /* Parse 'name=value' */ + char *pszProperty = RTStrDup(ValueUnion.psz); + if (pszProperty) + { + char *pDelimiter = strchr(pszProperty, '='); + if (pDelimiter) + { + *pDelimiter = '\0'; + + Bstr bstrName = pszProperty; + Bstr bstrValue = &pDelimiter[1]; + CHECK_ERROR(vrdeServer, SetVRDEProperty(bstrName.raw(), bstrValue.raw())); + } + else + { + RTStrFree(pszProperty); + + errorArgument(ModifyVM::tr("Invalid --vrdeproperty argument '%s'"), ValueUnion.psz); + hrc = E_FAIL; + break; + } + RTStrFree(pszProperty); + } + else + { + RTStrmPrintf(g_pStdErr, ModifyVM::tr("Error: Failed to allocate memory for VRDE property '%s'\n"), + ValueUnion.psz); + hrc = E_FAIL; + } + } + break; + } + + case MODIFYVM_VRDPPORT: + vrdeWarningDeprecatedOption("port"); + RT_FALL_THRU(); + + case MODIFYVM_VRDEPORT: + { + ComPtr vrdeServer; + sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam()); + ASSERT(vrdeServer); + + if (!RTStrICmp(ValueUnion.psz, "default")) + CHECK_ERROR(vrdeServer, SetVRDEProperty(Bstr("TCP/Ports").raw(), Bstr("0").raw())); + else + CHECK_ERROR(vrdeServer, SetVRDEProperty(Bstr("TCP/Ports").raw(), Bstr(ValueUnion.psz).raw())); + break; + } + + case MODIFYVM_VRDPADDRESS: + vrdeWarningDeprecatedOption("address"); + RT_FALL_THRU(); + + case MODIFYVM_VRDEADDRESS: + { + ComPtr vrdeServer; + sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam()); + ASSERT(vrdeServer); + + CHECK_ERROR(vrdeServer, SetVRDEProperty(Bstr("TCP/Address").raw(), Bstr(ValueUnion.psz).raw())); + break; + } + + case MODIFYVM_VRDPAUTHTYPE: + vrdeWarningDeprecatedOption("authtype"); + RT_FALL_THRU(); + case MODIFYVM_VRDEAUTHTYPE: + { + ComPtr vrdeServer; + sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam()); + ASSERT(vrdeServer); + + if (!RTStrICmp(ValueUnion.psz, "null")) + { + CHECK_ERROR(vrdeServer, COMSETTER(AuthType)(AuthType_Null)); + } + else if (!RTStrICmp(ValueUnion.psz, "external")) + { + CHECK_ERROR(vrdeServer, COMSETTER(AuthType)(AuthType_External)); + } + else if (!RTStrICmp(ValueUnion.psz, "guest")) + { + CHECK_ERROR(vrdeServer, COMSETTER(AuthType)(AuthType_Guest)); + } + else + { + errorArgument(ModifyVM::tr("Invalid --vrdeauthtype argument '%s'"), ValueUnion.psz); + hrc = E_FAIL; + } + break; + } + + case MODIFYVM_VRDEAUTHLIBRARY: + { + ComPtr vrdeServer; + sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam()); + ASSERT(vrdeServer); + + if (vrdeServer) + { + if (RTStrICmp(ValueUnion.psz, "default") != 0) + { + Bstr bstr(ValueUnion.psz); + CHECK_ERROR(vrdeServer, COMSETTER(AuthLibrary)(bstr.raw())); + } + else + CHECK_ERROR(vrdeServer, COMSETTER(AuthLibrary)(Bstr().raw())); + } + break; + } + + case MODIFYVM_VRDPMULTICON: + vrdeWarningDeprecatedOption("multicon"); + RT_FALL_THRU(); + case MODIFYVM_VRDEMULTICON: + { + ComPtr vrdeServer; + sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam()); + ASSERT(vrdeServer); + + CHECK_ERROR(vrdeServer, COMSETTER(AllowMultiConnection)(ValueUnion.f)); + break; + } + + case MODIFYVM_VRDPREUSECON: + vrdeWarningDeprecatedOption("reusecon"); + RT_FALL_THRU(); + case MODIFYVM_VRDEREUSECON: + { + ComPtr vrdeServer; + sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam()); + ASSERT(vrdeServer); + + CHECK_ERROR(vrdeServer, COMSETTER(ReuseSingleConnection)(ValueUnion.f)); + break; + } + + case MODIFYVM_VRDPVIDEOCHANNEL: + vrdeWarningDeprecatedOption("videochannel"); + RT_FALL_THRU(); + case MODIFYVM_VRDEVIDEOCHANNEL: + { + ComPtr vrdeServer; + sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam()); + ASSERT(vrdeServer); + + CHECK_ERROR(vrdeServer, SetVRDEProperty(Bstr("VideoChannel/Enabled").raw(), + ValueUnion.f? Bstr("true").raw(): Bstr("false").raw())); + break; + } + + case MODIFYVM_VRDPVIDEOCHANNELQUALITY: + vrdeWarningDeprecatedOption("videochannelquality"); + RT_FALL_THRU(); + case MODIFYVM_VRDEVIDEOCHANNELQUALITY: + { + ComPtr vrdeServer; + sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam()); + ASSERT(vrdeServer); + + CHECK_ERROR(vrdeServer, SetVRDEProperty(Bstr("VideoChannel/Quality").raw(), + Bstr(ValueUnion.psz).raw())); + break; + } + + case MODIFYVM_VRDP: + vrdeWarningDeprecatedOption(""); + RT_FALL_THRU(); + case MODIFYVM_VRDE: + { + ComPtr vrdeServer; + sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam()); + ASSERT(vrdeServer); + + CHECK_ERROR(vrdeServer, COMSETTER(Enabled)(ValueUnion.f)); + break; + } + + case MODIFYVM_USBRENAME: + { + const char *pszName = ValueUnion.psz; + int vrc = RTGetOptFetchValue(&GetOptState, &ValueUnion, RTGETOPT_REQ_STRING); + if (RT_FAILURE(vrc)) + return errorSyntax(ModifyVM::tr("Missing or invalid argument to '%s'"), + GetOptState.pDef->pszLong); + const char *pszNewName = ValueUnion.psz; + + SafeIfaceArray ctrls; + CHECK_ERROR(sessionMachine, COMGETTER(USBControllers)(ComSafeArrayAsOutParam(ctrls))); + bool fRenamed = false; + for (size_t i = 0; i < ctrls.size(); i++) + { + ComPtr pCtrl = ctrls[i]; + Bstr bstrName; + CHECK_ERROR(pCtrl, COMGETTER(Name)(bstrName.asOutParam())); + if (bstrName == pszName) + { + bstrName = pszNewName; + CHECK_ERROR(pCtrl, COMSETTER(Name)(bstrName.raw())); + fRenamed = true; + } + } + if (!fRenamed) + { + errorArgument(ModifyVM::tr("Invalid --usbrename parameters, nothing renamed")); + hrc = E_FAIL; + } + break; + } + + case MODIFYVM_USBXHCI: + { + ULONG cXhciCtrls = 0; + hrc = sessionMachine->GetUSBControllerCountByType(USBControllerType_XHCI, &cXhciCtrls); + if (SUCCEEDED(hrc)) + { + if (!cXhciCtrls && ValueUnion.f) + { + ComPtr UsbCtl; + CHECK_ERROR(sessionMachine, AddUSBController(Bstr("xHCI").raw(), USBControllerType_XHCI, + UsbCtl.asOutParam())); + } + else if (cXhciCtrls && !ValueUnion.f) + { + SafeIfaceArray ctrls; + CHECK_ERROR(sessionMachine, COMGETTER(USBControllers)(ComSafeArrayAsOutParam(ctrls))); + for (size_t i = 0; i < ctrls.size(); i++) + { + ComPtr pCtrl = ctrls[i]; + USBControllerType_T enmType; + CHECK_ERROR(pCtrl, COMGETTER(Type)(&enmType)); + if (enmType == USBControllerType_XHCI) + { + Bstr ctrlName; + CHECK_ERROR(pCtrl, COMGETTER(Name)(ctrlName.asOutParam())); + CHECK_ERROR(sessionMachine, RemoveUSBController(ctrlName.raw())); + } + } + } + } + break; + } + + case MODIFYVM_USBEHCI: + { + ULONG cEhciCtrls = 0; + hrc = sessionMachine->GetUSBControllerCountByType(USBControllerType_EHCI, &cEhciCtrls); + if (SUCCEEDED(hrc)) + { + if (!cEhciCtrls && ValueUnion.f) + { + ComPtr UsbCtl; + CHECK_ERROR(sessionMachine, AddUSBController(Bstr("EHCI").raw(), USBControllerType_EHCI, + UsbCtl.asOutParam())); + } + else if (cEhciCtrls && !ValueUnion.f) + { + SafeIfaceArray ctrls; + CHECK_ERROR(sessionMachine, COMGETTER(USBControllers)(ComSafeArrayAsOutParam(ctrls))); + for (size_t i = 0; i < ctrls.size(); i++) + { + ComPtr pCtrl = ctrls[i]; + USBControllerType_T enmType; + CHECK_ERROR(pCtrl, COMGETTER(Type)(&enmType)); + if (enmType == USBControllerType_EHCI) + { + Bstr ctrlName; + CHECK_ERROR(pCtrl, COMGETTER(Name)(ctrlName.asOutParam())); + CHECK_ERROR(sessionMachine, RemoveUSBController(ctrlName.raw())); + } + } + } + } + break; + } + + case MODIFYVM_USBOHCI: + { + ULONG cOhciCtrls = 0; + hrc = sessionMachine->GetUSBControllerCountByType(USBControllerType_OHCI, &cOhciCtrls); + if (SUCCEEDED(hrc)) + { + if (!cOhciCtrls && ValueUnion.f) + { + ComPtr UsbCtl; + CHECK_ERROR(sessionMachine, AddUSBController(Bstr("OHCI").raw(), USBControllerType_OHCI, + UsbCtl.asOutParam())); + } + else if (cOhciCtrls && !ValueUnion.f) + { + SafeIfaceArray ctrls; + CHECK_ERROR(sessionMachine, COMGETTER(USBControllers)(ComSafeArrayAsOutParam(ctrls))); + for (size_t i = 0; i < ctrls.size(); i++) + { + ComPtr pCtrl = ctrls[i]; + USBControllerType_T enmType; + CHECK_ERROR(pCtrl, COMGETTER(Type)(&enmType)); + if (enmType == USBControllerType_OHCI) + { + Bstr ctrlName; + CHECK_ERROR(pCtrl, COMGETTER(Name)(ctrlName.asOutParam())); + CHECK_ERROR(sessionMachine, RemoveUSBController(ctrlName.raw())); + } + } + } + } + break; + } + + case MODIFYVM_SNAPSHOTFOLDER: + { + if (!RTStrICmp(ValueUnion.psz, "default")) + CHECK_ERROR(sessionMachine, COMSETTER(SnapshotFolder)(Bstr().raw())); + else + CHECK_ERROR(sessionMachine, COMSETTER(SnapshotFolder)(Bstr(ValueUnion.psz).raw())); + break; + } + + case MODIFYVM_TELEPORTER_ENABLED: + { + CHECK_ERROR(sessionMachine, COMSETTER(TeleporterEnabled)(ValueUnion.f)); + break; + } + + case MODIFYVM_TELEPORTER_PORT: + { + CHECK_ERROR(sessionMachine, COMSETTER(TeleporterPort)(ValueUnion.u32)); + break; + } + + case MODIFYVM_TELEPORTER_ADDRESS: + { + CHECK_ERROR(sessionMachine, COMSETTER(TeleporterAddress)(Bstr(ValueUnion.psz).raw())); + break; + } + + case MODIFYVM_TELEPORTER_PASSWORD: + { + CHECK_ERROR(sessionMachine, COMSETTER(TeleporterPassword)(Bstr(ValueUnion.psz).raw())); + break; + } + + case MODIFYVM_TELEPORTER_PASSWORD_FILE: + { + Utf8Str password; + RTEXITCODE rcExit = readPasswordFile(ValueUnion.psz, &password); + if (rcExit != RTEXITCODE_SUCCESS) + hrc = E_FAIL; + else + CHECK_ERROR(sessionMachine, COMSETTER(TeleporterPassword)(Bstr(password).raw())); + break; + } + + case MODIFYVM_TRACING_ENABLED: + { + CHECK_ERROR(sessionMachine, COMSETTER(TracingEnabled)(ValueUnion.f)); + break; + } + + case MODIFYVM_TRACING_CONFIG: + { + CHECK_ERROR(sessionMachine, COMSETTER(TracingConfig)(Bstr(ValueUnion.psz).raw())); + break; + } + + case MODIFYVM_TRACING_ALLOW_VM_ACCESS: + { + CHECK_ERROR(sessionMachine, COMSETTER(AllowTracingToAccessVM)(ValueUnion.f)); + break; + } + + case MODIFYVM_HARDWARE_UUID: + { + CHECK_ERROR(sessionMachine, COMSETTER(HardwareUUID)(Bstr(ValueUnion.psz).raw())); + break; + } + + case MODIFYVM_HPET: + { + CHECK_ERROR(sessionMachine, COMSETTER(HPETEnabled)(ValueUnion.f)); + break; + } + + case MODIFYVM_IOCACHE: + { + CHECK_ERROR(sessionMachine, COMSETTER(IOCacheEnabled)(ValueUnion.f)); + break; + } + + case MODIFYVM_IOCACHESIZE: + { + CHECK_ERROR(sessionMachine, COMSETTER(IOCacheSize)(ValueUnion.u32)); + break; + } + + case MODIFYVM_CHIPSET: + { + if (!RTStrICmp(ValueUnion.psz, "piix3")) + { + CHECK_ERROR(sessionMachine, COMSETTER(ChipsetType)(ChipsetType_PIIX3)); + } + else if (!RTStrICmp(ValueUnion.psz, "ich9")) + { + CHECK_ERROR(sessionMachine, COMSETTER(ChipsetType)(ChipsetType_ICH9)); + BOOL fIoApic = FALSE; + CHECK_ERROR(biosSettings, COMGETTER(IOAPICEnabled)(&fIoApic)); + if (!fIoApic) + { + RTStrmPrintf(g_pStdErr, ModifyVM::tr("*** I/O APIC must be enabled for ICH9, enabling. ***\n")); + CHECK_ERROR(biosSettings, COMSETTER(IOAPICEnabled)(TRUE)); + } + } + else + { + errorArgument(ModifyVM::tr("Invalid --chipset argument '%s' (valid: piix3,ich9)"), ValueUnion.psz); + hrc = E_FAIL; + } + break; + } +#if defined(VBOX_WITH_IOMMU_AMD) || defined(VBOX_WITH_IOMMU_INTEL) + case MODIFYVM_IOMMU: + { + if ( !RTStrICmp(ValueUnion.psz, "none") + || !RTStrICmp(ValueUnion.psz, "disabled")) + CHECK_ERROR(sessionMachine, COMSETTER(IommuType)(IommuType_None)); + else if (!RTStrICmp(ValueUnion.psz, "amd")) + CHECK_ERROR(sessionMachine, COMSETTER(IommuType)(IommuType_AMD)); + else if (!RTStrICmp(ValueUnion.psz, "intel")) + { +#ifdef VBOX_WITH_IOMMU_INTEL + CHECK_ERROR(sessionMachine, COMSETTER(IommuType)(IommuType_Intel)); +#else + errorArgument(ModifyVM::tr("Invalid --iommu argument '%s' (valid: none,amd,automatic)"), ValueUnion.psz); + hrc = E_FAIL; +#endif + } + else if (!RTStrICmp(ValueUnion.psz, "automatic")) + { + CHECK_ERROR(sessionMachine, COMSETTER(IommuType)(IommuType_Automatic)); +#ifndef VBOX_WITH_IOMMU_INTEL + RTStrmPrintf(g_pStdErr, + ModifyVM::tr("Warning: On Intel hosts, 'automatic' will not enable an IOMMU since the Intel IOMMU device is not supported yet.\n")); +#endif + } + else + { + errorArgument(ModifyVM::tr("Invalid --iommu argument '%s'"), ValueUnion.psz); + hrc = E_FAIL; + } + break; + } +#endif +#if defined(VBOX_WITH_TPM) + case MODIFYVM_TPM_TYPE: + { + ComPtr tpm; + sessionMachine->COMGETTER(TrustedPlatformModule)(tpm.asOutParam()); + + if ( !RTStrICmp(ValueUnion.psz, "none") + || !RTStrICmp(ValueUnion.psz, "disabled")) + CHECK_ERROR(tpm, COMSETTER(Type)(TpmType_None)); + else if (!RTStrICmp(ValueUnion.psz, "1.2")) + CHECK_ERROR(tpm, COMSETTER(Type)(TpmType_v1_2)); + else if (!RTStrICmp(ValueUnion.psz, "2.0")) + CHECK_ERROR(tpm, COMSETTER(Type)(TpmType_v2_0)); + else if (!RTStrICmp(ValueUnion.psz, "host")) + CHECK_ERROR(tpm, COMSETTER(Type)(TpmType_Host)); + else if (!RTStrICmp(ValueUnion.psz, "swtpm")) + CHECK_ERROR(tpm, COMSETTER(Type)(TpmType_Swtpm)); + else + { + errorArgument(ModifyVM::tr("Invalid --tpm-type argument '%s'"), ValueUnion.psz); + hrc = E_FAIL; + } + break; + } + + case MODIFYVM_TPM_LOCATION: + { + ComPtr tpm; + sessionMachine->COMGETTER(TrustedPlatformModule)(tpm.asOutParam()); + + CHECK_ERROR(tpm, COMSETTER(Location)(Bstr(ValueUnion.psz).raw())); + break; + } +#endif +#ifdef VBOX_WITH_RECORDING + case MODIFYVM_RECORDING: + RT_FALL_THROUGH(); + case MODIFYVM_RECORDING_SCREENS: + RT_FALL_THROUGH(); + case MODIFYVM_RECORDING_FILENAME: + RT_FALL_THROUGH(); + case MODIFYVM_RECORDING_VIDEO_WIDTH: + RT_FALL_THROUGH(); + case MODIFYVM_RECORDING_VIDEO_HEIGHT: + RT_FALL_THROUGH(); + case MODIFYVM_RECORDING_VIDEO_RES: + RT_FALL_THROUGH(); + case MODIFYVM_RECORDING_VIDEO_RATE: + RT_FALL_THROUGH(); + case MODIFYVM_RECORDING_VIDEO_FPS: + RT_FALL_THROUGH(); + case MODIFYVM_RECORDING_MAXTIME: + RT_FALL_THROUGH(); + case MODIFYVM_RECORDING_MAXSIZE: + RT_FALL_THROUGH(); + case MODIFYVM_RECORDING_OPTIONS: + { + ComPtr recordingSettings; + CHECK_ERROR_BREAK(sessionMachine, COMGETTER(RecordingSettings)(recordingSettings.asOutParam())); + SafeIfaceArray saRecordingScreenScreens; + CHECK_ERROR_BREAK(recordingSettings, COMGETTER(Screens)(ComSafeArrayAsOutParam(saRecordingScreenScreens))); + + switch (c) + { + case MODIFYVM_RECORDING: + { + CHECK_ERROR(recordingSettings, COMSETTER(Enabled)(ValueUnion.f)); + break; + } + case MODIFYVM_RECORDING_SCREENS: + { + ULONG cMonitors = 64; + CHECK_ERROR(pGraphicsAdapter, COMGETTER(MonitorCount)(&cMonitors)); + com::SafeArray screens(cMonitors); + if (RT_FAILURE(parseScreens(ValueUnion.psz, &screens))) + { + errorArgument(ModifyVM::tr("Invalid list of screens specified\n")); + hrc = E_FAIL; + break; + } + + if (cMonitors > saRecordingScreenScreens.size()) /* Paranoia. */ + cMonitors = (ULONG)saRecordingScreenScreens.size(); + + for (size_t i = 0; i < cMonitors; ++i) + CHECK_ERROR_BREAK(saRecordingScreenScreens[i], COMSETTER(Enabled)(screens[i])); + break; + } + case MODIFYVM_RECORDING_FILENAME: + { + Bstr bstr; + /* empty string will fall through, leaving bstr empty */ + if (*ValueUnion.psz) + { + char szVCFileAbs[RTPATH_MAX] = ""; + int vrc = RTPathAbs(ValueUnion.psz, szVCFileAbs, sizeof(szVCFileAbs)); + if (RT_FAILURE(vrc)) + { + errorArgument(ModifyVM::tr("Cannot convert filename \"%s\" to absolute path\n"), ValueUnion.psz); + hrc = E_FAIL; + break; + } + bstr = szVCFileAbs; + } + + for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i) + CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(Filename)(bstr.raw())); + break; + } + case MODIFYVM_RECORDING_VIDEO_WIDTH: + { + for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i) + CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(VideoWidth)(ValueUnion.u32)); + break; + } + case MODIFYVM_RECORDING_VIDEO_HEIGHT: + { + for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i) + CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(VideoHeight)(ValueUnion.u32)); + break; + } + case MODIFYVM_RECORDING_VIDEO_RES: + { + uint32_t uWidth = 0; + char *pszNext; + int vrc = RTStrToUInt32Ex(ValueUnion.psz, &pszNext, 0, &uWidth); + if (RT_FAILURE(vrc) || vrc != VWRN_TRAILING_CHARS || !pszNext || *pszNext != 'x') + { + errorArgument(ModifyVM::tr("Error parsing video resolution '%s' (expected x)"), + ValueUnion.psz); + hrc = E_FAIL; + break; + } + uint32_t uHeight = 0; + vrc = RTStrToUInt32Ex(pszNext+1, NULL, 0, &uHeight); + if (vrc != VINF_SUCCESS) + { + errorArgument(ModifyVM::tr("Error parsing video resolution '%s' (expected x)"), + ValueUnion.psz); + hrc = E_FAIL; + break; + } + + for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i) + { + CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(VideoWidth)(uWidth)); + CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(VideoHeight)(uHeight)); + } + break; + } + case MODIFYVM_RECORDING_VIDEO_RATE: + { + for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i) + CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(VideoRate)(ValueUnion.u32)); + break; + } + case MODIFYVM_RECORDING_VIDEO_FPS: + { + for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i) + CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(VideoFPS)(ValueUnion.u32)); + break; + } + case MODIFYVM_RECORDING_MAXTIME: + { + for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i) + CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(MaxTime)(ValueUnion.u32)); + break; + } + case MODIFYVM_RECORDING_MAXSIZE: + { + for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i) + CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(MaxFileSize)(ValueUnion.u32)); + break; + } + case MODIFYVM_RECORDING_OPTIONS: + { + Bstr bstr(ValueUnion.psz); + for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i) + CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(Options)(bstr.raw())); + break; + } + } + + break; + } +#endif + case MODIFYVM_AUTOSTART_ENABLED: + { + CHECK_ERROR(sessionMachine, COMSETTER(AutostartEnabled)(ValueUnion.f)); + break; + } + + case MODIFYVM_AUTOSTART_DELAY: + { + CHECK_ERROR(sessionMachine, COMSETTER(AutostartDelay)(ValueUnion.u32)); + break; + } + + case MODIFYVM_AUTOSTOP_TYPE: + { + AutostopType_T enmAutostopType = AutostopType_Disabled; + + if (!RTStrICmp(ValueUnion.psz, "disabled")) + enmAutostopType = AutostopType_Disabled; + else if (!RTStrICmp(ValueUnion.psz, "savestate")) + enmAutostopType = AutostopType_SaveState; + else if (!RTStrICmp(ValueUnion.psz, "poweroff")) + enmAutostopType = AutostopType_PowerOff; + else if (!RTStrICmp(ValueUnion.psz, "acpishutdown")) + enmAutostopType = AutostopType_AcpiShutdown; + else + { + errorArgument(ModifyVM::tr("Invalid --autostop-type argument '%s' (valid: disabled, savestate, poweroff, acpishutdown)"), + ValueUnion.psz); + hrc = E_FAIL; + } + + if (SUCCEEDED(hrc)) + CHECK_ERROR(sessionMachine, COMSETTER(AutostopType)(enmAutostopType)); + break; + } +#ifdef VBOX_WITH_PCI_PASSTHROUGH + case MODIFYVM_ATTACH_PCI: + { + const char* pAt = strchr(ValueUnion.psz, '@'); + int32_t iHostAddr, iGuestAddr; + + iHostAddr = parsePci(ValueUnion.psz); + iGuestAddr = pAt != NULL ? parsePci(pAt + 1) : iHostAddr; + + if (iHostAddr == -1 || iGuestAddr == -1) + { + errorArgument(ModifyVM::tr("Invalid --pciattach argument '%s' (valid: 'HB:HD.HF@GB:GD.GF' or just 'HB:HD.HF')"), + ValueUnion.psz); + hrc = E_FAIL; + } + else + { + CHECK_ERROR(sessionMachine, AttachHostPCIDevice(iHostAddr, iGuestAddr, TRUE)); + } + + break; + } + case MODIFYVM_DETACH_PCI: + { + int32_t iHostAddr; + + iHostAddr = parsePci(ValueUnion.psz); + if (iHostAddr == -1) + { + errorArgument(ModifyVM::tr("Invalid --pcidetach argument '%s' (valid: 'HB:HD.HF')"), ValueUnion.psz); + hrc = E_FAIL; + } + else + { + CHECK_ERROR(sessionMachine, DetachHostPCIDevice(iHostAddr)); + } + + break; + } +#endif + +#ifdef VBOX_WITH_USB_CARDREADER + case MODIFYVM_USBCARDREADER: + { + CHECK_ERROR(sessionMachine, COMSETTER(EmulatedUSBCardReaderEnabled)(ValueUnion.f)); + break; + } +#endif /* VBOX_WITH_USB_CARDREADER */ + + case MODIFYVM_DEFAULTFRONTEND: + { + Bstr bstr(ValueUnion.psz); + if (bstr == "default") + bstr = Bstr::Empty; + CHECK_ERROR(sessionMachine, COMSETTER(DefaultFrontend)(bstr.raw())); + break; + } + + case MODIFYVM_VMPROC_PRIORITY: + { + VMProcPriority_T enmPriority = nameToVMProcPriority(ValueUnion.psz); + if (enmPriority == VMProcPriority_Invalid) + { + errorArgument(ModifyVM::tr("Invalid --vm-process-priority '%s'"), ValueUnion.psz); + hrc = E_FAIL; + } + else + { + CHECK_ERROR(sessionMachine, COMSETTER(VMProcessPriority)(enmPriority)); + } + break; + } + + case MODIFYVM_TESTING_ENABLED: + hrc = setExtraData(sessionMachine, "VBoxInternal/Devices/VMMDev/0/Config/TestingEnabled", ValueUnion.f ? "1" : ""); + break; + + case MODIFYVM_TESTING_MMIO: + hrc = setExtraData(sessionMachine, "VBoxInternal/Devices/VMMDev/0/Config/TestingMMIO", ValueUnion.f ? "1" : ""); + break; + + case MODIFYVM_TESTING_CFG_DWORD: + if (GetOptState.uIndex <= 9) + { + char szVar[128]; + RTStrPrintf(szVar, sizeof(szVar), "VBoxInternal/Devices/VMMDev/0/Config/TestingCfgDword%u", + GetOptState.uIndex); + char szValue[32]; + RTStrPrintf(szValue, sizeof(szValue), "%u", ValueUnion.u32); + hrc = setExtraData(sessionMachine, szVar, szValue); + } + else + hrc = errorArgumentHr(ModifyVM::tr("--testing-cfg-dword index %u is out of range: 0 thru 9"), + GetOptState.uIndex); + break; + + case MODIFYVM_GUEST_DEBUG_PROVIDER: + { + ComPtr gstDbgCtrl; + CHECK_ERROR_BREAK(sessionMachine, COMGETTER(GuestDebugControl)(gstDbgCtrl.asOutParam())); + + GuestDebugProvider_T enmDebugProvider = GuestDebugProvider_None; + + if (!RTStrICmp(ValueUnion.psz, "none")) + enmDebugProvider = GuestDebugProvider_None; + else if (!RTStrICmp(ValueUnion.psz, "native")) + enmDebugProvider = GuestDebugProvider_Native; + else if (!RTStrICmp(ValueUnion.psz, "gdb")) + enmDebugProvider = GuestDebugProvider_GDB; + else if (!RTStrICmp(ValueUnion.psz, "kd")) + enmDebugProvider = GuestDebugProvider_KD; + else + { + errorArgument(ModifyVM::tr("Invalid --guest-debug-provider '%s' (valid: none, native, gdb, kd)"), + ValueUnion.psz); + hrc = E_FAIL; + } + + if (SUCCEEDED(hrc)) + CHECK_ERROR(gstDbgCtrl, COMSETTER(DebugProvider)(enmDebugProvider)); + break; + } + + case MODIFYVM_GUEST_DEBUG_IO_PROVIDER: + { + ComPtr gstDbgCtrl; + CHECK_ERROR_BREAK(sessionMachine, COMGETTER(GuestDebugControl)(gstDbgCtrl.asOutParam())); + + GuestDebugIoProvider_T enmDebugIoProvider = GuestDebugIoProvider_None; + + if (!RTStrICmp(ValueUnion.psz, "none")) + enmDebugIoProvider = GuestDebugIoProvider_None; + else if (!RTStrICmp(ValueUnion.psz, "tcp")) + enmDebugIoProvider = GuestDebugIoProvider_TCP; + else if (!RTStrICmp(ValueUnion.psz, "udp")) + enmDebugIoProvider = GuestDebugIoProvider_UDP; + else if (!RTStrICmp(ValueUnion.psz, "ipc")) + enmDebugIoProvider = GuestDebugIoProvider_IPC; + else + { + errorArgument(ModifyVM::tr("Invalid --guest-debug-io-provider '%s' (valid: none, tcp, udp, ipc)"), + ValueUnion.psz); + hrc = E_FAIL; + } + + if (SUCCEEDED(hrc)) + CHECK_ERROR(gstDbgCtrl, COMSETTER(DebugIoProvider)(enmDebugIoProvider)); + break; + } + + case MODIFYVM_GUEST_DEBUG_ADDRESS: + { + ComPtr gstDbgCtrl; + CHECK_ERROR_BREAK(sessionMachine, COMGETTER(GuestDebugControl)(gstDbgCtrl.asOutParam())); + + Bstr bstr(ValueUnion.psz); + CHECK_ERROR(gstDbgCtrl, COMSETTER(DebugAddress)(bstr.raw())); + break; + } + + case MODIFYVM_GUEST_DEBUG_PORT: + { + ComPtr gstDbgCtrl; + CHECK_ERROR_BREAK(sessionMachine, COMGETTER(GuestDebugControl)(gstDbgCtrl.asOutParam())); + CHECK_ERROR(gstDbgCtrl, COMSETTER(DebugPort)(ValueUnion.u32)); + break; + } + + default: + errorGetOpt(c, &ValueUnion); + hrc = E_FAIL; + break; + } + } + + /* commit changes */ + if (SUCCEEDED(hrc)) + CHECK_ERROR(sessionMachine, SaveSettings()); + + /* it's important to always close sessions */ + a->session->UnlockMachine(); + + return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE; +} -- cgit v1.2.3