VirtualBox

source: vbox/trunk/src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp@ 98032

Last change on this file since 98032 was 98032, checked in by vboxsync, 2 years ago

Audio/VBoxManage: Resolved a @todo: Marked the modifyvm "--audio" switch as being deprecated and introduced the switches "--audio-driver" and "--audio-enabled". This allows more flexible control of the audio stack.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 162.1 KB
Line 
1/* $Id: VBoxManageModifyVM.cpp 98032 2023-01-09 17:27:44Z vboxsync $ */
2/** @file
3 * VBoxManage - Implementation of modifyvm command.
4 */
5
6/*
7 * Copyright (C) 2006-2022 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
32#include <VBox/com/com.h>
33#include <VBox/com/array.h>
34#include <VBox/com/ErrorInfo.h>
35#include <VBox/com/errorprint.h>
36#include <VBox/com/VirtualBox.h>
37
38#include <iprt/cidr.h>
39#include <iprt/ctype.h>
40#include <iprt/file.h>
41#include <iprt/param.h>
42#include <iprt/path.h>
43#include <iprt/stream.h>
44#include <iprt/string.h>
45#include <iprt/getopt.h>
46#include <VBox/log.h>
47#include "VBoxManage.h"
48#include "VBoxManageUtils.h"
49
50DECLARE_TRANSLATION_CONTEXT(ModifyVM);
51
52using namespace com;
53/** @todo refine this after HDD changes; MSC 8.0/64 has trouble with handleModifyVM. */
54#if defined(_MSC_VER)
55# pragma optimize("g", off)
56# if _MSC_VER < RT_MSC_VER_VC120
57# pragma warning(disable:4748)
58# endif
59#endif
60
61enum
62{
63 MODIFYVM_NAME = 1000,
64 MODIFYVM_GROUPS,
65 MODIFYVM_DESCRIPTION,
66 MODIFYVM_OSTYPE,
67 MODIFYVM_ICONFILE,
68 MODIFYVM_MEMORY,
69 MODIFYVM_PAGEFUSION,
70 MODIFYVM_VRAM,
71 MODIFYVM_FIRMWARE,
72 MODIFYVM_ACPI,
73 MODIFYVM_IOAPIC,
74 MODIFYVM_PAE,
75 MODIFYVM_LONGMODE,
76 MODIFYVM_CPUID_PORTABILITY,
77 MODIFYVM_TFRESET,
78 MODIFYVM_APIC,
79 MODIFYVM_X2APIC,
80 MODIFYVM_PARAVIRTPROVIDER,
81 MODIFYVM_PARAVIRTDEBUG,
82 MODIFYVM_HWVIRTEX,
83 MODIFYVM_NESTEDPAGING,
84 MODIFYVM_LARGEPAGES,
85 MODIFYVM_VTXVPID,
86 MODIFYVM_VTXUX,
87 MODIFYVM_VIRT_VMSAVE_VMLOAD,
88 MODIFYVM_IBPB_ON_VM_EXIT,
89 MODIFYVM_IBPB_ON_VM_ENTRY,
90 MODIFYVM_SPEC_CTRL,
91 MODIFYVM_L1D_FLUSH_ON_SCHED,
92 MODIFYVM_L1D_FLUSH_ON_VM_ENTRY,
93 MODIFYVM_MDS_CLEAR_ON_SCHED,
94 MODIFYVM_MDS_CLEAR_ON_VM_ENTRY,
95 MODIFYVM_NESTED_HW_VIRT,
96 MODIFYVM_CPUS,
97 MODIFYVM_CPUHOTPLUG,
98 MODIFYVM_CPU_PROFILE,
99 MODIFYVM_PLUGCPU,
100 MODIFYVM_UNPLUGCPU,
101 MODIFYVM_SETCPUID,
102 MODIFYVM_DELCPUID,
103 MODIFYVM_DELCPUID_OLD, // legacy, different syntax from MODIFYVM_DELCPUID
104 MODIFYVM_DELALLCPUID,
105 MODIFYVM_GRAPHICSCONTROLLER,
106 MODIFYVM_MONITORCOUNT,
107 MODIFYVM_ACCELERATE3D,
108#ifdef VBOX_WITH_VIDEOHWACCEL
109 MODIFYVM_ACCELERATE2DVIDEO,
110#endif
111 MODIFYVM_BIOSLOGOFADEIN,
112 MODIFYVM_BIOSLOGOFADEOUT,
113 MODIFYVM_BIOSLOGODISPLAYTIME,
114 MODIFYVM_BIOSLOGOIMAGEPATH,
115 MODIFYVM_BIOSBOOTMENU,
116 MODIFYVM_BIOSAPIC,
117 MODIFYVM_BIOSSYSTEMTIMEOFFSET,
118 MODIFYVM_BIOSPXEDEBUG,
119 MODIFYVM_SYSTEMUUIDLE,
120 MODIFYVM_BOOT,
121 MODIFYVM_HDA, // deprecated
122 MODIFYVM_HDB, // deprecated
123 MODIFYVM_HDD, // deprecated
124 MODIFYVM_IDECONTROLLER, // deprecated
125 MODIFYVM_SATAPORTCOUNT, // deprecated
126 MODIFYVM_SATAPORT, // deprecated
127 MODIFYVM_SATA, // deprecated
128 MODIFYVM_SCSIPORT, // deprecated
129 MODIFYVM_SCSITYPE, // deprecated
130 MODIFYVM_SCSI, // deprecated
131 MODIFYVM_DVDPASSTHROUGH, // deprecated
132 MODIFYVM_DVD, // deprecated
133 MODIFYVM_FLOPPY, // deprecated
134 MODIFYVM_NICTRACEFILE,
135 MODIFYVM_NICTRACE,
136 MODIFYVM_NICPROPERTY,
137 MODIFYVM_NICTYPE,
138 MODIFYVM_NICSPEED,
139 MODIFYVM_NICBOOTPRIO,
140 MODIFYVM_NICPROMISC,
141 MODIFYVM_NICBWGROUP,
142 MODIFYVM_NIC,
143 MODIFYVM_CABLECONNECTED,
144 MODIFYVM_BRIDGEADAPTER,
145#ifdef VBOX_WITH_CLOUD_NET
146 MODIFYVM_CLOUDNET,
147#endif /* VBOX_WITH_CLOUD_NET */
148 MODIFYVM_HOSTONLYADAPTER,
149#ifdef VBOX_WITH_VMNET
150 MODIFYVM_HOSTONLYNET,
151#endif /* VBOX_WITH_VMNET */
152 MODIFYVM_INTNET,
153 MODIFYVM_GENERICDRV,
154 MODIFYVM_NATNETWORKNAME,
155 MODIFYVM_NATNET,
156 MODIFYVM_NATBINDIP,
157 MODIFYVM_NATSETTINGS,
158 MODIFYVM_NATPF,
159 MODIFYVM_NATALIASMODE,
160 MODIFYVM_NATTFTPPREFIX,
161 MODIFYVM_NATTFTPFILE,
162 MODIFYVM_NATTFTPSERVER,
163 MODIFYVM_NATDNSPASSDOMAIN,
164 MODIFYVM_NATDNSPROXY,
165 MODIFYVM_NATDNSHOSTRESOLVER,
166 MODIFYVM_NATLOCALHOSTREACHABLE,
167 MODIFYVM_MACADDRESS,
168 MODIFYVM_HIDPTR,
169 MODIFYVM_HIDKBD,
170 MODIFYVM_UARTMODE,
171 MODIFYVM_UARTTYPE,
172 MODIFYVM_UART,
173#if defined(RT_OS_LINUX) || defined(RT_OS_WINDOWS)
174 MODIFYVM_LPTMODE,
175 MODIFYVM_LPT,
176#endif
177 MODIFYVM_GUESTMEMORYBALLOON,
178 MODIFYVM_AUDIOCONTROLLER,
179 MODIFYVM_AUDIOCODEC,
180 MODIFYVM_AUDIODRIVER,
181 MODIFYVM_AUDIOENABLED,
182 MODIFYVM_AUDIO, /* Deprecated; remove in the next major version. */
183 MODIFYVM_AUDIOIN,
184 MODIFYVM_AUDIOOUT,
185#ifdef VBOX_WITH_SHARED_CLIPBOARD
186 MODIFYVM_CLIPBOARD_MODE,
187# ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
188 MODIFYVM_CLIPBOARD_FILE_TRANSFERS,
189# endif
190#endif
191 MODIFYVM_DRAGANDDROP,
192 MODIFYVM_VRDPPORT, /* VRDE: deprecated */
193 MODIFYVM_VRDPADDRESS, /* VRDE: deprecated */
194 MODIFYVM_VRDPAUTHTYPE, /* VRDE: deprecated */
195 MODIFYVM_VRDPMULTICON, /* VRDE: deprecated */
196 MODIFYVM_VRDPREUSECON, /* VRDE: deprecated */
197 MODIFYVM_VRDPVIDEOCHANNEL, /* VRDE: deprecated */
198 MODIFYVM_VRDPVIDEOCHANNELQUALITY, /* VRDE: deprecated */
199 MODIFYVM_VRDP, /* VRDE: deprecated */
200 MODIFYVM_VRDEPROPERTY,
201 MODIFYVM_VRDEPORT,
202 MODIFYVM_VRDEADDRESS,
203 MODIFYVM_VRDEAUTHTYPE,
204 MODIFYVM_VRDEAUTHLIBRARY,
205 MODIFYVM_VRDEMULTICON,
206 MODIFYVM_VRDEREUSECON,
207 MODIFYVM_VRDEVIDEOCHANNEL,
208 MODIFYVM_VRDEVIDEOCHANNELQUALITY,
209 MODIFYVM_VRDE_EXTPACK,
210 MODIFYVM_VRDE,
211 MODIFYVM_RTCUSEUTC,
212 MODIFYVM_USBRENAME,
213 MODIFYVM_USBXHCI,
214 MODIFYVM_USBEHCI,
215 MODIFYVM_USBOHCI,
216 MODIFYVM_SNAPSHOTFOLDER,
217 MODIFYVM_TELEPORTER_ENABLED,
218 MODIFYVM_TELEPORTER_PORT,
219 MODIFYVM_TELEPORTER_ADDRESS,
220 MODIFYVM_TELEPORTER_PASSWORD,
221 MODIFYVM_TELEPORTER_PASSWORD_FILE,
222 MODIFYVM_TRACING_ENABLED,
223 MODIFYVM_TRACING_CONFIG,
224 MODIFYVM_TRACING_ALLOW_VM_ACCESS,
225 MODIFYVM_HARDWARE_UUID,
226 MODIFYVM_HPET,
227 MODIFYVM_IOCACHE,
228 MODIFYVM_IOCACHESIZE,
229 MODIFYVM_CPU_EXECTUION_CAP,
230 MODIFYVM_AUTOSTART_ENABLED,
231 MODIFYVM_AUTOSTART_DELAY,
232 MODIFYVM_AUTOSTOP_TYPE,
233#ifdef VBOX_WITH_PCI_PASSTHROUGH
234 MODIFYVM_ATTACH_PCI,
235 MODIFYVM_DETACH_PCI,
236#endif
237#ifdef VBOX_WITH_USB_CARDREADER
238 MODIFYVM_USBCARDREADER,
239#endif
240#ifdef VBOX_WITH_RECORDING
241 MODIFYVM_RECORDING,
242 MODIFYVM_RECORDING_FEATURES,
243 MODIFYVM_RECORDING_SCREENS,
244 MODIFYVM_RECORDING_FILENAME,
245 MODIFYVM_RECORDING_VIDEO_WIDTH,
246 MODIFYVM_RECORDING_VIDEO_HEIGHT,
247 MODIFYVM_RECORDING_VIDEO_RES,
248 MODIFYVM_RECORDING_VIDEO_RATE,
249 MODIFYVM_RECORDING_VIDEO_FPS,
250 MODIFYVM_RECORDING_MAXTIME,
251 MODIFYVM_RECORDING_MAXSIZE,
252 MODIFYVM_RECORDING_OPTIONS,
253#endif
254 MODIFYVM_CHIPSET,
255#if defined(VBOX_WITH_IOMMU_AMD) || defined(VBOX_WITH_IOMMU_INTEL)
256 MODIFYVM_IOMMU,
257#endif
258#if defined(VBOX_WITH_TPM)
259 MODIFYVM_TPM_LOCATION,
260 MODIFYVM_TPM_TYPE,
261#endif
262 MODIFYVM_DEFAULTFRONTEND,
263 MODIFYVM_VMPROC_PRIORITY,
264 MODIFYVM_TESTING_ENABLED,
265 MODIFYVM_TESTING_MMIO,
266 MODIFYVM_TESTING_CFG_DWORD,
267 MODIFYVM_GUEST_DEBUG_PROVIDER,
268 MODIFYVM_GUEST_DEBUG_IO_PROVIDER,
269 MODIFYVM_GUEST_DEBUG_ADDRESS,
270 MODIFYVM_GUEST_DEBUG_PORT,
271};
272
273static const RTGETOPTDEF g_aModifyVMOptions[] =
274{
275 OPT1("--name", MODIFYVM_NAME, RTGETOPT_REQ_STRING),
276 OPT1("--groups", MODIFYVM_GROUPS, RTGETOPT_REQ_STRING),
277 OPT1("--description", MODIFYVM_DESCRIPTION, RTGETOPT_REQ_STRING),
278 OPT2("--os-type", "--ostype", MODIFYVM_OSTYPE, RTGETOPT_REQ_STRING),
279 OPT2("--icon-file", "--iconfile", MODIFYVM_ICONFILE, RTGETOPT_REQ_STRING),
280 OPT1("--memory", MODIFYVM_MEMORY, RTGETOPT_REQ_UINT32),
281 OPT2("--page-fusion", "--pagefusion", MODIFYVM_PAGEFUSION, RTGETOPT_REQ_BOOL_ONOFF),
282 OPT1("--vram", MODIFYVM_VRAM, RTGETOPT_REQ_UINT32),
283 OPT1("--firmware", MODIFYVM_FIRMWARE, RTGETOPT_REQ_STRING),
284 OPT1("--acpi", MODIFYVM_ACPI, RTGETOPT_REQ_BOOL_ONOFF),
285 OPT1("--ioapic", MODIFYVM_IOAPIC, RTGETOPT_REQ_BOOL_ONOFF),
286 OPT1("--pae", MODIFYVM_PAE, RTGETOPT_REQ_BOOL_ONOFF),
287 OPT2("--long-mode", "--longmode", MODIFYVM_LONGMODE, RTGETOPT_REQ_BOOL_ONOFF),
288 OPT1("--cpuid-portability-level", MODIFYVM_CPUID_PORTABILITY, RTGETOPT_REQ_UINT32),
289 OPT2("--triple-fault-reset", "--triplefaultreset", MODIFYVM_TFRESET, RTGETOPT_REQ_BOOL_ONOFF),
290 OPT1("--apic", MODIFYVM_APIC, RTGETOPT_REQ_BOOL_ONOFF),
291 OPT1("--x2apic", MODIFYVM_X2APIC, RTGETOPT_REQ_BOOL_ONOFF),
292 OPT2("--paravirt-provider", "--paravirtprovider", MODIFYVM_PARAVIRTPROVIDER, RTGETOPT_REQ_STRING),
293 OPT2("--paravirt-debug", "--paravirtdebug", MODIFYVM_PARAVIRTDEBUG, RTGETOPT_REQ_STRING),
294 OPT1("--hwvirtex", MODIFYVM_HWVIRTEX, RTGETOPT_REQ_BOOL_ONOFF),
295 OPT2("--nested-paging", "--nestedpaging", MODIFYVM_NESTEDPAGING, RTGETOPT_REQ_BOOL_ONOFF),
296 OPT2("--large-pages", "--largepages", MODIFYVM_LARGEPAGES, RTGETOPT_REQ_BOOL_ONOFF),
297 OPT2("--vtx-vpid", "--vtxvpid", MODIFYVM_VTXVPID, RTGETOPT_REQ_BOOL_ONOFF),
298 OPT2("--vtx-ux", "--vtxux", MODIFYVM_VTXUX, RTGETOPT_REQ_BOOL_ONOFF),
299 OPT1("--virt-vmsave-vmload", MODIFYVM_VIRT_VMSAVE_VMLOAD, RTGETOPT_REQ_BOOL_ONOFF),
300 OPT1("--ibpb-on-vm-exit", MODIFYVM_IBPB_ON_VM_EXIT, RTGETOPT_REQ_BOOL_ONOFF),
301 OPT1("--ibpb-on-vm-entry", MODIFYVM_IBPB_ON_VM_ENTRY, RTGETOPT_REQ_BOOL_ONOFF),
302 OPT1("--spec-ctrl", MODIFYVM_SPEC_CTRL, RTGETOPT_REQ_BOOL_ONOFF),
303 OPT1("--l1d-flush-on-sched", MODIFYVM_L1D_FLUSH_ON_SCHED, RTGETOPT_REQ_BOOL_ONOFF),
304 OPT1("--l1d-flush-on-vm-entry", MODIFYVM_L1D_FLUSH_ON_VM_ENTRY, RTGETOPT_REQ_BOOL_ONOFF),
305 OPT1("--mds-clear-on-sched", MODIFYVM_MDS_CLEAR_ON_SCHED, RTGETOPT_REQ_BOOL_ONOFF),
306 OPT1("--mds-clear-on-vm-entry", MODIFYVM_MDS_CLEAR_ON_VM_ENTRY, RTGETOPT_REQ_BOOL_ONOFF),
307 OPT1("--nested-hw-virt", MODIFYVM_NESTED_HW_VIRT, RTGETOPT_REQ_BOOL_ONOFF),
308 OPT2("--cpuid-set", "--cpuidset", MODIFYVM_SETCPUID, RTGETOPT_REQ_UINT32_OPTIONAL_PAIR | RTGETOPT_FLAG_HEX),
309 OPT1("--cpuid-remove", MODIFYVM_DELCPUID, RTGETOPT_REQ_UINT32_OPTIONAL_PAIR | RTGETOPT_FLAG_HEX),
310 OPT1("--cpuidremove", MODIFYVM_DELCPUID_OLD, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_HEX), /* legacy - syntax differs */
311 OPT2("--cpuid-remove-all", "--cpuidremoveall", MODIFYVM_DELALLCPUID, RTGETOPT_REQ_NOTHING),
312 OPT1("--cpus", MODIFYVM_CPUS, RTGETOPT_REQ_UINT32),
313 OPT2("--cpu-hotplug", "--cpuhotplug", MODIFYVM_CPUHOTPLUG, RTGETOPT_REQ_BOOL_ONOFF),
314 OPT1("--cpu-profile", MODIFYVM_CPU_PROFILE, RTGETOPT_REQ_STRING),
315 OPT2("--plug-cpu", "--plugcpu", MODIFYVM_PLUGCPU, RTGETOPT_REQ_UINT32),
316 OPT2("--unplug-cpu", "--unplugcpu", MODIFYVM_UNPLUGCPU, RTGETOPT_REQ_UINT32),
317 OPT2("--cpu-execution-cap", "--cpuexecutioncap", MODIFYVM_CPU_EXECTUION_CAP, RTGETOPT_REQ_UINT32),
318 OPT2("--rtc-use-utc", "--rtcuseutc", MODIFYVM_RTCUSEUTC, RTGETOPT_REQ_BOOL_ONOFF),
319 OPT2("--graphicscontroller", "--graphicscontroller", MODIFYVM_GRAPHICSCONTROLLER, RTGETOPT_REQ_STRING),
320 OPT2("--monitor-count", "--monitorcount", MODIFYVM_MONITORCOUNT, RTGETOPT_REQ_UINT32),
321 OPT2("--accelerate-3d", "--accelerate3d", MODIFYVM_ACCELERATE3D, RTGETOPT_REQ_BOOL_ONOFF),
322#ifdef VBOX_WITH_VIDEOHWACCEL
323 OPT2("--accelerate-2d-video", "--accelerate2dvideo", MODIFYVM_ACCELERATE2DVIDEO, RTGETOPT_REQ_BOOL_ONOFF),
324#endif
325 OPT2("--bios-logo-fade-in", "--bioslogofadein", MODIFYVM_BIOSLOGOFADEIN, RTGETOPT_REQ_BOOL_ONOFF),
326 OPT2("--bios-logo-fade-out", "--bioslogofadeout", MODIFYVM_BIOSLOGOFADEOUT, RTGETOPT_REQ_BOOL_ONOFF),
327 OPT2("--bios-logo-display-time", "--bioslogodisplaytime", MODIFYVM_BIOSLOGODISPLAYTIME, RTGETOPT_REQ_UINT32),
328 OPT2("--bios-logo-image-path", "--bioslogoimagepath", MODIFYVM_BIOSLOGOIMAGEPATH, RTGETOPT_REQ_STRING),
329 OPT2("--bios-boot-menu", "--biosbootmenu", MODIFYVM_BIOSBOOTMENU, RTGETOPT_REQ_STRING),
330 OPT2("--bios-system-time-offset", "--biossystemtimeoffset", MODIFYVM_BIOSSYSTEMTIMEOFFSET, RTGETOPT_REQ_INT64),
331 OPT2("--bios-apic", "--biosapic", MODIFYVM_BIOSAPIC, RTGETOPT_REQ_STRING),
332 OPT2("--bios-pxe-debug", "--biospxedebug", MODIFYVM_BIOSPXEDEBUG, RTGETOPT_REQ_BOOL_ONOFF),
333 OPT2("--system-uuid-le", "--system-uuid-le", MODIFYVM_SYSTEMUUIDLE, RTGETOPT_REQ_BOOL_ONOFF),
334 OPT1("--boot", MODIFYVM_BOOT, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
335 OPT1("--hda", MODIFYVM_HDA, RTGETOPT_REQ_STRING), /* deprecated */
336 OPT1("--hdb", MODIFYVM_HDB, RTGETOPT_REQ_STRING), /* deprecated */
337 OPT1("--hdd", MODIFYVM_HDD, RTGETOPT_REQ_STRING), /* deprecated */
338 OPT2("--idec-ontroller", "--idecontroller", MODIFYVM_IDECONTROLLER, RTGETOPT_REQ_STRING), /* deprecated */
339 OPT2("--sata-port-count", "--sataportcount", MODIFYVM_SATAPORTCOUNT, RTGETOPT_REQ_UINT32), /* deprecated */
340 OPT2("--sata-port", "--sataport", MODIFYVM_SATAPORT, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX), /* deprecated */
341 OPT1("--sata", MODIFYVM_SATA, RTGETOPT_REQ_STRING), /* deprecated */
342 OPT2("--scsi-port", "--scsiport", MODIFYVM_SCSIPORT, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX), /* deprecated */
343 OPT2("--scsi-type", "--scsitype", MODIFYVM_SCSITYPE, RTGETOPT_REQ_STRING), /* deprecated */
344 OPT1("--scsi", MODIFYVM_SCSI, RTGETOPT_REQ_STRING), /* deprecated */
345 OPT2("--dvd-pass-through", "--dvdpassthrough", MODIFYVM_DVDPASSTHROUGH, RTGETOPT_REQ_STRING), /* deprecated */
346 OPT1("--dvd", MODIFYVM_DVD, RTGETOPT_REQ_STRING), /* deprecated */
347 OPT1("--floppy", MODIFYVM_FLOPPY, RTGETOPT_REQ_STRING), /* deprecated */
348 OPT2("--nic-trace-file", "--nictracefile", MODIFYVM_NICTRACEFILE, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
349 OPT2("--nic-trace", "--nictrace", MODIFYVM_NICTRACE, RTGETOPT_REQ_BOOL_ONOFF | RTGETOPT_FLAG_INDEX),
350 OPT2("--nic-property", "--nicproperty", MODIFYVM_NICPROPERTY, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
351 OPT2("--nic-type", "--nictype", MODIFYVM_NICTYPE, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
352 OPT2("--nic-speed", "--nicspeed", MODIFYVM_NICSPEED, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_INDEX),
353 OPT2("--nic-boot-prio", "--nicbootprio", MODIFYVM_NICBOOTPRIO, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_INDEX),
354 OPT2("--nic-promisc", "--nicpromisc", MODIFYVM_NICPROMISC, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
355 OPT2("--nic-bandwidth-group", "--nicbandwidthgroup", MODIFYVM_NICBWGROUP, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
356 OPT1("--nic", MODIFYVM_NIC, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
357 OPT2("--cable-connected", "--cableconnected", MODIFYVM_CABLECONNECTED, RTGETOPT_REQ_BOOL_ONOFF | RTGETOPT_FLAG_INDEX),
358 OPT2("--bridge-adapter", "--bridgeadapter", MODIFYVM_BRIDGEADAPTER, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
359#ifdef VBOX_WITH_CLOUD_NET
360 OPT2("--cloud-network", "--cloudnetwork", MODIFYVM_CLOUDNET, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
361#endif /* VBOX_WITH_CLOUD_NET */
362 OPT2("--host-only-adapter", "--hostonlyadapter", MODIFYVM_HOSTONLYADAPTER, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
363#ifdef VBOX_WITH_VMNET
364 OPT2("--host-only-net", "--hostonlynet", MODIFYVM_HOSTONLYNET, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
365#endif
366 OPT1("--intnet", MODIFYVM_INTNET, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
367 OPT2("--nic-generic-drv", "--nicgenericdrv", MODIFYVM_GENERICDRV, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
368 OPT2("--nat-network", "--natnetwork", MODIFYVM_NATNETWORKNAME, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
369 OPT2("--nat-net", "--natnet", MODIFYVM_NATNET, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
370 OPT2("--nat-bind-ip", "--natbindip", MODIFYVM_NATBINDIP, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
371 OPT2("--nat-settings", "--natsettings", MODIFYVM_NATSETTINGS, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
372 OPT2("--nat-pf", "--natpf", MODIFYVM_NATPF, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
373 OPT2("--nat-alias-mode", "--nataliasmode", MODIFYVM_NATALIASMODE, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
374 OPT2("--nat-tftp-prefix", "--nattftpprefix", MODIFYVM_NATTFTPPREFIX, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
375 OPT2("--nat-tftp-file", "--nattftpfile", MODIFYVM_NATTFTPFILE, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
376 OPT2("--nat-tftp-server", "--nattftpserver", MODIFYVM_NATTFTPSERVER, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
377 OPT2("--nat-dns-pass-domain", "--natdnspassdomain", MODIFYVM_NATDNSPASSDOMAIN, RTGETOPT_REQ_BOOL_ONOFF | RTGETOPT_FLAG_INDEX),
378 OPT2("--nat-dns-proxy", "--natdnsproxy", MODIFYVM_NATDNSPROXY, RTGETOPT_REQ_BOOL_ONOFF | RTGETOPT_FLAG_INDEX),
379 OPT2("--nat-dns-host-resolver", "--natdnshostresolver", MODIFYVM_NATDNSHOSTRESOLVER, RTGETOPT_REQ_BOOL_ONOFF | RTGETOPT_FLAG_INDEX),
380 OPT2("--nat-localhostreachable", "--natlocalhostreachable", MODIFYVM_NATLOCALHOSTREACHABLE, RTGETOPT_REQ_BOOL_ONOFF | RTGETOPT_FLAG_INDEX),
381 OPT2("--mac-address", "--macaddress", MODIFYVM_MACADDRESS, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
382 OPT1("--mouse", MODIFYVM_HIDPTR, RTGETOPT_REQ_STRING),
383 OPT1("--keyboard", MODIFYVM_HIDKBD, RTGETOPT_REQ_STRING),
384 OPT2("--uart-mode", "--uartmode", MODIFYVM_UARTMODE, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
385 OPT2("--uart-type", "--uarttype", MODIFYVM_UARTTYPE, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
386 OPT1("--uart", MODIFYVM_UART, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
387#if defined(RT_OS_LINUX) || defined(RT_OS_WINDOWS)
388 OPT2("--lpt-mode", "--lptmode", MODIFYVM_LPTMODE, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
389 OPT1("--lpt", MODIFYVM_LPT, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX),
390#endif
391 OPT2("--guest-memory-balloon", "--guestmemoryballoon", MODIFYVM_GUESTMEMORYBALLOON, RTGETOPT_REQ_UINT32),
392 OPT2("--audio-controller", "--audiocontroller", MODIFYVM_AUDIOCONTROLLER, RTGETOPT_REQ_STRING),
393 OPT2("--audio-codec", "--audiocodec", MODIFYVM_AUDIOCODEC, RTGETOPT_REQ_STRING),
394 OPT1("--audio", MODIFYVM_AUDIO, RTGETOPT_REQ_STRING),
395 OPT2("--audio-driver", "--audiodriver", MODIFYVM_AUDIODRIVER, RTGETOPT_REQ_STRING),
396 OPT2("--audio-enabled", "--audioenabled", MODIFYVM_AUDIOENABLED, RTGETOPT_REQ_BOOL_ONOFF),
397 OPT2("--audio-in", "--audioin", MODIFYVM_AUDIOIN, RTGETOPT_REQ_BOOL_ONOFF),
398 OPT2("--audio-out", "--audioout", MODIFYVM_AUDIOOUT, RTGETOPT_REQ_BOOL_ONOFF),
399#ifdef VBOX_WITH_SHARED_CLIPBOARD
400 OPT1("--clipboard-mode", MODIFYVM_CLIPBOARD_MODE, RTGETOPT_REQ_STRING),
401 OPT1("--clipboard", MODIFYVM_CLIPBOARD_MODE, RTGETOPT_REQ_STRING), /* deprecated */
402# ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
403 OPT1("--clipboard-file-transfers", MODIFYVM_CLIPBOARD_FILE_TRANSFERS, RTGETOPT_REQ_STRING),
404# endif
405#endif
406 OPT2("--drag-and-drop", "--draganddrop", MODIFYVM_DRAGANDDROP, RTGETOPT_REQ_STRING),
407 OPT2("--vrdp-port", "--vrdpport", MODIFYVM_VRDPPORT, RTGETOPT_REQ_STRING), /* deprecated */
408 OPT2("--vrdp-address", "--vrdpaddress", MODIFYVM_VRDPADDRESS, RTGETOPT_REQ_STRING), /* deprecated */
409 OPT2("--vrdp-auth-type", "--vrdpauthtype", MODIFYVM_VRDPAUTHTYPE, RTGETOPT_REQ_STRING), /* deprecated */
410 OPT2("--vrdp-multi-con", "--vrdpmulticon", MODIFYVM_VRDPMULTICON, RTGETOPT_REQ_BOOL_ONOFF), /* deprecated */
411 OPT2("--vrdp-reuse-con", "--vrdpreusecon", MODIFYVM_VRDPREUSECON, RTGETOPT_REQ_BOOL_ONOFF), /* deprecated */
412 OPT2("--vrdp-video-channel", "--vrdpvideochannel", MODIFYVM_VRDPVIDEOCHANNEL, RTGETOPT_REQ_BOOL_ONOFF), /* deprecated */
413 OPT2("--vrdp-video-channel-quality", "--vrdpvideochannelquality",MODIFYVM_VRDPVIDEOCHANNELQUALITY, RTGETOPT_REQ_STRING), /* deprecated */
414 OPT1("--vrdp", MODIFYVM_VRDP, RTGETOPT_REQ_BOOL_ONOFF), /* deprecated */
415 OPT2("--vrde-property", "--vrdeproperty", MODIFYVM_VRDEPROPERTY, RTGETOPT_REQ_STRING),
416 OPT2("--vrde-port", "--vrdeport", MODIFYVM_VRDEPORT, RTGETOPT_REQ_STRING),
417 OPT2("--vrde-address", "--vrdeaddress", MODIFYVM_VRDEADDRESS, RTGETOPT_REQ_STRING),
418 OPT2("--vrde-auth-type", "--vrdeauthtype", MODIFYVM_VRDEAUTHTYPE, RTGETOPT_REQ_STRING),
419 OPT2("--vrde-auth-library", "--vrdeauthlibrary", MODIFYVM_VRDEAUTHLIBRARY, RTGETOPT_REQ_STRING),
420 OPT2("--vrde-multi-con", "--vrdemulticon", MODIFYVM_VRDEMULTICON, RTGETOPT_REQ_BOOL_ONOFF),
421 OPT2("--vrde-reuse-con", "--vrdereusecon", MODIFYVM_VRDEREUSECON, RTGETOPT_REQ_BOOL_ONOFF),
422 OPT2("--vrde-video-channel", "--vrdevideochannel", MODIFYVM_VRDEVIDEOCHANNEL, RTGETOPT_REQ_BOOL_ONOFF),
423 OPT2("--vrde-video-channel-quality", "--vrdevideochannelquality",MODIFYVM_VRDEVIDEOCHANNELQUALITY, RTGETOPT_REQ_STRING),
424 OPT2("--vrde-extpack", "--vrdeextpack", MODIFYVM_VRDE_EXTPACK, RTGETOPT_REQ_STRING),
425 OPT1("--vrde", MODIFYVM_VRDE, RTGETOPT_REQ_BOOL_ONOFF),
426 OPT2("--usb-rename", "--usbrename", MODIFYVM_USBRENAME, RTGETOPT_REQ_STRING),
427 OPT2("--usb-xhci", "--usbxhci", MODIFYVM_USBXHCI, RTGETOPT_REQ_BOOL_ONOFF),
428 OPT2("--usb-ehci", "--usbehci", MODIFYVM_USBEHCI, RTGETOPT_REQ_BOOL_ONOFF),
429 OPT2("--usb-ohci", "--usbohci", MODIFYVM_USBOHCI, RTGETOPT_REQ_BOOL_ONOFF),
430 OPT1("--usb", MODIFYVM_USBOHCI, RTGETOPT_REQ_BOOL_ONOFF), /* deprecated */
431 OPT2("--snapshot-folder", "--snapshotfolder", MODIFYVM_SNAPSHOTFOLDER, RTGETOPT_REQ_STRING),
432 OPT1("--teleporter", MODIFYVM_TELEPORTER_ENABLED, RTGETOPT_REQ_BOOL_ONOFF),
433 OPT2("--teleporter-enabled", "--teleporterenabled", MODIFYVM_TELEPORTER_ENABLED, RTGETOPT_REQ_BOOL_ONOFF), /* deprecated */
434 OPT2("--teleporter-port", "--teleporterport", MODIFYVM_TELEPORTER_PORT, RTGETOPT_REQ_UINT32),
435 OPT2("--teleporter-address", "--teleporteraddress", MODIFYVM_TELEPORTER_ADDRESS, RTGETOPT_REQ_STRING),
436 OPT2("--teleporter-password", "--teleporterpassword", MODIFYVM_TELEPORTER_PASSWORD, RTGETOPT_REQ_STRING),
437 OPT2("--teleporter-password-file", "--teleporterpasswordfile", MODIFYVM_TELEPORTER_PASSWORD_FILE, RTGETOPT_REQ_STRING),
438 OPT1("--tracing-enabled", MODIFYVM_TRACING_ENABLED, RTGETOPT_REQ_BOOL_ONOFF),
439 OPT1("--tracing-config", MODIFYVM_TRACING_CONFIG, RTGETOPT_REQ_STRING),
440 OPT1("--tracing-allow-vm-access", MODIFYVM_TRACING_ALLOW_VM_ACCESS, RTGETOPT_REQ_BOOL_ONOFF),
441 OPT2("--hardware-uuid", "--hardwareuuid", MODIFYVM_HARDWARE_UUID, RTGETOPT_REQ_STRING),
442 OPT1("--hpet", MODIFYVM_HPET, RTGETOPT_REQ_BOOL_ONOFF),
443 OPT1("--iocache", MODIFYVM_IOCACHE, RTGETOPT_REQ_BOOL_ONOFF),
444 OPT2("--iocache-size", "--iocachesize", MODIFYVM_IOCACHESIZE, RTGETOPT_REQ_UINT32),
445 OPT1("--chipset", MODIFYVM_CHIPSET, RTGETOPT_REQ_STRING),
446#if defined(VBOX_WITH_IOMMU_AMD) || defined(VBOX_WITH_IOMMU_INTEL)
447 OPT1("--iommu", MODIFYVM_IOMMU, RTGETOPT_REQ_STRING),
448#endif
449#if defined(VBOX_WITH_TPM)
450 OPT1("--tpm-type", MODIFYVM_TPM_TYPE, RTGETOPT_REQ_STRING),
451 OPT1("--tpm-location", MODIFYVM_TPM_LOCATION, RTGETOPT_REQ_STRING),
452#endif
453#ifdef VBOX_WITH_RECORDING
454 OPT1("--recording", MODIFYVM_RECORDING, RTGETOPT_REQ_BOOL_ONOFF),
455 OPT2("--recording-screens", "--recordingscreens", MODIFYVM_RECORDING_SCREENS, RTGETOPT_REQ_STRING),
456 OPT2("--recording-file", "--recordingfile", MODIFYVM_RECORDING_FILENAME, RTGETOPT_REQ_STRING),
457 OPT2("--recording-max-time", "--recordingmaxtime", MODIFYVM_RECORDING_MAXTIME, RTGETOPT_REQ_INT32),
458 OPT2("--recording-max-size", "--recordingmaxsize", MODIFYVM_RECORDING_MAXSIZE, RTGETOPT_REQ_INT32),
459 OPT2("--recording-opts", "--recordingopts", MODIFYVM_RECORDING_OPTIONS, RTGETOPT_REQ_STRING),
460 OPT2("--recording-options", "--recordingoptions", MODIFYVM_RECORDING_OPTIONS, RTGETOPT_REQ_STRING),
461 OPT2("--recording-video-res", "--recordingvideores", MODIFYVM_RECORDING_VIDEO_RES, RTGETOPT_REQ_STRING),
462 OPT2("--recording-video-resolution", "--recordingvideoresolution",MODIFYVM_RECORDING_VIDEO_RES, RTGETOPT_REQ_STRING),
463 OPT2("--recording-video-rate", "--recordingvideorate", MODIFYVM_RECORDING_VIDEO_RATE, RTGETOPT_REQ_UINT32),
464 OPT2("--recording-video-fps", "--recordingvideofps", MODIFYVM_RECORDING_VIDEO_FPS, RTGETOPT_REQ_UINT32),
465#endif
466 OPT1("--autostart-enabled", MODIFYVM_AUTOSTART_ENABLED, RTGETOPT_REQ_BOOL_ONOFF),
467 OPT1("--autostart-delay", MODIFYVM_AUTOSTART_DELAY, RTGETOPT_REQ_UINT32),
468 OPT1("--autostop-type", MODIFYVM_AUTOSTOP_TYPE, RTGETOPT_REQ_STRING),
469#ifdef VBOX_WITH_PCI_PASSTHROUGH
470 OPT2("--pci-attach", "--pciattach", MODIFYVM_ATTACH_PCI, RTGETOPT_REQ_STRING),
471 OPT2("--pci-detach", "--pcidetach", MODIFYVM_DETACH_PCI, RTGETOPT_REQ_STRING),
472#endif
473#ifdef VBOX_WITH_USB_CARDREADER
474 OPT2("--usb-card-reader", "--usbcardreader", MODIFYVM_USBCARDREADER, RTGETOPT_REQ_BOOL_ONOFF),
475#endif
476 OPT2("--default-frontend", "--defaultfrontend", MODIFYVM_DEFAULTFRONTEND, RTGETOPT_REQ_STRING),
477 OPT1("--vm-process-priority", MODIFYVM_VMPROC_PRIORITY, RTGETOPT_REQ_STRING),
478 OPT1("--testing-enabled", MODIFYVM_TESTING_ENABLED, RTGETOPT_REQ_BOOL_ONOFF),
479 OPT1("--testing-mmio", MODIFYVM_TESTING_MMIO, RTGETOPT_REQ_BOOL_ONOFF),
480 OPT1("--testing-cfg-dword", MODIFYVM_TESTING_CFG_DWORD, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_INDEX),
481 OPT1("--guest-debug-provider", MODIFYVM_GUEST_DEBUG_PROVIDER, RTGETOPT_REQ_STRING),
482 OPT1("--guest-debug-io-provider", MODIFYVM_GUEST_DEBUG_IO_PROVIDER, RTGETOPT_REQ_STRING),
483 OPT1("--guest-debug-address", MODIFYVM_GUEST_DEBUG_ADDRESS, RTGETOPT_REQ_STRING),
484 OPT1("--guest-debug-port", MODIFYVM_GUEST_DEBUG_PORT, RTGETOPT_REQ_UINT32),
485};
486
487static void vrdeWarningDeprecatedOption(const char *pszOption)
488{
489 RTStrmPrintf(g_pStdErr, ModifyVM::tr("Warning: '--vrdp%s' is deprecated. Use '--vrde%s'.\n"), pszOption, pszOption);
490}
491
492
493/**
494 * Wrapper around IMachine::SetExtraData that does the error reporting.
495 *
496 * @returns COM result code.
497 * @param rSessionMachine The IMachine.
498 * @param pszVariable The variable to set.
499 * @param pszValue The value to set. To delete pass empty string, not
500 * NULL.
501 */
502static HRESULT setExtraData(ComPtr<IMachine> &rSessionMachine, const char *pszVariable, const char *pszValue)
503{
504 HRESULT hrc = rSessionMachine->SetExtraData(Bstr(pszVariable).raw(), Bstr(pszValue).raw());
505 if (FAILED(hrc))
506 {
507 char *pszContext = RTStrAPrintf2("IMachine::SetExtraData('%s', '%s')", pszVariable, pszValue);
508 com::GlueHandleComError(rSessionMachine, pszContext, hrc, __FILE__, __LINE__);
509 RTStrFree(pszContext);
510 }
511 return hrc;
512}
513
514
515#ifdef VBOX_WITH_PCI_PASSTHROUGH
516/** Parse PCI address in format 01:02.03 and convert it to the numeric representation. */
517static int32_t parsePci(const char* szPciAddr)
518{
519 char* pszNext = (char*)szPciAddr;
520 int rc;
521 uint8_t aVals[3] = {0, 0, 0};
522
523 rc = RTStrToUInt8Ex(pszNext, &pszNext, 16, &aVals[0]);
524 if (RT_FAILURE(rc) || pszNext == NULL || *pszNext != ':')
525 return -1;
526
527 rc = RTStrToUInt8Ex(pszNext+1, &pszNext, 16, &aVals[1]);
528 if (RT_FAILURE(rc) || pszNext == NULL || *pszNext != '.')
529 return -1;
530
531 rc = RTStrToUInt8Ex(pszNext+1, &pszNext, 16, &aVals[2]);
532 if (RT_FAILURE(rc) || pszNext == NULL)
533 return -1;
534
535 return (aVals[0] << 8) | (aVals[1] << 3) | (aVals[2] << 0);
536}
537#endif
538
539void parseGroups(const char *pcszGroups, com::SafeArray<BSTR> *pGroups)
540{
541 while (pcszGroups)
542 {
543 char *pComma = RTStrStr(pcszGroups, ",");
544 if (pComma)
545 {
546 Bstr(pcszGroups, pComma - pcszGroups).detachTo(pGroups->appendedRaw());
547 pcszGroups = pComma + 1;
548 }
549 else
550 {
551 Bstr(pcszGroups).detachTo(pGroups->appendedRaw());
552 pcszGroups = NULL;
553 }
554 }
555}
556
557#ifdef VBOX_WITH_RECORDING
558int parseScreens(const char *pcszScreens, com::SafeArray<BOOL> *pScreens)
559{
560 if (!RTStrICmp(pcszScreens, "all"))
561 {
562 for (uint32_t i = 0; i < pScreens->size(); i++)
563 (*pScreens)[i] = TRUE;
564 return VINF_SUCCESS;
565 }
566 if (!RTStrICmp(pcszScreens, "none"))
567 {
568 for (uint32_t i = 0; i < pScreens->size(); i++)
569 (*pScreens)[i] = FALSE;
570 return VINF_SUCCESS;
571 }
572 while (pcszScreens && *pcszScreens)
573 {
574 char *pszNext;
575 uint32_t iScreen;
576 int rc = RTStrToUInt32Ex(pcszScreens, &pszNext, 0, &iScreen);
577 if (RT_FAILURE(rc))
578 return VERR_PARSE_ERROR;
579 if (iScreen >= pScreens->size())
580 return VERR_PARSE_ERROR;
581 if (pszNext && *pszNext)
582 {
583 pszNext = RTStrStripL(pszNext);
584 if (*pszNext != ',')
585 return VERR_PARSE_ERROR;
586 pszNext++;
587 }
588 (*pScreens)[iScreen] = true;
589 pcszScreens = pszNext;
590 }
591 return VINF_SUCCESS;
592}
593#endif
594
595static int parseNum(uint32_t uIndex, unsigned cMaxIndex, const char *pszName)
596{
597 if ( uIndex >= 1
598 && uIndex <= cMaxIndex)
599 return uIndex;
600 errorArgument(ModifyVM::tr("Invalid %s number %u"), pszName, uIndex);
601 return 0;
602}
603
604VMProcPriority_T nameToVMProcPriority(const char *pszName)
605{
606 if (!RTStrICmp(pszName, "default"))
607 return VMProcPriority_Default;
608 if (!RTStrICmp(pszName, "flat"))
609 return VMProcPriority_Flat;
610 if (!RTStrICmp(pszName, "low"))
611 return VMProcPriority_Low;
612 if (!RTStrICmp(pszName, "normal"))
613 return VMProcPriority_Normal;
614 if (!RTStrICmp(pszName, "high"))
615 return VMProcPriority_High;
616
617 return VMProcPriority_Invalid;
618}
619
620RTEXITCODE handleModifyVM(HandlerArg *a)
621{
622 int c;
623 HRESULT hrc;
624 Bstr name;
625
626 /* VM ID + at least one parameter. Parameter arguments are checked
627 * individually. */
628 if (a->argc < 2)
629 return errorSyntax(ModifyVM::tr("Not enough parameters"));
630
631 /* try to find the given sessionMachine */
632 ComPtr<IMachine> machine;
633 CHECK_ERROR_RET(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(),
634 machine.asOutParam()), RTEXITCODE_FAILURE);
635
636
637 /* Get the number of network adapters */
638 ULONG NetworkAdapterCount = getMaxNics(a->virtualBox, machine);
639
640 /* open a session for the VM */
641 CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Write), RTEXITCODE_FAILURE);
642
643 /* get the mutable session sessionMachine */
644 ComPtr<IMachine> sessionMachine;
645 CHECK_ERROR_RET(a->session, COMGETTER(Machine)(sessionMachine.asOutParam()), RTEXITCODE_FAILURE);
646
647 ComPtr<IBIOSSettings> biosSettings;
648 sessionMachine->COMGETTER(BIOSSettings)(biosSettings.asOutParam());
649
650 ComPtr<IGraphicsAdapter> pGraphicsAdapter;
651 sessionMachine->COMGETTER(GraphicsAdapter)(pGraphicsAdapter.asOutParam());
652
653 RTGETOPTSTATE GetOptState;
654 RTGetOptInit(&GetOptState, a->argc, a->argv, g_aModifyVMOptions,
655 RT_ELEMENTS(g_aModifyVMOptions), 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
656
657 RTGETOPTUNION ValueUnion;
658 while ( SUCCEEDED (hrc)
659 && (c = RTGetOpt(&GetOptState, &ValueUnion)))
660 {
661 switch (c)
662 {
663 case MODIFYVM_NAME:
664 {
665 CHECK_ERROR(sessionMachine, COMSETTER(Name)(Bstr(ValueUnion.psz).raw()));
666 break;
667 }
668 case MODIFYVM_GROUPS:
669 {
670 com::SafeArray<BSTR> groups;
671 parseGroups(ValueUnion.psz, &groups);
672 CHECK_ERROR(sessionMachine, COMSETTER(Groups)(ComSafeArrayAsInParam(groups)));
673 break;
674 }
675 case MODIFYVM_DESCRIPTION:
676 {
677 CHECK_ERROR(sessionMachine, COMSETTER(Description)(Bstr(ValueUnion.psz).raw()));
678 break;
679 }
680 case MODIFYVM_OSTYPE:
681 {
682 CHECK_ERROR(sessionMachine, COMSETTER(OSTypeId)(Bstr(ValueUnion.psz).raw()));
683 break;
684 }
685
686 case MODIFYVM_ICONFILE:
687 {
688 RTFILE iconFile;
689 int vrc = RTFileOpen(&iconFile, ValueUnion.psz, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
690 if (RT_FAILURE(vrc))
691 {
692 RTMsgError(ModifyVM::tr("Cannot open file \"%s\": %Rrc"), ValueUnion.psz, vrc);
693 hrc = E_FAIL;
694 break;
695 }
696 uint64_t cbSize;
697 vrc = RTFileQuerySize(iconFile, &cbSize);
698 if (RT_FAILURE(vrc))
699 {
700 RTMsgError(ModifyVM::tr("Cannot get size of file \"%s\": %Rrc"), ValueUnion.psz, vrc);
701 hrc = E_FAIL;
702 break;
703 }
704 if (cbSize > _256K)
705 {
706 RTMsgError(ModifyVM::tr("File \"%s\" is bigger than 256KByte"), ValueUnion.psz);
707 hrc = E_FAIL;
708 break;
709 }
710 SafeArray<BYTE> icon((size_t)cbSize);
711 hrc = RTFileRead(iconFile, icon.raw(), (size_t)cbSize, NULL);
712 if (RT_FAILURE(vrc))
713 {
714 RTMsgError(ModifyVM::tr("Cannot read contents of file \"%s\": %Rrc"), ValueUnion.psz, vrc);
715 hrc = E_FAIL;
716 break;
717 }
718 RTFileClose(iconFile);
719 CHECK_ERROR(sessionMachine, COMSETTER(Icon)(ComSafeArrayAsInParam(icon)));
720 break;
721 }
722
723 case MODIFYVM_MEMORY:
724 {
725 CHECK_ERROR(sessionMachine, COMSETTER(MemorySize)(ValueUnion.u32));
726 break;
727 }
728
729 case MODIFYVM_PAGEFUSION:
730 {
731 CHECK_ERROR(sessionMachine, COMSETTER(PageFusionEnabled)(ValueUnion.f));
732 break;
733 }
734
735 case MODIFYVM_VRAM:
736 {
737 CHECK_ERROR(pGraphicsAdapter, COMSETTER(VRAMSize)(ValueUnion.u32));
738 break;
739 }
740
741 case MODIFYVM_FIRMWARE:
742 {
743 if (!RTStrICmp(ValueUnion.psz, "efi"))
744 {
745 CHECK_ERROR(sessionMachine, COMSETTER(FirmwareType)(FirmwareType_EFI));
746 }
747 else if (!RTStrICmp(ValueUnion.psz, "efi32"))
748 {
749 CHECK_ERROR(sessionMachine, COMSETTER(FirmwareType)(FirmwareType_EFI32));
750 }
751 else if (!RTStrICmp(ValueUnion.psz, "efi64"))
752 {
753 CHECK_ERROR(sessionMachine, COMSETTER(FirmwareType)(FirmwareType_EFI64));
754 }
755 else if (!RTStrICmp(ValueUnion.psz, "efidual"))
756 {
757 CHECK_ERROR(sessionMachine, COMSETTER(FirmwareType)(FirmwareType_EFIDUAL));
758 }
759 else if (!RTStrICmp(ValueUnion.psz, "bios"))
760 {
761 CHECK_ERROR(sessionMachine, COMSETTER(FirmwareType)(FirmwareType_BIOS));
762 }
763 else
764 {
765 errorArgument(ModifyVM::tr("Invalid --firmware argument '%s'"), ValueUnion.psz);
766 hrc = E_FAIL;
767 }
768 break;
769 }
770
771 case MODIFYVM_ACPI:
772 {
773 CHECK_ERROR(biosSettings, COMSETTER(ACPIEnabled)(ValueUnion.f));
774 break;
775 }
776
777 case MODIFYVM_IOAPIC:
778 {
779 CHECK_ERROR(biosSettings, COMSETTER(IOAPICEnabled)(ValueUnion.f));
780 break;
781 }
782
783 case MODIFYVM_PAE:
784 {
785 CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_PAE, ValueUnion.f));
786 break;
787 }
788
789 case MODIFYVM_LONGMODE:
790 {
791 CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_LongMode, ValueUnion.f));
792 break;
793 }
794
795 case MODIFYVM_CPUID_PORTABILITY:
796 {
797 CHECK_ERROR(sessionMachine, COMSETTER(CPUIDPortabilityLevel)(ValueUnion.u32));
798 break;
799 }
800
801 case MODIFYVM_TFRESET:
802 {
803 CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_TripleFaultReset, ValueUnion.f));
804 break;
805 }
806
807 case MODIFYVM_APIC:
808 {
809 CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_APIC, ValueUnion.f));
810 break;
811 }
812
813 case MODIFYVM_X2APIC:
814 {
815 CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_X2APIC, ValueUnion.f));
816 break;
817 }
818
819 case MODIFYVM_PARAVIRTPROVIDER:
820 {
821 if ( !RTStrICmp(ValueUnion.psz, "none")
822 || !RTStrICmp(ValueUnion.psz, "disabled"))
823 CHECK_ERROR(sessionMachine, COMSETTER(ParavirtProvider)(ParavirtProvider_None));
824 else if (!RTStrICmp(ValueUnion.psz, "default"))
825 CHECK_ERROR(sessionMachine, COMSETTER(ParavirtProvider)(ParavirtProvider_Default));
826 else if (!RTStrICmp(ValueUnion.psz, "legacy"))
827 CHECK_ERROR(sessionMachine, COMSETTER(ParavirtProvider)(ParavirtProvider_Legacy));
828 else if (!RTStrICmp(ValueUnion.psz, "minimal"))
829 CHECK_ERROR(sessionMachine, COMSETTER(ParavirtProvider)(ParavirtProvider_Minimal));
830 else if (!RTStrICmp(ValueUnion.psz, "hyperv"))
831 CHECK_ERROR(sessionMachine, COMSETTER(ParavirtProvider)(ParavirtProvider_HyperV));
832 else if (!RTStrICmp(ValueUnion.psz, "kvm"))
833 CHECK_ERROR(sessionMachine, COMSETTER(ParavirtProvider)(ParavirtProvider_KVM));
834 else
835 {
836 errorArgument(ModifyVM::tr("Invalid --paravirtprovider argument '%s'"), ValueUnion.psz);
837 hrc = E_FAIL;
838 }
839 break;
840 }
841
842 case MODIFYVM_PARAVIRTDEBUG:
843 {
844 CHECK_ERROR(sessionMachine, COMSETTER(ParavirtDebug)(Bstr(ValueUnion.psz).raw()));
845 break;
846 }
847
848 case MODIFYVM_HWVIRTEX:
849 {
850 CHECK_ERROR(sessionMachine, SetHWVirtExProperty(HWVirtExPropertyType_Enabled, ValueUnion.f));
851 break;
852 }
853
854 case MODIFYVM_SETCPUID:
855 {
856 uint32_t const idx = c == MODIFYVM_SETCPUID ? ValueUnion.PairU32.uFirst : ValueUnion.u32;
857 uint32_t const idxSub = c == MODIFYVM_SETCPUID ? ValueUnion.PairU32.uSecond : UINT32_MAX;
858 uint32_t aValue[4];
859 for (unsigned i = 0; i < 4; i++)
860 {
861 int vrc = RTGetOptFetchValue(&GetOptState, &ValueUnion, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_HEX);
862 if (RT_FAILURE(vrc))
863 return errorSyntax(ModifyVM::tr("Missing or invalid argument to '%s'"),
864 GetOptState.pDef->pszLong);
865 aValue[i] = ValueUnion.u32;
866 }
867 CHECK_ERROR(sessionMachine, SetCPUIDLeaf(idx, idxSub, aValue[0], aValue[1], aValue[2], aValue[3]));
868 break;
869 }
870
871 case MODIFYVM_DELCPUID:
872 CHECK_ERROR(sessionMachine, RemoveCPUIDLeaf(ValueUnion.PairU32.uFirst, ValueUnion.PairU32.uSecond));
873 break;
874
875 case MODIFYVM_DELCPUID_OLD:
876 CHECK_ERROR(sessionMachine, RemoveCPUIDLeaf(ValueUnion.u32, UINT32_MAX));
877 break;
878
879 case MODIFYVM_DELALLCPUID:
880 {
881 CHECK_ERROR(sessionMachine, RemoveAllCPUIDLeaves());
882 break;
883 }
884
885 case MODIFYVM_NESTEDPAGING:
886 {
887 CHECK_ERROR(sessionMachine, SetHWVirtExProperty(HWVirtExPropertyType_NestedPaging, ValueUnion.f));
888 break;
889 }
890
891 case MODIFYVM_LARGEPAGES:
892 {
893 CHECK_ERROR(sessionMachine, SetHWVirtExProperty(HWVirtExPropertyType_LargePages, ValueUnion.f));
894 break;
895 }
896
897 case MODIFYVM_VTXVPID:
898 {
899 CHECK_ERROR(sessionMachine, SetHWVirtExProperty(HWVirtExPropertyType_VPID, ValueUnion.f));
900 break;
901 }
902
903 case MODIFYVM_VTXUX:
904 {
905 CHECK_ERROR(sessionMachine, SetHWVirtExProperty(HWVirtExPropertyType_UnrestrictedExecution, ValueUnion.f));
906 break;
907 }
908
909 case MODIFYVM_VIRT_VMSAVE_VMLOAD:
910 CHECK_ERROR(sessionMachine, SetHWVirtExProperty(HWVirtExPropertyType_VirtVmsaveVmload, ValueUnion.f));
911 break;
912
913 case MODIFYVM_IBPB_ON_VM_EXIT:
914 CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_IBPBOnVMExit, ValueUnion.f));
915 break;
916
917 case MODIFYVM_IBPB_ON_VM_ENTRY:
918 CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_IBPBOnVMEntry, ValueUnion.f));
919 break;
920
921 case MODIFYVM_SPEC_CTRL:
922 CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_SpecCtrl, ValueUnion.f));
923 break;
924
925 case MODIFYVM_L1D_FLUSH_ON_SCHED:
926 CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_L1DFlushOnEMTScheduling, ValueUnion.f));
927 break;
928
929 case MODIFYVM_L1D_FLUSH_ON_VM_ENTRY:
930 CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_L1DFlushOnVMEntry, ValueUnion.f));
931 break;
932
933 case MODIFYVM_MDS_CLEAR_ON_SCHED:
934 CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_MDSClearOnEMTScheduling, ValueUnion.f));
935 break;
936
937 case MODIFYVM_MDS_CLEAR_ON_VM_ENTRY:
938 CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_MDSClearOnVMEntry, ValueUnion.f));
939 break;
940
941 case MODIFYVM_NESTED_HW_VIRT:
942 CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_HWVirt, ValueUnion.f));
943 break;
944
945 case MODIFYVM_CPUS:
946 {
947 CHECK_ERROR(sessionMachine, COMSETTER(CPUCount)(ValueUnion.u32));
948 break;
949 }
950
951 case MODIFYVM_RTCUSEUTC:
952 {
953 CHECK_ERROR(sessionMachine, COMSETTER(RTCUseUTC)(ValueUnion.f));
954 break;
955 }
956
957 case MODIFYVM_CPUHOTPLUG:
958 {
959 CHECK_ERROR(sessionMachine, COMSETTER(CPUHotPlugEnabled)(ValueUnion.f));
960 break;
961 }
962
963 case MODIFYVM_CPU_PROFILE:
964 {
965 CHECK_ERROR(sessionMachine, COMSETTER(CPUProfile)(Bstr(ValueUnion.psz).raw()));
966 break;
967 }
968
969 case MODIFYVM_PLUGCPU:
970 {
971 CHECK_ERROR(sessionMachine, HotPlugCPU(ValueUnion.u32));
972 break;
973 }
974
975 case MODIFYVM_UNPLUGCPU:
976 {
977 CHECK_ERROR(sessionMachine, HotUnplugCPU(ValueUnion.u32));
978 break;
979 }
980
981 case MODIFYVM_CPU_EXECTUION_CAP:
982 {
983 CHECK_ERROR(sessionMachine, COMSETTER(CPUExecutionCap)(ValueUnion.u32));
984 break;
985 }
986
987 case MODIFYVM_GRAPHICSCONTROLLER:
988 {
989 if ( !RTStrICmp(ValueUnion.psz, "none")
990 || !RTStrICmp(ValueUnion.psz, "disabled"))
991 CHECK_ERROR(pGraphicsAdapter, COMSETTER(GraphicsControllerType)(GraphicsControllerType_Null));
992 else if ( !RTStrICmp(ValueUnion.psz, "vboxvga")
993 || !RTStrICmp(ValueUnion.psz, "vbox")
994 || !RTStrICmp(ValueUnion.psz, "vga")
995 || !RTStrICmp(ValueUnion.psz, "vesa"))
996 CHECK_ERROR(pGraphicsAdapter, COMSETTER(GraphicsControllerType)(GraphicsControllerType_VBoxVGA));
997#ifdef VBOX_WITH_VMSVGA
998 else if ( !RTStrICmp(ValueUnion.psz, "vmsvga")
999 || !RTStrICmp(ValueUnion.psz, "vmware"))
1000 CHECK_ERROR(pGraphicsAdapter, COMSETTER(GraphicsControllerType)(GraphicsControllerType_VMSVGA));
1001 else if ( !RTStrICmp(ValueUnion.psz, "vboxsvga")
1002 || !RTStrICmp(ValueUnion.psz, "svga"))
1003 CHECK_ERROR(pGraphicsAdapter, COMSETTER(GraphicsControllerType)(GraphicsControllerType_VBoxSVGA));
1004#endif
1005 else
1006 {
1007 errorArgument(ModifyVM::tr("Invalid --graphicscontroller argument '%s'"), ValueUnion.psz);
1008 hrc = E_FAIL;
1009 }
1010 break;
1011 }
1012
1013 case MODIFYVM_MONITORCOUNT:
1014 {
1015 CHECK_ERROR(pGraphicsAdapter, COMSETTER(MonitorCount)(ValueUnion.u32));
1016 break;
1017 }
1018
1019 case MODIFYVM_ACCELERATE3D:
1020 {
1021 CHECK_ERROR(pGraphicsAdapter, COMSETTER(Accelerate3DEnabled)(ValueUnion.f));
1022 break;
1023 }
1024
1025#ifdef VBOX_WITH_VIDEOHWACCEL
1026 case MODIFYVM_ACCELERATE2DVIDEO:
1027 {
1028 CHECK_ERROR(pGraphicsAdapter, COMSETTER(Accelerate2DVideoEnabled)(ValueUnion.f));
1029 break;
1030 }
1031#endif
1032
1033 case MODIFYVM_BIOSLOGOFADEIN:
1034 {
1035 CHECK_ERROR(biosSettings, COMSETTER(LogoFadeIn)(ValueUnion.f));
1036 break;
1037 }
1038
1039 case MODIFYVM_BIOSLOGOFADEOUT:
1040 {
1041 CHECK_ERROR(biosSettings, COMSETTER(LogoFadeOut)(ValueUnion.f));
1042 break;
1043 }
1044
1045 case MODIFYVM_BIOSLOGODISPLAYTIME:
1046 {
1047 CHECK_ERROR(biosSettings, COMSETTER(LogoDisplayTime)(ValueUnion.u32));
1048 break;
1049 }
1050
1051 case MODIFYVM_BIOSLOGOIMAGEPATH:
1052 {
1053 CHECK_ERROR(biosSettings, COMSETTER(LogoImagePath)(Bstr(ValueUnion.psz).raw()));
1054 break;
1055 }
1056
1057 case MODIFYVM_BIOSBOOTMENU:
1058 {
1059 if (!RTStrICmp(ValueUnion.psz, "disabled"))
1060 {
1061 CHECK_ERROR(biosSettings, COMSETTER(BootMenuMode)(BIOSBootMenuMode_Disabled));
1062 }
1063 else if (!RTStrICmp(ValueUnion.psz, "menuonly"))
1064 {
1065 CHECK_ERROR(biosSettings, COMSETTER(BootMenuMode)(BIOSBootMenuMode_MenuOnly));
1066 }
1067 else if (!RTStrICmp(ValueUnion.psz, "messageandmenu"))
1068 {
1069 CHECK_ERROR(biosSettings, COMSETTER(BootMenuMode)(BIOSBootMenuMode_MessageAndMenu));
1070 }
1071 else
1072 {
1073 errorArgument(ModifyVM::tr("Invalid --biosbootmenu argument '%s'"), ValueUnion.psz);
1074 hrc = E_FAIL;
1075 }
1076 break;
1077 }
1078
1079 case MODIFYVM_BIOSAPIC:
1080 {
1081 if (!RTStrICmp(ValueUnion.psz, "disabled"))
1082 {
1083 CHECK_ERROR(biosSettings, COMSETTER(APICMode)(APICMode_Disabled));
1084 }
1085 else if ( !RTStrICmp(ValueUnion.psz, "apic")
1086 || !RTStrICmp(ValueUnion.psz, "lapic")
1087 || !RTStrICmp(ValueUnion.psz, "xapic"))
1088 {
1089 CHECK_ERROR(biosSettings, COMSETTER(APICMode)(APICMode_APIC));
1090 }
1091 else if (!RTStrICmp(ValueUnion.psz, "x2apic"))
1092 {
1093 CHECK_ERROR(biosSettings, COMSETTER(APICMode)(APICMode_X2APIC));
1094 }
1095 else
1096 {
1097 errorArgument(ModifyVM::tr("Invalid --biosapic argument '%s'"), ValueUnion.psz);
1098 hrc = E_FAIL;
1099 }
1100 break;
1101 }
1102
1103 case MODIFYVM_BIOSSYSTEMTIMEOFFSET:
1104 {
1105 CHECK_ERROR(biosSettings, COMSETTER(TimeOffset)(ValueUnion.i64));
1106 break;
1107 }
1108
1109 case MODIFYVM_BIOSPXEDEBUG:
1110 {
1111 CHECK_ERROR(biosSettings, COMSETTER(PXEDebugEnabled)(ValueUnion.f));
1112 break;
1113 }
1114
1115 case MODIFYVM_SYSTEMUUIDLE:
1116 {
1117 CHECK_ERROR(biosSettings, COMSETTER(SMBIOSUuidLittleEndian)(ValueUnion.f));
1118 break;
1119 }
1120
1121 case MODIFYVM_BOOT:
1122 {
1123 if (!RTStrICmp(ValueUnion.psz, "none"))
1124 {
1125 CHECK_ERROR(sessionMachine, SetBootOrder(GetOptState.uIndex, DeviceType_Null));
1126 }
1127 else if (!RTStrICmp(ValueUnion.psz, "floppy"))
1128 {
1129 CHECK_ERROR(sessionMachine, SetBootOrder(GetOptState.uIndex, DeviceType_Floppy));
1130 }
1131 else if (!RTStrICmp(ValueUnion.psz, "dvd"))
1132 {
1133 CHECK_ERROR(sessionMachine, SetBootOrder(GetOptState.uIndex, DeviceType_DVD));
1134 }
1135 else if (!RTStrICmp(ValueUnion.psz, "disk"))
1136 {
1137 CHECK_ERROR(sessionMachine, SetBootOrder(GetOptState.uIndex, DeviceType_HardDisk));
1138 }
1139 else if (!RTStrICmp(ValueUnion.psz, "net"))
1140 {
1141 CHECK_ERROR(sessionMachine, SetBootOrder(GetOptState.uIndex, DeviceType_Network));
1142 }
1143 else
1144 return errorArgument(ModifyVM::tr("Invalid boot device '%s'"), ValueUnion.psz);
1145 break;
1146 }
1147
1148 case MODIFYVM_HDA: // deprecated
1149 case MODIFYVM_HDB: // deprecated
1150 case MODIFYVM_HDD: // deprecated
1151 case MODIFYVM_SATAPORT: // deprecated
1152 {
1153 uint32_t u1 = 0, u2 = 0;
1154 Bstr bstrController = L"IDE Controller";
1155
1156 switch (c)
1157 {
1158 case MODIFYVM_HDA: // deprecated
1159 u1 = 0;
1160 break;
1161
1162 case MODIFYVM_HDB: // deprecated
1163 u1 = 0;
1164 u2 = 1;
1165 break;
1166
1167 case MODIFYVM_HDD: // deprecated
1168 u1 = 1;
1169 u2 = 1;
1170 break;
1171
1172 case MODIFYVM_SATAPORT: // deprecated
1173 u1 = GetOptState.uIndex;
1174 bstrController = L"SATA";
1175 break;
1176 }
1177
1178 if (!RTStrICmp(ValueUnion.psz, "none"))
1179 {
1180 sessionMachine->DetachDevice(bstrController.raw(), u1, u2);
1181 }
1182 else
1183 {
1184 ComPtr<IMedium> hardDisk;
1185 hrc = openMedium(a, ValueUnion.psz, DeviceType_HardDisk,
1186 AccessMode_ReadWrite, hardDisk,
1187 false /* fForceNewUuidOnOpen */,
1188 false /* fSilent */);
1189 if (FAILED(hrc))
1190 break;
1191 if (hardDisk)
1192 {
1193 CHECK_ERROR(sessionMachine, AttachDevice(bstrController.raw(),
1194 u1, u2,
1195 DeviceType_HardDisk,
1196 hardDisk));
1197 }
1198 else
1199 hrc = E_FAIL;
1200 }
1201 break;
1202 }
1203
1204 case MODIFYVM_IDECONTROLLER: // deprecated
1205 {
1206 ComPtr<IStorageController> storageController;
1207 CHECK_ERROR(sessionMachine, GetStorageControllerByName(Bstr("IDE Controller").raw(),
1208 storageController.asOutParam()));
1209
1210 if (!RTStrICmp(ValueUnion.psz, "PIIX3"))
1211 {
1212 CHECK_ERROR(storageController, COMSETTER(ControllerType)(StorageControllerType_PIIX3));
1213 }
1214 else if (!RTStrICmp(ValueUnion.psz, "PIIX4"))
1215 {
1216 CHECK_ERROR(storageController, COMSETTER(ControllerType)(StorageControllerType_PIIX4));
1217 }
1218 else if (!RTStrICmp(ValueUnion.psz, "ICH6"))
1219 {
1220 CHECK_ERROR(storageController, COMSETTER(ControllerType)(StorageControllerType_ICH6));
1221 }
1222 else
1223 {
1224 errorArgument(ModifyVM::tr("Invalid --idecontroller argument '%s'"), ValueUnion.psz);
1225 hrc = E_FAIL;
1226 }
1227 break;
1228 }
1229
1230 case MODIFYVM_SATAPORTCOUNT: // deprecated
1231 {
1232 ComPtr<IStorageController> SataCtl;
1233 CHECK_ERROR(sessionMachine, GetStorageControllerByName(Bstr("SATA").raw(),
1234 SataCtl.asOutParam()));
1235
1236 if (SUCCEEDED(hrc) && ValueUnion.u32 > 0)
1237 CHECK_ERROR(SataCtl, COMSETTER(PortCount)(ValueUnion.u32));
1238 break;
1239 }
1240
1241 case MODIFYVM_SATA: // deprecated
1242 {
1243 if (!RTStrICmp(ValueUnion.psz, "on") || !RTStrICmp(ValueUnion.psz, "enable"))
1244 {
1245 ComPtr<IStorageController> ctl;
1246 CHECK_ERROR(sessionMachine, AddStorageController(Bstr("SATA").raw(),
1247 StorageBus_SATA,
1248 ctl.asOutParam()));
1249 CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_IntelAhci));
1250 }
1251 else if (!RTStrICmp(ValueUnion.psz, "off") || !RTStrICmp(ValueUnion.psz, "disable"))
1252 CHECK_ERROR(sessionMachine, RemoveStorageController(Bstr("SATA").raw()));
1253 else
1254 return errorArgument(ModifyVM::tr("Invalid --usb argument '%s'"), ValueUnion.psz);
1255 break;
1256 }
1257
1258 case MODIFYVM_SCSIPORT: // deprecated
1259 {
1260 if (!RTStrICmp(ValueUnion.psz, "none"))
1261 {
1262 hrc = sessionMachine->DetachDevice(Bstr("LsiLogic").raw(),
1263 GetOptState.uIndex, 0);
1264 if (FAILED(hrc))
1265 CHECK_ERROR(sessionMachine, DetachDevice(Bstr("BusLogic").raw(),
1266 GetOptState.uIndex, 0));
1267 }
1268 else
1269 {
1270 ComPtr<IMedium> hardDisk;
1271 hrc = openMedium(a, ValueUnion.psz, DeviceType_HardDisk,
1272 AccessMode_ReadWrite, hardDisk,
1273 false /* fForceNewUuidOnOpen */,
1274 false /* fSilent */);
1275 if (FAILED(hrc))
1276 break;
1277 if (hardDisk)
1278 {
1279 hrc = sessionMachine->AttachDevice(Bstr("LsiLogic").raw(),
1280 GetOptState.uIndex, 0,
1281 DeviceType_HardDisk,
1282 hardDisk);
1283 if (FAILED(hrc))
1284 CHECK_ERROR(sessionMachine,
1285 AttachDevice(Bstr("BusLogic").raw(),
1286 GetOptState.uIndex, 0,
1287 DeviceType_HardDisk,
1288 hardDisk));
1289 }
1290 else
1291 hrc = E_FAIL;
1292 }
1293 break;
1294 }
1295
1296 case MODIFYVM_SCSITYPE: // deprecated
1297 {
1298 ComPtr<IStorageController> ctl;
1299
1300 if (!RTStrICmp(ValueUnion.psz, "LsiLogic"))
1301 {
1302 hrc = sessionMachine->RemoveStorageController(Bstr("BusLogic").raw());
1303 if (FAILED(hrc))
1304 CHECK_ERROR(sessionMachine, RemoveStorageController(Bstr("LsiLogic").raw()));
1305
1306 CHECK_ERROR(sessionMachine,
1307 AddStorageController(Bstr("LsiLogic").raw(),
1308 StorageBus_SCSI,
1309 ctl.asOutParam()));
1310
1311 if (SUCCEEDED(hrc))
1312 CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_LsiLogic));
1313 }
1314 else if (!RTStrICmp(ValueUnion.psz, "BusLogic"))
1315 {
1316 hrc = sessionMachine->RemoveStorageController(Bstr("LsiLogic").raw());
1317 if (FAILED(hrc))
1318 CHECK_ERROR(sessionMachine, RemoveStorageController(Bstr("BusLogic").raw()));
1319
1320 CHECK_ERROR(sessionMachine,
1321 AddStorageController(Bstr("BusLogic").raw(),
1322 StorageBus_SCSI,
1323 ctl.asOutParam()));
1324
1325 if (SUCCEEDED(hrc))
1326 CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_BusLogic));
1327 }
1328 else
1329 return errorArgument(ModifyVM::tr("Invalid --scsitype argument '%s'"), ValueUnion.psz);
1330 break;
1331 }
1332
1333 case MODIFYVM_SCSI: // deprecated
1334 {
1335 if (!RTStrICmp(ValueUnion.psz, "on") || !RTStrICmp(ValueUnion.psz, "enable"))
1336 {
1337 ComPtr<IStorageController> ctl;
1338
1339 CHECK_ERROR(sessionMachine, AddStorageController(Bstr("BusLogic").raw(),
1340 StorageBus_SCSI,
1341 ctl.asOutParam()));
1342 if (SUCCEEDED(hrc))
1343 CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_BusLogic));
1344 }
1345 else if (!RTStrICmp(ValueUnion.psz, "off") || !RTStrICmp(ValueUnion.psz, "disable"))
1346 {
1347 hrc = sessionMachine->RemoveStorageController(Bstr("BusLogic").raw());
1348 if (FAILED(hrc))
1349 CHECK_ERROR(sessionMachine, RemoveStorageController(Bstr("LsiLogic").raw()));
1350 }
1351 break;
1352 }
1353
1354 case MODIFYVM_DVDPASSTHROUGH: // deprecated
1355 {
1356 CHECK_ERROR(sessionMachine, PassthroughDevice(Bstr("IDE Controller").raw(),
1357 1, 0,
1358 !RTStrICmp(ValueUnion.psz, "on")));
1359 break;
1360 }
1361
1362 case MODIFYVM_DVD: // deprecated
1363 {
1364 ComPtr<IMedium> dvdMedium;
1365
1366 /* unmount? */
1367 if (!RTStrICmp(ValueUnion.psz, "none"))
1368 {
1369 /* nothing to do, NULL object will cause unmount */
1370 }
1371 /* host drive? */
1372 else if (!RTStrNICmp(ValueUnion.psz, RT_STR_TUPLE("host:")))
1373 {
1374 ComPtr<IHost> host;
1375 CHECK_ERROR(a->virtualBox, COMGETTER(Host)(host.asOutParam()));
1376 hrc = host->FindHostDVDDrive(Bstr(ValueUnion.psz + 5).raw(),
1377 dvdMedium.asOutParam());
1378 if (!dvdMedium)
1379 {
1380 /* 2nd try: try with the real name, important on Linux+libhal */
1381 char szPathReal[RTPATH_MAX];
1382 if (RT_FAILURE(RTPathReal(ValueUnion.psz + 5, szPathReal, sizeof(szPathReal))))
1383 {
1384 errorArgument(ModifyVM::tr("Invalid host DVD drive name \"%s\""), ValueUnion.psz + 5);
1385 hrc = E_FAIL;
1386 break;
1387 }
1388 hrc = host->FindHostDVDDrive(Bstr(szPathReal).raw(),
1389 dvdMedium.asOutParam());
1390 if (!dvdMedium)
1391 {
1392 errorArgument(ModifyVM::tr("Invalid host DVD drive name \"%s\""), ValueUnion.psz + 5);
1393 hrc = E_FAIL;
1394 break;
1395 }
1396 }
1397 }
1398 else
1399 {
1400 hrc = openMedium(a, ValueUnion.psz, DeviceType_DVD,
1401 AccessMode_ReadOnly, dvdMedium,
1402 false /* fForceNewUuidOnOpen */,
1403 false /* fSilent */);
1404 if (FAILED(hrc))
1405 break;
1406 if (!dvdMedium)
1407 {
1408 hrc = E_FAIL;
1409 break;
1410 }
1411 }
1412
1413 CHECK_ERROR(sessionMachine, MountMedium(Bstr("IDE Controller").raw(),
1414 1, 0,
1415 dvdMedium,
1416 FALSE /* aForce */));
1417 break;
1418 }
1419
1420 case MODIFYVM_FLOPPY: // deprecated
1421 {
1422 ComPtr<IMedium> floppyMedium;
1423 ComPtr<IMediumAttachment> floppyAttachment;
1424 sessionMachine->GetMediumAttachment(Bstr("Floppy Controller").raw(),
1425 0, 0, floppyAttachment.asOutParam());
1426
1427 /* disable? */
1428 if (!RTStrICmp(ValueUnion.psz, "disabled"))
1429 {
1430 /* disable the controller */
1431 if (floppyAttachment)
1432 CHECK_ERROR(sessionMachine, DetachDevice(Bstr("Floppy Controller").raw(),
1433 0, 0));
1434 }
1435 else
1436 {
1437 /* enable the controller */
1438 if (!floppyAttachment)
1439 CHECK_ERROR(sessionMachine, AttachDeviceWithoutMedium(Bstr("Floppy Controller").raw(),
1440 0, 0,
1441 DeviceType_Floppy));
1442
1443 /* unmount? */
1444 if ( !RTStrICmp(ValueUnion.psz, "none")
1445 || !RTStrICmp(ValueUnion.psz, "empty")) // deprecated
1446 {
1447 /* nothing to do, NULL object will cause unmount */
1448 }
1449 /* host drive? */
1450 else if (!RTStrNICmp(ValueUnion.psz, RT_STR_TUPLE("host:")))
1451 {
1452 ComPtr<IHost> host;
1453 CHECK_ERROR(a->virtualBox, COMGETTER(Host)(host.asOutParam()));
1454 hrc = host->FindHostFloppyDrive(Bstr(ValueUnion.psz + 5).raw(),
1455 floppyMedium.asOutParam());
1456 if (!floppyMedium)
1457 {
1458 errorArgument(ModifyVM::tr("Invalid host floppy drive name \"%s\""), ValueUnion.psz + 5);
1459 hrc = E_FAIL;
1460 break;
1461 }
1462 }
1463 else
1464 {
1465 hrc = openMedium(a, ValueUnion.psz, DeviceType_Floppy,
1466 AccessMode_ReadWrite, floppyMedium,
1467 false /* fForceNewUuidOnOpen */,
1468 false /* fSilent */);
1469 if (FAILED(hrc))
1470 break;
1471 if (!floppyMedium)
1472 {
1473 hrc = E_FAIL;
1474 break;
1475 }
1476 }
1477 CHECK_ERROR(sessionMachine, MountMedium(Bstr("Floppy Controller").raw(),
1478 0, 0,
1479 floppyMedium,
1480 FALSE /* aForce */));
1481 }
1482 break;
1483 }
1484
1485 case MODIFYVM_NICTRACEFILE:
1486 {
1487
1488 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1489 break;
1490
1491 ComPtr<INetworkAdapter> nic;
1492 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1493 ASSERT(nic);
1494
1495 CHECK_ERROR(nic, COMSETTER(TraceFile)(Bstr(ValueUnion.psz).raw()));
1496 break;
1497 }
1498
1499 case MODIFYVM_NICTRACE:
1500 {
1501 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1502 break;
1503
1504 ComPtr<INetworkAdapter> nic;
1505 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1506 ASSERT(nic);
1507
1508 CHECK_ERROR(nic, COMSETTER(TraceEnabled)(ValueUnion.f));
1509 break;
1510 }
1511
1512 case MODIFYVM_NICPROPERTY:
1513 {
1514 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1515 break;
1516
1517 ComPtr<INetworkAdapter> nic;
1518 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1519 ASSERT(nic);
1520
1521 if (nic)
1522 {
1523 /* Parse 'name=value' */
1524 char *pszProperty = RTStrDup(ValueUnion.psz);
1525 if (pszProperty)
1526 {
1527 char *pDelimiter = strchr(pszProperty, '=');
1528 if (pDelimiter)
1529 {
1530 *pDelimiter = '\0';
1531
1532 Bstr bstrName = pszProperty;
1533 Bstr bstrValue = &pDelimiter[1];
1534 CHECK_ERROR(nic, SetProperty(bstrName.raw(), bstrValue.raw()));
1535 }
1536 else
1537 {
1538 errorArgument(ModifyVM::tr("Invalid --nicproperty%d argument '%s'"), GetOptState.uIndex, ValueUnion.psz);
1539 hrc = E_FAIL;
1540 }
1541 RTStrFree(pszProperty);
1542 }
1543 else
1544 {
1545 RTStrmPrintf(g_pStdErr, ModifyVM::tr("Error: Failed to allocate memory for --nicproperty%d '%s'\n"),
1546 GetOptState.uIndex, ValueUnion.psz);
1547 hrc = E_FAIL;
1548 }
1549 }
1550 break;
1551 }
1552 case MODIFYVM_NICTYPE:
1553 {
1554 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1555 break;
1556
1557 ComPtr<INetworkAdapter> nic;
1558 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1559 ASSERT(nic);
1560
1561 if (!RTStrICmp(ValueUnion.psz, "Am79C970A"))
1562 {
1563 CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_Am79C970A));
1564 }
1565 else if (!RTStrICmp(ValueUnion.psz, "Am79C973"))
1566 {
1567 CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_Am79C973));
1568 }
1569 else if (!RTStrICmp(ValueUnion.psz, "Am79C960"))
1570 {
1571 CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_Am79C960));
1572 }
1573#ifdef VBOX_WITH_E1000
1574 else if (!RTStrICmp(ValueUnion.psz, "82540EM"))
1575 {
1576 CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_I82540EM));
1577 }
1578 else if (!RTStrICmp(ValueUnion.psz, "82543GC"))
1579 {
1580 CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_I82543GC));
1581 }
1582 else if (!RTStrICmp(ValueUnion.psz, "82545EM"))
1583 {
1584 CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_I82545EM));
1585 }
1586#endif
1587#ifdef VBOX_WITH_VIRTIO
1588 else if (!RTStrICmp(ValueUnion.psz, "virtio"))
1589 {
1590 CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_Virtio));
1591 }
1592#endif /* VBOX_WITH_VIRTIO */
1593 else if (!RTStrICmp(ValueUnion.psz, "NE1000"))
1594 {
1595 CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_NE1000));
1596 }
1597 else if (!RTStrICmp(ValueUnion.psz, "NE2000"))
1598 {
1599 CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_NE2000));
1600 }
1601 else if (!RTStrICmp(ValueUnion.psz, "WD8003"))
1602 {
1603 CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_WD8003));
1604 }
1605 else if (!RTStrICmp(ValueUnion.psz, "WD8013"))
1606 {
1607 CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_WD8013));
1608 }
1609 else if (!RTStrICmp(ValueUnion.psz, "3C503"))
1610 {
1611 CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_ELNK2));
1612 }
1613 else if (!RTStrICmp(ValueUnion.psz, "3C501"))
1614 {
1615 CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_ELNK1));
1616 }
1617 else
1618 {
1619 errorArgument(ModifyVM::tr("Invalid NIC type '%s' specified for NIC %u"),
1620 ValueUnion.psz, GetOptState.uIndex);
1621 hrc = E_FAIL;
1622 }
1623 break;
1624 }
1625
1626 case MODIFYVM_NICSPEED:
1627 {
1628 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1629 break;
1630
1631 ComPtr<INetworkAdapter> nic;
1632 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1633 ASSERT(nic);
1634
1635 CHECK_ERROR(nic, COMSETTER(LineSpeed)(ValueUnion.u32));
1636 break;
1637 }
1638
1639 case MODIFYVM_NICBOOTPRIO:
1640 {
1641 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1642 break;
1643
1644 ComPtr<INetworkAdapter> nic;
1645 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1646 ASSERT(nic);
1647
1648 /* Somewhat arbitrary limitation - we can pass a list of up to 4 PCI devices
1649 * to the PXE ROM, hence only boot priorities 1-4 are allowed (in addition to
1650 * 0 for the default lowest priority).
1651 */
1652 if (ValueUnion.u32 > 4)
1653 {
1654 errorArgument(ModifyVM::tr("Invalid boot priority '%u' specfied for NIC %u"), ValueUnion.u32, GetOptState.uIndex);
1655 hrc = E_FAIL;
1656 }
1657 else
1658 {
1659 CHECK_ERROR(nic, COMSETTER(BootPriority)(ValueUnion.u32));
1660 }
1661 break;
1662 }
1663
1664 case MODIFYVM_NICPROMISC:
1665 {
1666 NetworkAdapterPromiscModePolicy_T enmPromiscModePolicy;
1667 if (!RTStrICmp(ValueUnion.psz, "deny"))
1668 enmPromiscModePolicy = NetworkAdapterPromiscModePolicy_Deny;
1669 else if ( !RTStrICmp(ValueUnion.psz, "allow-vms")
1670 || !RTStrICmp(ValueUnion.psz, "allow-network"))
1671 enmPromiscModePolicy = NetworkAdapterPromiscModePolicy_AllowNetwork;
1672 else if (!RTStrICmp(ValueUnion.psz, "allow-all"))
1673 enmPromiscModePolicy = NetworkAdapterPromiscModePolicy_AllowAll;
1674 else
1675 {
1676 errorArgument(ModifyVM::tr("Unknown promiscuous mode policy '%s'"), ValueUnion.psz);
1677 hrc = E_INVALIDARG;
1678 break;
1679 }
1680
1681 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1682 break;
1683
1684 ComPtr<INetworkAdapter> nic;
1685 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1686 ASSERT(nic);
1687
1688 CHECK_ERROR(nic, COMSETTER(PromiscModePolicy)(enmPromiscModePolicy));
1689 break;
1690 }
1691
1692 case MODIFYVM_NICBWGROUP:
1693 {
1694 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1695 break;
1696
1697 ComPtr<INetworkAdapter> nic;
1698 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1699 ASSERT(nic);
1700
1701 if (!RTStrICmp(ValueUnion.psz, "none"))
1702 {
1703 /* Just remove the bandwidth group. */
1704 CHECK_ERROR(nic, COMSETTER(BandwidthGroup)(NULL));
1705 }
1706 else
1707 {
1708 ComPtr<IBandwidthControl> bwCtrl;
1709 ComPtr<IBandwidthGroup> bwGroup;
1710
1711 CHECK_ERROR(sessionMachine, COMGETTER(BandwidthControl)(bwCtrl.asOutParam()));
1712
1713 if (SUCCEEDED(hrc))
1714 {
1715 CHECK_ERROR(bwCtrl, GetBandwidthGroup(Bstr(ValueUnion.psz).raw(), bwGroup.asOutParam()));
1716 if (SUCCEEDED(hrc))
1717 {
1718 CHECK_ERROR(nic, COMSETTER(BandwidthGroup)(bwGroup));
1719 }
1720 }
1721 }
1722 break;
1723 }
1724
1725 case MODIFYVM_NIC:
1726 {
1727 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1728 break;
1729
1730 ComPtr<INetworkAdapter> nic;
1731 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1732 ASSERT(nic);
1733
1734 /*
1735 * Check if the NIC is already enabled. Do not try to
1736 * enable it if it already is. That makes a
1737 * difference for saved VMs for which you can change
1738 * the NIC attachment, but can't change the NIC
1739 * enabled status (yes, the setter also should not
1740 * freak out about a no-op request).
1741 */
1742 BOOL fEnabled;;
1743 CHECK_ERROR(nic, COMGETTER(Enabled)(&fEnabled));
1744
1745 if (!RTStrICmp(ValueUnion.psz, "none"))
1746 {
1747 if (RT_BOOL(fEnabled))
1748 CHECK_ERROR(nic, COMSETTER(Enabled)(FALSE));
1749 }
1750 else if (!RTStrICmp(ValueUnion.psz, "null"))
1751 {
1752 if (!fEnabled)
1753 CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE));
1754 CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_Null));
1755 }
1756 else if (!RTStrICmp(ValueUnion.psz, "nat"))
1757 {
1758 if (!fEnabled)
1759 CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE));
1760 CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_NAT));
1761 }
1762 else if ( !RTStrICmp(ValueUnion.psz, "bridged")
1763 || !RTStrICmp(ValueUnion.psz, "hostif")) /* backward compatibility */
1764 {
1765 if (!fEnabled)
1766 CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE));
1767 CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_Bridged));
1768 }
1769 else if (!RTStrICmp(ValueUnion.psz, "intnet"))
1770 {
1771 if (!fEnabled)
1772 CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE));
1773 CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_Internal));
1774 }
1775 else if (!RTStrICmp(ValueUnion.psz, "hostonly"))
1776 {
1777 if (!fEnabled)
1778 CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE));
1779 CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_HostOnly));
1780 }
1781#ifdef VBOX_WITH_VMNET
1782 else if (!RTStrICmp(ValueUnion.psz, "hostonlynet"))
1783 {
1784 if (!fEnabled)
1785 CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE));
1786 CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_HostOnlyNetwork));
1787 }
1788#endif /* VBOX_WITH_VMNET */
1789 else if (!RTStrICmp(ValueUnion.psz, "generic"))
1790 {
1791 if (!fEnabled)
1792 CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE));
1793 CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_Generic));
1794 }
1795 else if (!RTStrICmp(ValueUnion.psz, "natnetwork"))
1796 {
1797 if (!fEnabled)
1798 CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE));
1799 CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_NATNetwork));
1800 }
1801#ifdef VBOX_WITH_CLOUD_NET
1802 else if (!RTStrICmp(ValueUnion.psz, "cloud"))
1803 {
1804 if (!fEnabled)
1805 CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE));
1806 CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_Cloud));
1807 }
1808#endif /* VBOX_WITH_CLOUD_NET */
1809 else
1810 {
1811 errorArgument(ModifyVM::tr("Invalid type '%s' specfied for NIC %u"), ValueUnion.psz, GetOptState.uIndex);
1812 hrc = E_FAIL;
1813 }
1814 break;
1815 }
1816
1817 case MODIFYVM_CABLECONNECTED:
1818 {
1819 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1820 break;
1821
1822 ComPtr<INetworkAdapter> nic;
1823 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1824 ASSERT(nic);
1825
1826 CHECK_ERROR(nic, COMSETTER(CableConnected)(ValueUnion.f));
1827 break;
1828 }
1829
1830 case MODIFYVM_BRIDGEADAPTER:
1831 {
1832 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1833 break;
1834
1835 ComPtr<INetworkAdapter> nic;
1836 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1837 ASSERT(nic);
1838
1839 /* remove it? */
1840 if (!RTStrICmp(ValueUnion.psz, "none"))
1841 {
1842 CHECK_ERROR(nic, COMSETTER(BridgedInterface)(Bstr().raw()));
1843 }
1844 else
1845 {
1846 CHECK_ERROR(nic, COMSETTER(BridgedInterface)(Bstr(ValueUnion.psz).raw()));
1847 verifyHostNetworkInterfaceName(a->virtualBox, ValueUnion.psz,
1848 HostNetworkInterfaceType_Bridged);
1849 }
1850 break;
1851 }
1852
1853#ifdef VBOX_WITH_CLOUD_NET
1854 case MODIFYVM_CLOUDNET:
1855 {
1856 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1857 break;
1858
1859 ComPtr<INetworkAdapter> nic;
1860 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1861 ASSERT(nic);
1862
1863 /* remove it? */
1864 if (!RTStrICmp(ValueUnion.psz, "none"))
1865 {
1866 CHECK_ERROR(nic, COMSETTER(CloudNetwork)(Bstr().raw()));
1867 }
1868 else
1869 {
1870 CHECK_ERROR(nic, COMSETTER(CloudNetwork)(Bstr(ValueUnion.psz).raw()));
1871 }
1872 break;
1873 }
1874#endif /* VBOX_WITH_CLOUD_NET */
1875
1876 case MODIFYVM_HOSTONLYADAPTER:
1877 {
1878 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1879 break;
1880
1881 ComPtr<INetworkAdapter> nic;
1882 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1883 ASSERT(nic);
1884
1885 /* remove it? */
1886 if (!RTStrICmp(ValueUnion.psz, "none"))
1887 {
1888 CHECK_ERROR(nic, COMSETTER(HostOnlyInterface)(Bstr().raw()));
1889 }
1890 else
1891 {
1892 CHECK_ERROR(nic, COMSETTER(HostOnlyInterface)(Bstr(ValueUnion.psz).raw()));
1893 verifyHostNetworkInterfaceName(a->virtualBox, ValueUnion.psz,
1894 HostNetworkInterfaceType_HostOnly);
1895 }
1896 break;
1897 }
1898
1899#ifdef VBOX_WITH_VMNET
1900 case MODIFYVM_HOSTONLYNET:
1901 {
1902 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1903 break;
1904
1905 ComPtr<INetworkAdapter> nic;
1906 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1907 ASSERT(nic);
1908
1909 /* remove it? */
1910 if (!RTStrICmp(ValueUnion.psz, "none"))
1911 {
1912 CHECK_ERROR(nic, COMSETTER(HostOnlyNetwork)(Bstr().raw()));
1913 }
1914 else
1915 {
1916 CHECK_ERROR(nic, COMSETTER(HostOnlyNetwork)(Bstr(ValueUnion.psz).raw()));
1917 }
1918 break;
1919 }
1920#endif /* VBOX_WITH_VMNET */
1921
1922 case MODIFYVM_INTNET:
1923 {
1924 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1925 break;
1926
1927 ComPtr<INetworkAdapter> nic;
1928 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1929 ASSERT(nic);
1930
1931 /* remove it? */
1932 if (!RTStrICmp(ValueUnion.psz, "none"))
1933 {
1934 CHECK_ERROR(nic, COMSETTER(InternalNetwork)(Bstr().raw()));
1935 }
1936 else
1937 {
1938 CHECK_ERROR(nic, COMSETTER(InternalNetwork)(Bstr(ValueUnion.psz).raw()));
1939 }
1940 break;
1941 }
1942
1943 case MODIFYVM_GENERICDRV:
1944 {
1945 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1946 break;
1947
1948 ComPtr<INetworkAdapter> nic;
1949 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1950 ASSERT(nic);
1951
1952 CHECK_ERROR(nic, COMSETTER(GenericDriver)(Bstr(ValueUnion.psz).raw()));
1953 break;
1954 }
1955
1956 case MODIFYVM_NATNETWORKNAME:
1957 {
1958 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1959 break;
1960
1961 ComPtr<INetworkAdapter> nic;
1962 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1963 ASSERT(nic);
1964
1965 CHECK_ERROR(nic, COMSETTER(NATNetwork)(Bstr(ValueUnion.psz).raw()));
1966 break;
1967 }
1968
1969 case MODIFYVM_NATNET:
1970 {
1971 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1972 break;
1973
1974 ComPtr<INetworkAdapter> nic;
1975 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1976 ASSERT(nic);
1977
1978 ComPtr<INATEngine> engine;
1979 CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
1980
1981 const char *psz = ValueUnion.psz;
1982 if (!RTStrICmp("default", psz))
1983 psz = "";
1984
1985 CHECK_ERROR(engine, COMSETTER(Network)(Bstr(psz).raw()));
1986 break;
1987 }
1988
1989 case MODIFYVM_NATBINDIP:
1990 {
1991 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1992 break;
1993
1994 ComPtr<INetworkAdapter> nic;
1995 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1996 ASSERT(nic);
1997
1998 ComPtr<INATEngine> engine;
1999 CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
2000
2001 CHECK_ERROR(engine, COMSETTER(HostIP)(Bstr(ValueUnion.psz).raw()));
2002 break;
2003 }
2004
2005#define ITERATE_TO_NEXT_TERM(ch) \
2006 do { \
2007 while (*ch != ',') \
2008 { \
2009 if (*ch == 0) \
2010 { \
2011 return errorSyntax(ModifyVM::tr("Missing or invalid argument to '%s'"), \
2012 GetOptState.pDef->pszLong); \
2013 } \
2014 ch++; \
2015 } \
2016 *ch = '\0'; \
2017 ch++; \
2018 } while(0)
2019
2020 case MODIFYVM_NATSETTINGS:
2021 {
2022 ComPtr<INetworkAdapter> nic;
2023 ComPtr<INATEngine> engine;
2024 char *strMtu;
2025 char *strSockSnd;
2026 char *strSockRcv;
2027 char *strTcpSnd;
2028 char *strTcpRcv;
2029 char *strRaw = RTStrDup(ValueUnion.psz);
2030 char *ch = strRaw;
2031 strMtu = RTStrStrip(ch);
2032 ITERATE_TO_NEXT_TERM(ch);
2033 strSockSnd = RTStrStrip(ch);
2034 ITERATE_TO_NEXT_TERM(ch);
2035 strSockRcv = RTStrStrip(ch);
2036 ITERATE_TO_NEXT_TERM(ch);
2037 strTcpSnd = RTStrStrip(ch);
2038 ITERATE_TO_NEXT_TERM(ch);
2039 strTcpRcv = RTStrStrip(ch);
2040
2041 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
2042 break;
2043
2044 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
2045 ASSERT(nic);
2046
2047 CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
2048 CHECK_ERROR(engine, SetNetworkSettings(RTStrToUInt32(strMtu), RTStrToUInt32(strSockSnd), RTStrToUInt32(strSockRcv),
2049 RTStrToUInt32(strTcpSnd), RTStrToUInt32(strTcpRcv)));
2050 break;
2051 }
2052
2053
2054 case MODIFYVM_NATPF:
2055 {
2056 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
2057 break;
2058
2059 ComPtr<INetworkAdapter> nic;
2060 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
2061 ASSERT(nic);
2062
2063 ComPtr<INATEngine> engine;
2064 CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
2065
2066 /* format name:proto:hostip:hostport:guestip:guestport*/
2067 if (RTStrCmp(ValueUnion.psz, "delete") != 0)
2068 {
2069 char *strName;
2070 char *strProto;
2071 char *strHostIp;
2072 char *strHostPort;
2073 char *strGuestIp;
2074 char *strGuestPort;
2075 char *strRaw = RTStrDup(ValueUnion.psz);
2076 char *ch = strRaw;
2077 strName = RTStrStrip(ch);
2078 ITERATE_TO_NEXT_TERM(ch);
2079 strProto = RTStrStrip(ch);
2080 ITERATE_TO_NEXT_TERM(ch);
2081 strHostIp = RTStrStrip(ch);
2082 ITERATE_TO_NEXT_TERM(ch);
2083 strHostPort = RTStrStrip(ch);
2084 ITERATE_TO_NEXT_TERM(ch);
2085 strGuestIp = RTStrStrip(ch);
2086 ITERATE_TO_NEXT_TERM(ch);
2087 strGuestPort = RTStrStrip(ch);
2088 NATProtocol_T proto;
2089 if (RTStrICmp(strProto, "udp") == 0)
2090 proto = NATProtocol_UDP;
2091 else if (RTStrICmp(strProto, "tcp") == 0)
2092 proto = NATProtocol_TCP;
2093 else
2094 {
2095 errorArgument(ModifyVM::tr("Invalid proto '%s' specfied for NIC %u"), ValueUnion.psz, GetOptState.uIndex);
2096 hrc = E_FAIL;
2097 break;
2098 }
2099 CHECK_ERROR(engine, AddRedirect(Bstr(strName).raw(), proto,
2100 Bstr(strHostIp).raw(),
2101 RTStrToUInt16(strHostPort),
2102 Bstr(strGuestIp).raw(),
2103 RTStrToUInt16(strGuestPort)));
2104 }
2105 else
2106 {
2107 /* delete NAT Rule operation */
2108 int vrc;
2109 vrc = RTGetOptFetchValue(&GetOptState, &ValueUnion, RTGETOPT_REQ_STRING);
2110 if (RT_FAILURE(vrc))
2111 return errorSyntax(ModifyVM::tr("Not enough parameters"));
2112 CHECK_ERROR(engine, RemoveRedirect(Bstr(ValueUnion.psz).raw()));
2113 }
2114 break;
2115 }
2116 #undef ITERATE_TO_NEXT_TERM
2117 case MODIFYVM_NATALIASMODE:
2118 {
2119 ComPtr<INetworkAdapter> nic;
2120 ComPtr<INATEngine> engine;
2121 uint32_t aliasMode = 0;
2122
2123 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
2124 ASSERT(nic);
2125
2126 CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
2127 if (RTStrCmp(ValueUnion.psz, "default") == 0)
2128 aliasMode = 0;
2129 else
2130 {
2131 char *token = (char *)ValueUnion.psz;
2132 while (token)
2133 {
2134 if (RTStrNCmp(token, RT_STR_TUPLE("log")) == 0)
2135 aliasMode |= NATAliasMode_AliasLog;
2136 else if (RTStrNCmp(token, RT_STR_TUPLE("proxyonly")) == 0)
2137 aliasMode |= NATAliasMode_AliasProxyOnly;
2138 else if (RTStrNCmp(token, RT_STR_TUPLE("sameports")) == 0)
2139 aliasMode |= NATAliasMode_AliasUseSamePorts;
2140 token = RTStrStr(token, ",");
2141 if (token == NULL)
2142 break;
2143 token++;
2144 }
2145 }
2146 CHECK_ERROR(engine, COMSETTER(AliasMode)(aliasMode));
2147 break;
2148 }
2149
2150 case MODIFYVM_NATTFTPPREFIX:
2151 {
2152 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
2153 break;
2154
2155 ComPtr<INetworkAdapter> nic;
2156 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
2157 ASSERT(nic);
2158
2159 ComPtr<INATEngine> engine;
2160 CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
2161
2162 CHECK_ERROR(engine, COMSETTER(TFTPPrefix)(Bstr(ValueUnion.psz).raw()));
2163 break;
2164 }
2165
2166 case MODIFYVM_NATTFTPFILE:
2167 {
2168 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
2169 break;
2170
2171 ComPtr<INetworkAdapter> nic;
2172 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
2173 ASSERT(nic);
2174
2175 ComPtr<INATEngine> engine;
2176 CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
2177
2178 CHECK_ERROR(engine, COMSETTER(TFTPBootFile)(Bstr(ValueUnion.psz).raw()));
2179 break;
2180 }
2181
2182 case MODIFYVM_NATTFTPSERVER:
2183 {
2184 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
2185 break;
2186
2187 ComPtr<INetworkAdapter> nic;
2188 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
2189 ASSERT(nic);
2190
2191 ComPtr<INATEngine> engine;
2192 CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
2193
2194 CHECK_ERROR(engine, COMSETTER(TFTPNextServer)(Bstr(ValueUnion.psz).raw()));
2195 break;
2196 }
2197 case MODIFYVM_NATDNSPASSDOMAIN:
2198 {
2199 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
2200 break;
2201
2202 ComPtr<INetworkAdapter> nic;
2203 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
2204 ASSERT(nic);
2205
2206 ComPtr<INATEngine> engine;
2207 CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
2208
2209 CHECK_ERROR(engine, COMSETTER(DNSPassDomain)(ValueUnion.f));
2210 break;
2211 }
2212
2213 case MODIFYVM_NATDNSPROXY:
2214 {
2215 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
2216 break;
2217
2218 ComPtr<INetworkAdapter> nic;
2219 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
2220 ASSERT(nic);
2221
2222 ComPtr<INATEngine> engine;
2223 CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
2224
2225 CHECK_ERROR(engine, COMSETTER(DNSProxy)(ValueUnion.f));
2226 break;
2227 }
2228
2229 case MODIFYVM_NATDNSHOSTRESOLVER:
2230 {
2231 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
2232 break;
2233
2234 ComPtr<INetworkAdapter> nic;
2235 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
2236 ASSERT(nic);
2237
2238 ComPtr<INATEngine> engine;
2239 CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
2240
2241 CHECK_ERROR(engine, COMSETTER(DNSUseHostResolver)(ValueUnion.f));
2242 break;
2243 }
2244
2245 case MODIFYVM_NATLOCALHOSTREACHABLE:
2246 {
2247 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
2248 break;
2249
2250 ComPtr<INetworkAdapter> nic;
2251 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
2252 ASSERT(nic);
2253
2254 ComPtr<INATEngine> engine;
2255 CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
2256
2257 CHECK_ERROR(engine, COMSETTER(LocalhostReachable)(ValueUnion.f));
2258 break;
2259 }
2260
2261 case MODIFYVM_MACADDRESS:
2262 {
2263 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
2264 break;
2265
2266 ComPtr<INetworkAdapter> nic;
2267 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
2268 ASSERT(nic);
2269
2270 /* generate one? */
2271 if (!RTStrICmp(ValueUnion.psz, "auto"))
2272 {
2273 CHECK_ERROR(nic, COMSETTER(MACAddress)(Bstr().raw()));
2274 }
2275 else
2276 {
2277 CHECK_ERROR(nic, COMSETTER(MACAddress)(Bstr(ValueUnion.psz).raw()));
2278 }
2279 break;
2280 }
2281
2282 case MODIFYVM_HIDPTR:
2283 {
2284 bool fEnableUsb = false;
2285 if (!RTStrICmp(ValueUnion.psz, "ps2"))
2286 {
2287 CHECK_ERROR(sessionMachine, COMSETTER(PointingHIDType)(PointingHIDType_PS2Mouse));
2288 }
2289 else if (!RTStrICmp(ValueUnion.psz, "usb"))
2290 {
2291 CHECK_ERROR(sessionMachine, COMSETTER(PointingHIDType)(PointingHIDType_USBMouse));
2292 if (SUCCEEDED(hrc))
2293 fEnableUsb = true;
2294 }
2295 else if (!RTStrICmp(ValueUnion.psz, "usbtablet"))
2296 {
2297 CHECK_ERROR(sessionMachine, COMSETTER(PointingHIDType)(PointingHIDType_USBTablet));
2298 if (SUCCEEDED(hrc))
2299 fEnableUsb = true;
2300 }
2301 else if (!RTStrICmp(ValueUnion.psz, "usbmultitouch"))
2302 {
2303 CHECK_ERROR(sessionMachine, COMSETTER(PointingHIDType)(PointingHIDType_USBMultiTouch));
2304 if (SUCCEEDED(hrc))
2305 fEnableUsb = true;
2306 }
2307 else if (!RTStrICmp(ValueUnion.psz, "usbmtscreenpluspad"))
2308 {
2309 CHECK_ERROR(sessionMachine, COMSETTER(PointingHIDType)(PointingHIDType_USBMultiTouchScreenPlusPad));
2310 if (SUCCEEDED(hrc))
2311 fEnableUsb = true;
2312 }
2313 else if (!RTStrICmp(ValueUnion.psz, "none"))
2314 {
2315 CHECK_ERROR(sessionMachine, COMSETTER(PointingHIDType)(PointingHIDType_None));
2316 }
2317 else
2318 {
2319 errorArgument(ModifyVM::tr("Invalid type '%s' specfied for pointing device"), ValueUnion.psz);
2320 hrc = E_FAIL;
2321 }
2322 if (fEnableUsb)
2323 {
2324 /* Make sure either the OHCI or xHCI controller is enabled. */
2325 ULONG cOhciCtrls = 0;
2326 ULONG cXhciCtrls = 0;
2327 hrc = sessionMachine->GetUSBControllerCountByType(USBControllerType_OHCI, &cOhciCtrls);
2328 if (SUCCEEDED(hrc)) {
2329 hrc = sessionMachine->GetUSBControllerCountByType(USBControllerType_XHCI, &cXhciCtrls);
2330 if ( SUCCEEDED(hrc)
2331 && cOhciCtrls + cXhciCtrls == 0)
2332 {
2333 /* If there's nothing, enable OHCI (always available). */
2334 ComPtr<IUSBController> UsbCtl;
2335 CHECK_ERROR(sessionMachine, AddUSBController(Bstr("OHCI").raw(), USBControllerType_OHCI,
2336 UsbCtl.asOutParam()));
2337 }
2338 }
2339 }
2340 break;
2341 }
2342
2343 case MODIFYVM_HIDKBD:
2344 {
2345 bool fEnableUsb = false;
2346 if (!RTStrICmp(ValueUnion.psz, "ps2"))
2347 {
2348 CHECK_ERROR(sessionMachine, COMSETTER(KeyboardHIDType)(KeyboardHIDType_PS2Keyboard));
2349 }
2350 else if (!RTStrICmp(ValueUnion.psz, "usb"))
2351 {
2352 CHECK_ERROR(sessionMachine, COMSETTER(KeyboardHIDType)(KeyboardHIDType_USBKeyboard));
2353 if (SUCCEEDED(hrc))
2354 fEnableUsb = true;
2355 }
2356 else if (!RTStrICmp(ValueUnion.psz, "none"))
2357 {
2358 CHECK_ERROR(sessionMachine, COMSETTER(KeyboardHIDType)(KeyboardHIDType_None));
2359 if (SUCCEEDED(hrc))
2360 fEnableUsb = true;
2361 }
2362 else
2363 {
2364 errorArgument(ModifyVM::tr("Invalid type '%s' specfied for keyboard"), ValueUnion.psz);
2365 hrc = E_FAIL;
2366 }
2367 if (fEnableUsb)
2368 {
2369 /* Make sure either the OHCI or xHCI controller is enabled. */
2370 ULONG cOhciCtrls = 0;
2371 ULONG cXhciCtrls = 0;
2372 hrc = sessionMachine->GetUSBControllerCountByType(USBControllerType_OHCI, &cOhciCtrls);
2373 if (SUCCEEDED(hrc)) {
2374 hrc = sessionMachine->GetUSBControllerCountByType(USBControllerType_XHCI, &cXhciCtrls);
2375 if ( SUCCEEDED(hrc)
2376 && cOhciCtrls + cXhciCtrls == 0)
2377 {
2378 /* If there's nothing, enable OHCI (always available). */
2379 ComPtr<IUSBController> UsbCtl;
2380 CHECK_ERROR(sessionMachine, AddUSBController(Bstr("OHCI").raw(), USBControllerType_OHCI,
2381 UsbCtl.asOutParam()));
2382 }
2383 }
2384 }
2385 break;
2386 }
2387
2388 case MODIFYVM_UARTMODE:
2389 {
2390 ComPtr<ISerialPort> uart;
2391
2392 CHECK_ERROR_BREAK(sessionMachine, GetSerialPort(GetOptState.uIndex - 1, uart.asOutParam()));
2393 ASSERT(uart);
2394
2395 if (!RTStrICmp(ValueUnion.psz, "disconnected"))
2396 {
2397 CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_Disconnected));
2398 }
2399 else if ( !RTStrICmp(ValueUnion.psz, "server")
2400 || !RTStrICmp(ValueUnion.psz, "client")
2401 || !RTStrICmp(ValueUnion.psz, "tcpserver")
2402 || !RTStrICmp(ValueUnion.psz, "tcpclient")
2403 || !RTStrICmp(ValueUnion.psz, "file"))
2404 {
2405 const char *pszMode = ValueUnion.psz;
2406
2407 int vrc = RTGetOptFetchValue(&GetOptState, &ValueUnion, RTGETOPT_REQ_STRING);
2408 if (RT_FAILURE(vrc))
2409 return errorSyntax(ModifyVM::tr("Missing or invalid argument to '%s'"),
2410 GetOptState.pDef->pszLong);
2411
2412 CHECK_ERROR(uart, COMSETTER(Path)(Bstr(ValueUnion.psz).raw()));
2413
2414 if (!RTStrICmp(pszMode, "server"))
2415 {
2416 CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_HostPipe));
2417 CHECK_ERROR(uart, COMSETTER(Server)(TRUE));
2418 }
2419 else if (!RTStrICmp(pszMode, "client"))
2420 {
2421 CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_HostPipe));
2422 CHECK_ERROR(uart, COMSETTER(Server)(FALSE));
2423 }
2424 else if (!RTStrICmp(pszMode, "tcpserver"))
2425 {
2426 CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_TCP));
2427 CHECK_ERROR(uart, COMSETTER(Server)(TRUE));
2428 }
2429 else if (!RTStrICmp(pszMode, "tcpclient"))
2430 {
2431 CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_TCP));
2432 CHECK_ERROR(uart, COMSETTER(Server)(FALSE));
2433 }
2434 else if (!RTStrICmp(pszMode, "file"))
2435 {
2436 CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_RawFile));
2437 }
2438 }
2439 else
2440 {
2441 CHECK_ERROR(uart, COMSETTER(Path)(Bstr(ValueUnion.psz).raw()));
2442 CHECK_ERROR(uart, COMSETTER(HostMode)(PortMode_HostDevice));
2443 }
2444 break;
2445 }
2446
2447 case MODIFYVM_UARTTYPE:
2448 {
2449 ComPtr<ISerialPort> uart;
2450
2451 CHECK_ERROR_BREAK(sessionMachine, GetSerialPort(GetOptState.uIndex - 1, uart.asOutParam()));
2452 ASSERT(uart);
2453
2454 if (!RTStrICmp(ValueUnion.psz, "16450"))
2455 {
2456 CHECK_ERROR(uart, COMSETTER(UartType)(UartType_U16450));
2457 }
2458 else if (!RTStrICmp(ValueUnion.psz, "16550A"))
2459 {
2460 CHECK_ERROR(uart, COMSETTER(UartType)(UartType_U16550A));
2461 }
2462 else if (!RTStrICmp(ValueUnion.psz, "16750"))
2463 {
2464 CHECK_ERROR(uart, COMSETTER(UartType)(UartType_U16750));
2465 }
2466 else
2467 return errorSyntax(ModifyVM::tr("Invalid argument to '%s'"),
2468 GetOptState.pDef->pszLong);
2469 break;
2470 }
2471
2472 case MODIFYVM_UART:
2473 {
2474 ComPtr<ISerialPort> uart;
2475
2476 CHECK_ERROR_BREAK(sessionMachine, GetSerialPort(GetOptState.uIndex - 1, uart.asOutParam()));
2477 ASSERT(uart);
2478
2479 if (!RTStrICmp(ValueUnion.psz, "off") || !RTStrICmp(ValueUnion.psz, "disable"))
2480 CHECK_ERROR(uart, COMSETTER(Enabled)(FALSE));
2481 else
2482 {
2483 const char *pszIOBase = ValueUnion.psz;
2484 uint32_t uVal = 0;
2485
2486 int vrc = RTGetOptFetchValue(&GetOptState, &ValueUnion, RTGETOPT_REQ_UINT32) != MODIFYVM_UART;
2487 if (RT_FAILURE(vrc))
2488 return errorSyntax(ModifyVM::tr("Missing or invalid argument to '%s'"),
2489 GetOptState.pDef->pszLong);
2490
2491 CHECK_ERROR(uart, COMSETTER(IRQ)(ValueUnion.u32));
2492
2493 vrc = RTStrToUInt32Ex(pszIOBase, NULL, 0, &uVal);
2494 if (vrc != VINF_SUCCESS || uVal == 0)
2495 return errorArgument(ModifyVM::tr("Error parsing UART I/O base '%s'"), pszIOBase);
2496 CHECK_ERROR(uart, COMSETTER(IOBase)(uVal));
2497
2498 CHECK_ERROR(uart, COMSETTER(Enabled)(TRUE));
2499 }
2500 break;
2501 }
2502
2503#if defined(RT_OS_LINUX) || defined(RT_OS_WINDOWS)
2504 case MODIFYVM_LPTMODE:
2505 {
2506 ComPtr<IParallelPort> lpt;
2507
2508 CHECK_ERROR_BREAK(sessionMachine, GetParallelPort(GetOptState.uIndex - 1, lpt.asOutParam()));
2509 ASSERT(lpt);
2510
2511 CHECK_ERROR(lpt, COMSETTER(Path)(Bstr(ValueUnion.psz).raw()));
2512 break;
2513 }
2514
2515 case MODIFYVM_LPT:
2516 {
2517 ComPtr<IParallelPort> lpt;
2518
2519 CHECK_ERROR_BREAK(sessionMachine, GetParallelPort(GetOptState.uIndex - 1, lpt.asOutParam()));
2520 ASSERT(lpt);
2521
2522 if (!RTStrICmp(ValueUnion.psz, "off") || !RTStrICmp(ValueUnion.psz, "disable"))
2523 CHECK_ERROR(lpt, COMSETTER(Enabled)(FALSE));
2524 else
2525 {
2526 const char *pszIOBase = ValueUnion.psz;
2527 uint32_t uVal = 0;
2528
2529 int vrc = RTGetOptFetchValue(&GetOptState, &ValueUnion, RTGETOPT_REQ_UINT32) != MODIFYVM_LPT;
2530 if (RT_FAILURE(vrc))
2531 return errorSyntax(ModifyVM::tr("Missing or invalid argument to '%s'"),
2532 GetOptState.pDef->pszLong);
2533
2534 CHECK_ERROR(lpt, COMSETTER(IRQ)(ValueUnion.u32));
2535
2536 vrc = RTStrToUInt32Ex(pszIOBase, NULL, 0, &uVal);
2537 if (vrc != VINF_SUCCESS || uVal == 0)
2538 return errorArgument(ModifyVM::tr("Error parsing LPT I/O base '%s'"), pszIOBase);
2539 CHECK_ERROR(lpt, COMSETTER(IOBase)(uVal));
2540
2541 CHECK_ERROR(lpt, COMSETTER(Enabled)(TRUE));
2542 }
2543 break;
2544 }
2545#endif
2546
2547 case MODIFYVM_GUESTMEMORYBALLOON:
2548 {
2549 CHECK_ERROR(sessionMachine, COMSETTER(MemoryBalloonSize)(ValueUnion.u32));
2550 break;
2551 }
2552
2553 case MODIFYVM_AUDIOCONTROLLER:
2554 {
2555 ComPtr<IAudioSettings> audioSettings;
2556 CHECK_ERROR_BREAK(sessionMachine, COMGETTER(AudioSettings)(audioSettings.asOutParam()));
2557 ComPtr<IAudioAdapter> audioAdapter;
2558 CHECK_ERROR_BREAK(audioSettings, COMGETTER(Adapter)(audioAdapter.asOutParam()));
2559 ASSERT(audioAdapter);
2560
2561 if (!RTStrICmp(ValueUnion.psz, "sb16"))
2562 CHECK_ERROR(audioAdapter, COMSETTER(AudioController)(AudioControllerType_SB16));
2563 else if (!RTStrICmp(ValueUnion.psz, "ac97"))
2564 CHECK_ERROR(audioAdapter, COMSETTER(AudioController)(AudioControllerType_AC97));
2565 else if (!RTStrICmp(ValueUnion.psz, "hda"))
2566 CHECK_ERROR(audioAdapter, COMSETTER(AudioController)(AudioControllerType_HDA));
2567 else
2568 {
2569 errorArgument(ModifyVM::tr("Invalid --audiocontroller argument '%s'"), ValueUnion.psz);
2570 hrc = E_FAIL;
2571 }
2572 break;
2573 }
2574
2575 case MODIFYVM_AUDIOCODEC:
2576 {
2577 ComPtr<IAudioSettings> audioSettings;
2578 CHECK_ERROR_BREAK(sessionMachine, COMGETTER(AudioSettings)(audioSettings.asOutParam()));
2579 ComPtr<IAudioAdapter> audioAdapter;
2580 CHECK_ERROR_BREAK(audioSettings, COMGETTER(Adapter)(audioAdapter.asOutParam()));
2581 ASSERT(audioAdapter);
2582
2583 if (!RTStrICmp(ValueUnion.psz, "sb16"))
2584 CHECK_ERROR(audioAdapter, COMSETTER(AudioCodec)(AudioCodecType_SB16));
2585 else if (!RTStrICmp(ValueUnion.psz, "stac9700"))
2586 CHECK_ERROR(audioAdapter, COMSETTER(AudioCodec)(AudioCodecType_STAC9700));
2587 else if (!RTStrICmp(ValueUnion.psz, "ad1980"))
2588 CHECK_ERROR(audioAdapter, COMSETTER(AudioCodec)(AudioCodecType_AD1980));
2589 else if (!RTStrICmp(ValueUnion.psz, "stac9221"))
2590 CHECK_ERROR(audioAdapter, COMSETTER(AudioCodec)(AudioCodecType_STAC9221));
2591 else
2592 {
2593 errorArgument(ModifyVM::tr("Invalid --audiocodec argument '%s'"), ValueUnion.psz);
2594 hrc = E_FAIL;
2595 }
2596 break;
2597 }
2598
2599 case MODIFYVM_AUDIODRIVER:
2600 RT_FALL_THROUGH();
2601 case MODIFYVM_AUDIO: /** @todo Deprecated; remove. */
2602 {
2603 if (c == MODIFYVM_AUDIO)
2604 RTStrmPrintf(g_pStdErr,
2605 ModifyVM::tr("Warning: --audio is deprecated and will be removed soon. Use --audio-driver instead!\n"));
2606
2607 ComPtr<IAudioSettings> audioSettings;
2608 CHECK_ERROR_BREAK(sessionMachine, COMGETTER(AudioSettings)(audioSettings.asOutParam()));
2609 ComPtr<IAudioAdapter> audioAdapter;
2610 CHECK_ERROR_BREAK(audioSettings, COMGETTER(Adapter)(audioAdapter.asOutParam()));
2611 ASSERT(audioAdapter);
2612 /* disable? */
2613 if ( !RTStrICmp(ValueUnion.psz, "none")
2614 || !RTStrICmp(ValueUnion.psz, "null"))
2615 CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_Null));
2616 else if (!RTStrICmp(ValueUnion.psz, "default"))
2617 CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_Default));
2618#ifdef RT_OS_WINDOWS
2619# ifdef VBOX_WITH_WINMM
2620 else if (!RTStrICmp(ValueUnion.psz, "winmm"))
2621 CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_WinMM));
2622# endif
2623 else if (!RTStrICmp(ValueUnion.psz, "dsound"))
2624 CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_DirectSound));
2625 else if (!RTStrICmp(ValueUnion.psz, "was"))
2626 CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_WAS));
2627#endif /* RT_OS_WINDOWS */
2628#ifdef VBOX_WITH_AUDIO_OSS
2629 else if (!RTStrICmp(ValueUnion.psz, "oss"))
2630 CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_OSS));
2631#endif
2632#ifdef VBOX_WITH_AUDIO_ALSA
2633 else if (!RTStrICmp(ValueUnion.psz, "alsa"))
2634 CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_ALSA));
2635#endif
2636#ifdef VBOX_WITH_AUDIO_PULSE
2637 else if (!RTStrICmp(ValueUnion.psz, "pulse"))
2638 CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_Pulse));
2639#endif
2640#ifdef RT_OS_DARWIN
2641 else if (!RTStrICmp(ValueUnion.psz, "coreaudio"))
2642 CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_CoreAudio));
2643#endif /* !RT_OS_DARWIN */
2644 else
2645 {
2646 errorArgument(ModifyVM::tr("Invalid %s argument '%s'"),
2647 c == MODIFYVM_AUDIO ? "--audio" : "--audio-driver", ValueUnion.psz);
2648 hrc = E_FAIL;
2649 }
2650
2651 if ( SUCCEEDED(hrc)
2652 && c == MODIFYVM_AUDIO) /* To keep the original behavior until we remove the command. */
2653 CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(RTStrICmp(ValueUnion.psz, "none") == false ? false : true));
2654
2655 break;
2656 }
2657
2658 case MODIFYVM_AUDIOENABLED:
2659 {
2660 ComPtr<IAudioSettings> audioSettings;
2661 CHECK_ERROR_BREAK(sessionMachine, COMGETTER(AudioSettings)(audioSettings.asOutParam()));
2662 ComPtr<IAudioAdapter> audioAdapter;
2663 CHECK_ERROR_BREAK(audioSettings, COMGETTER(Adapter)(audioAdapter.asOutParam()));
2664 ASSERT(audioAdapter);
2665
2666 CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(ValueUnion.f));
2667 break;
2668 }
2669
2670 case MODIFYVM_AUDIOIN:
2671 {
2672 ComPtr<IAudioSettings> audioSettings;
2673 CHECK_ERROR_BREAK(sessionMachine, COMGETTER(AudioSettings)(audioSettings.asOutParam()));
2674 ComPtr<IAudioAdapter> audioAdapter;
2675 CHECK_ERROR_BREAK(audioSettings, COMGETTER(Adapter)(audioAdapter.asOutParam()));
2676 ASSERT(audioAdapter);
2677
2678 CHECK_ERROR(audioAdapter, COMSETTER(EnabledIn)(ValueUnion.f));
2679 break;
2680 }
2681
2682 case MODIFYVM_AUDIOOUT:
2683 {
2684 ComPtr<IAudioSettings> audioSettings;
2685 CHECK_ERROR_BREAK(sessionMachine, COMGETTER(AudioSettings)(audioSettings.asOutParam()));
2686 ComPtr<IAudioAdapter> audioAdapter;
2687 CHECK_ERROR_BREAK(audioSettings, COMGETTER(Adapter)(audioAdapter.asOutParam()));
2688 ASSERT(audioAdapter);
2689
2690 CHECK_ERROR(audioAdapter, COMSETTER(EnabledOut)(ValueUnion.f));
2691 break;
2692 }
2693
2694#ifdef VBOX_WITH_SHARED_CLIPBOARD
2695 case MODIFYVM_CLIPBOARD_MODE:
2696 {
2697 ClipboardMode_T mode = ClipboardMode_Disabled; /* Shut up MSC */
2698 if (!RTStrICmp(ValueUnion.psz, "disabled"))
2699 mode = ClipboardMode_Disabled;
2700 else if (!RTStrICmp(ValueUnion.psz, "hosttoguest"))
2701 mode = ClipboardMode_HostToGuest;
2702 else if (!RTStrICmp(ValueUnion.psz, "guesttohost"))
2703 mode = ClipboardMode_GuestToHost;
2704 else if (!RTStrICmp(ValueUnion.psz, "bidirectional"))
2705 mode = ClipboardMode_Bidirectional;
2706 else
2707 {
2708 errorArgument(ModifyVM::tr("Invalid --clipboard-mode argument '%s'"), ValueUnion.psz);
2709 hrc = E_FAIL;
2710 }
2711 if (SUCCEEDED(hrc))
2712 {
2713 CHECK_ERROR(sessionMachine, COMSETTER(ClipboardMode)(mode));
2714 }
2715 break;
2716 }
2717
2718# ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
2719 case MODIFYVM_CLIPBOARD_FILE_TRANSFERS:
2720 {
2721 BOOL fEnabled = false; /* Shut up MSC */
2722 if (!RTStrICmp(ValueUnion.psz, "enabled"))
2723 fEnabled = true;
2724 else if (!RTStrICmp(ValueUnion.psz, "disabled"))
2725 fEnabled = false;
2726 else
2727 {
2728 errorArgument(ModifyVM::tr("Invalid --clipboard-file-transfers argument '%s'"), ValueUnion.psz);
2729 hrc = E_FAIL;
2730 }
2731 if (SUCCEEDED(hrc))
2732 {
2733 CHECK_ERROR(sessionMachine, COMSETTER(ClipboardFileTransfersEnabled)(fEnabled));
2734 }
2735 break;
2736 }
2737# endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */
2738#endif /* VBOX_WITH_SHARED_CLIPBOARD */
2739
2740 case MODIFYVM_DRAGANDDROP:
2741 {
2742 DnDMode_T mode = DnDMode_Disabled; /* Shut up MSC */
2743 if (!RTStrICmp(ValueUnion.psz, "disabled"))
2744 mode = DnDMode_Disabled;
2745 else if (!RTStrICmp(ValueUnion.psz, "hosttoguest"))
2746 mode = DnDMode_HostToGuest;
2747 else if (!RTStrICmp(ValueUnion.psz, "guesttohost"))
2748 mode = DnDMode_GuestToHost;
2749 else if (!RTStrICmp(ValueUnion.psz, "bidirectional"))
2750 mode = DnDMode_Bidirectional;
2751 else
2752 {
2753 errorArgument(ModifyVM::tr("Invalid --draganddrop argument '%s'"), ValueUnion.psz);
2754 hrc = E_FAIL;
2755 }
2756 if (SUCCEEDED(hrc))
2757 {
2758 CHECK_ERROR(sessionMachine, COMSETTER(DnDMode)(mode));
2759 }
2760 break;
2761 }
2762
2763 case MODIFYVM_VRDE_EXTPACK:
2764 {
2765 ComPtr<IVRDEServer> vrdeServer;
2766 sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
2767 ASSERT(vrdeServer);
2768
2769 if (vrdeServer)
2770 {
2771 if (RTStrICmp(ValueUnion.psz, "default") != 0)
2772 {
2773 Bstr bstr(ValueUnion.psz);
2774 CHECK_ERROR(vrdeServer, COMSETTER(VRDEExtPack)(bstr.raw()));
2775 }
2776 else
2777 CHECK_ERROR(vrdeServer, COMSETTER(VRDEExtPack)(Bstr().raw()));
2778 }
2779 break;
2780 }
2781
2782 case MODIFYVM_VRDEPROPERTY:
2783 {
2784 ComPtr<IVRDEServer> vrdeServer;
2785 sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
2786 ASSERT(vrdeServer);
2787
2788 if (vrdeServer)
2789 {
2790 /* Parse 'name=value' */
2791 char *pszProperty = RTStrDup(ValueUnion.psz);
2792 if (pszProperty)
2793 {
2794 char *pDelimiter = strchr(pszProperty, '=');
2795 if (pDelimiter)
2796 {
2797 *pDelimiter = '\0';
2798
2799 Bstr bstrName = pszProperty;
2800 Bstr bstrValue = &pDelimiter[1];
2801 CHECK_ERROR(vrdeServer, SetVRDEProperty(bstrName.raw(), bstrValue.raw()));
2802 }
2803 else
2804 {
2805 RTStrFree(pszProperty);
2806
2807 errorArgument(ModifyVM::tr("Invalid --vrdeproperty argument '%s'"), ValueUnion.psz);
2808 hrc = E_FAIL;
2809 break;
2810 }
2811 RTStrFree(pszProperty);
2812 }
2813 else
2814 {
2815 RTStrmPrintf(g_pStdErr, ModifyVM::tr("Error: Failed to allocate memory for VRDE property '%s'\n"),
2816 ValueUnion.psz);
2817 hrc = E_FAIL;
2818 }
2819 }
2820 break;
2821 }
2822
2823 case MODIFYVM_VRDPPORT:
2824 vrdeWarningDeprecatedOption("port");
2825 RT_FALL_THRU();
2826
2827 case MODIFYVM_VRDEPORT:
2828 {
2829 ComPtr<IVRDEServer> vrdeServer;
2830 sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
2831 ASSERT(vrdeServer);
2832
2833 if (!RTStrICmp(ValueUnion.psz, "default"))
2834 CHECK_ERROR(vrdeServer, SetVRDEProperty(Bstr("TCP/Ports").raw(), Bstr("0").raw()));
2835 else
2836 CHECK_ERROR(vrdeServer, SetVRDEProperty(Bstr("TCP/Ports").raw(), Bstr(ValueUnion.psz).raw()));
2837 break;
2838 }
2839
2840 case MODIFYVM_VRDPADDRESS:
2841 vrdeWarningDeprecatedOption("address");
2842 RT_FALL_THRU();
2843
2844 case MODIFYVM_VRDEADDRESS:
2845 {
2846 ComPtr<IVRDEServer> vrdeServer;
2847 sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
2848 ASSERT(vrdeServer);
2849
2850 CHECK_ERROR(vrdeServer, SetVRDEProperty(Bstr("TCP/Address").raw(), Bstr(ValueUnion.psz).raw()));
2851 break;
2852 }
2853
2854 case MODIFYVM_VRDPAUTHTYPE:
2855 vrdeWarningDeprecatedOption("authtype");
2856 RT_FALL_THRU();
2857 case MODIFYVM_VRDEAUTHTYPE:
2858 {
2859 ComPtr<IVRDEServer> vrdeServer;
2860 sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
2861 ASSERT(vrdeServer);
2862
2863 if (!RTStrICmp(ValueUnion.psz, "null"))
2864 {
2865 CHECK_ERROR(vrdeServer, COMSETTER(AuthType)(AuthType_Null));
2866 }
2867 else if (!RTStrICmp(ValueUnion.psz, "external"))
2868 {
2869 CHECK_ERROR(vrdeServer, COMSETTER(AuthType)(AuthType_External));
2870 }
2871 else if (!RTStrICmp(ValueUnion.psz, "guest"))
2872 {
2873 CHECK_ERROR(vrdeServer, COMSETTER(AuthType)(AuthType_Guest));
2874 }
2875 else
2876 {
2877 errorArgument(ModifyVM::tr("Invalid --vrdeauthtype argument '%s'"), ValueUnion.psz);
2878 hrc = E_FAIL;
2879 }
2880 break;
2881 }
2882
2883 case MODIFYVM_VRDEAUTHLIBRARY:
2884 {
2885 ComPtr<IVRDEServer> vrdeServer;
2886 sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
2887 ASSERT(vrdeServer);
2888
2889 if (vrdeServer)
2890 {
2891 if (RTStrICmp(ValueUnion.psz, "default") != 0)
2892 {
2893 Bstr bstr(ValueUnion.psz);
2894 CHECK_ERROR(vrdeServer, COMSETTER(AuthLibrary)(bstr.raw()));
2895 }
2896 else
2897 CHECK_ERROR(vrdeServer, COMSETTER(AuthLibrary)(Bstr().raw()));
2898 }
2899 break;
2900 }
2901
2902 case MODIFYVM_VRDPMULTICON:
2903 vrdeWarningDeprecatedOption("multicon");
2904 RT_FALL_THRU();
2905 case MODIFYVM_VRDEMULTICON:
2906 {
2907 ComPtr<IVRDEServer> vrdeServer;
2908 sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
2909 ASSERT(vrdeServer);
2910
2911 CHECK_ERROR(vrdeServer, COMSETTER(AllowMultiConnection)(ValueUnion.f));
2912 break;
2913 }
2914
2915 case MODIFYVM_VRDPREUSECON:
2916 vrdeWarningDeprecatedOption("reusecon");
2917 RT_FALL_THRU();
2918 case MODIFYVM_VRDEREUSECON:
2919 {
2920 ComPtr<IVRDEServer> vrdeServer;
2921 sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
2922 ASSERT(vrdeServer);
2923
2924 CHECK_ERROR(vrdeServer, COMSETTER(ReuseSingleConnection)(ValueUnion.f));
2925 break;
2926 }
2927
2928 case MODIFYVM_VRDPVIDEOCHANNEL:
2929 vrdeWarningDeprecatedOption("videochannel");
2930 RT_FALL_THRU();
2931 case MODIFYVM_VRDEVIDEOCHANNEL:
2932 {
2933 ComPtr<IVRDEServer> vrdeServer;
2934 sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
2935 ASSERT(vrdeServer);
2936
2937 CHECK_ERROR(vrdeServer, SetVRDEProperty(Bstr("VideoChannel/Enabled").raw(),
2938 ValueUnion.f? Bstr("true").raw(): Bstr("false").raw()));
2939 break;
2940 }
2941
2942 case MODIFYVM_VRDPVIDEOCHANNELQUALITY:
2943 vrdeWarningDeprecatedOption("videochannelquality");
2944 RT_FALL_THRU();
2945 case MODIFYVM_VRDEVIDEOCHANNELQUALITY:
2946 {
2947 ComPtr<IVRDEServer> vrdeServer;
2948 sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
2949 ASSERT(vrdeServer);
2950
2951 CHECK_ERROR(vrdeServer, SetVRDEProperty(Bstr("VideoChannel/Quality").raw(),
2952 Bstr(ValueUnion.psz).raw()));
2953 break;
2954 }
2955
2956 case MODIFYVM_VRDP:
2957 vrdeWarningDeprecatedOption("");
2958 RT_FALL_THRU();
2959 case MODIFYVM_VRDE:
2960 {
2961 ComPtr<IVRDEServer> vrdeServer;
2962 sessionMachine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
2963 ASSERT(vrdeServer);
2964
2965 CHECK_ERROR(vrdeServer, COMSETTER(Enabled)(ValueUnion.f));
2966 break;
2967 }
2968
2969 case MODIFYVM_USBRENAME:
2970 {
2971 const char *pszName = ValueUnion.psz;
2972 int vrc = RTGetOptFetchValue(&GetOptState, &ValueUnion, RTGETOPT_REQ_STRING);
2973 if (RT_FAILURE(vrc))
2974 return errorSyntax(ModifyVM::tr("Missing or invalid argument to '%s'"),
2975 GetOptState.pDef->pszLong);
2976 const char *pszNewName = ValueUnion.psz;
2977
2978 SafeIfaceArray<IUSBController> ctrls;
2979 CHECK_ERROR(sessionMachine, COMGETTER(USBControllers)(ComSafeArrayAsOutParam(ctrls)));
2980 bool fRenamed = false;
2981 for (size_t i = 0; i < ctrls.size(); i++)
2982 {
2983 ComPtr<IUSBController> pCtrl = ctrls[i];
2984 Bstr bstrName;
2985 CHECK_ERROR(pCtrl, COMGETTER(Name)(bstrName.asOutParam()));
2986 if (bstrName == pszName)
2987 {
2988 bstrName = pszNewName;
2989 CHECK_ERROR(pCtrl, COMSETTER(Name)(bstrName.raw()));
2990 fRenamed = true;
2991 }
2992 }
2993 if (!fRenamed)
2994 {
2995 errorArgument(ModifyVM::tr("Invalid --usbrename parameters, nothing renamed"));
2996 hrc = E_FAIL;
2997 }
2998 break;
2999 }
3000
3001 case MODIFYVM_USBXHCI:
3002 {
3003 ULONG cXhciCtrls = 0;
3004 hrc = sessionMachine->GetUSBControllerCountByType(USBControllerType_XHCI, &cXhciCtrls);
3005 if (SUCCEEDED(hrc))
3006 {
3007 if (!cXhciCtrls && ValueUnion.f)
3008 {
3009 ComPtr<IUSBController> UsbCtl;
3010 CHECK_ERROR(sessionMachine, AddUSBController(Bstr("xHCI").raw(), USBControllerType_XHCI,
3011 UsbCtl.asOutParam()));
3012 }
3013 else if (cXhciCtrls && !ValueUnion.f)
3014 {
3015 SafeIfaceArray<IUSBController> ctrls;
3016 CHECK_ERROR(sessionMachine, COMGETTER(USBControllers)(ComSafeArrayAsOutParam(ctrls)));
3017 for (size_t i = 0; i < ctrls.size(); i++)
3018 {
3019 ComPtr<IUSBController> pCtrl = ctrls[i];
3020 USBControllerType_T enmType;
3021 CHECK_ERROR(pCtrl, COMGETTER(Type)(&enmType));
3022 if (enmType == USBControllerType_XHCI)
3023 {
3024 Bstr ctrlName;
3025 CHECK_ERROR(pCtrl, COMGETTER(Name)(ctrlName.asOutParam()));
3026 CHECK_ERROR(sessionMachine, RemoveUSBController(ctrlName.raw()));
3027 }
3028 }
3029 }
3030 }
3031 break;
3032 }
3033
3034 case MODIFYVM_USBEHCI:
3035 {
3036 ULONG cEhciCtrls = 0;
3037 hrc = sessionMachine->GetUSBControllerCountByType(USBControllerType_EHCI, &cEhciCtrls);
3038 if (SUCCEEDED(hrc))
3039 {
3040 if (!cEhciCtrls && ValueUnion.f)
3041 {
3042 ComPtr<IUSBController> UsbCtl;
3043 CHECK_ERROR(sessionMachine, AddUSBController(Bstr("EHCI").raw(), USBControllerType_EHCI,
3044 UsbCtl.asOutParam()));
3045 }
3046 else if (cEhciCtrls && !ValueUnion.f)
3047 {
3048 SafeIfaceArray<IUSBController> ctrls;
3049 CHECK_ERROR(sessionMachine, COMGETTER(USBControllers)(ComSafeArrayAsOutParam(ctrls)));
3050 for (size_t i = 0; i < ctrls.size(); i++)
3051 {
3052 ComPtr<IUSBController> pCtrl = ctrls[i];
3053 USBControllerType_T enmType;
3054 CHECK_ERROR(pCtrl, COMGETTER(Type)(&enmType));
3055 if (enmType == USBControllerType_EHCI)
3056 {
3057 Bstr ctrlName;
3058 CHECK_ERROR(pCtrl, COMGETTER(Name)(ctrlName.asOutParam()));
3059 CHECK_ERROR(sessionMachine, RemoveUSBController(ctrlName.raw()));
3060 }
3061 }
3062 }
3063 }
3064 break;
3065 }
3066
3067 case MODIFYVM_USBOHCI:
3068 {
3069 ULONG cOhciCtrls = 0;
3070 hrc = sessionMachine->GetUSBControllerCountByType(USBControllerType_OHCI, &cOhciCtrls);
3071 if (SUCCEEDED(hrc))
3072 {
3073 if (!cOhciCtrls && ValueUnion.f)
3074 {
3075 ComPtr<IUSBController> UsbCtl;
3076 CHECK_ERROR(sessionMachine, AddUSBController(Bstr("OHCI").raw(), USBControllerType_OHCI,
3077 UsbCtl.asOutParam()));
3078 }
3079 else if (cOhciCtrls && !ValueUnion.f)
3080 {
3081 SafeIfaceArray<IUSBController> ctrls;
3082 CHECK_ERROR(sessionMachine, COMGETTER(USBControllers)(ComSafeArrayAsOutParam(ctrls)));
3083 for (size_t i = 0; i < ctrls.size(); i++)
3084 {
3085 ComPtr<IUSBController> pCtrl = ctrls[i];
3086 USBControllerType_T enmType;
3087 CHECK_ERROR(pCtrl, COMGETTER(Type)(&enmType));
3088 if (enmType == USBControllerType_OHCI)
3089 {
3090 Bstr ctrlName;
3091 CHECK_ERROR(pCtrl, COMGETTER(Name)(ctrlName.asOutParam()));
3092 CHECK_ERROR(sessionMachine, RemoveUSBController(ctrlName.raw()));
3093 }
3094 }
3095 }
3096 }
3097 break;
3098 }
3099
3100 case MODIFYVM_SNAPSHOTFOLDER:
3101 {
3102 if (!RTStrICmp(ValueUnion.psz, "default"))
3103 CHECK_ERROR(sessionMachine, COMSETTER(SnapshotFolder)(Bstr().raw()));
3104 else
3105 CHECK_ERROR(sessionMachine, COMSETTER(SnapshotFolder)(Bstr(ValueUnion.psz).raw()));
3106 break;
3107 }
3108
3109 case MODIFYVM_TELEPORTER_ENABLED:
3110 {
3111 CHECK_ERROR(sessionMachine, COMSETTER(TeleporterEnabled)(ValueUnion.f));
3112 break;
3113 }
3114
3115 case MODIFYVM_TELEPORTER_PORT:
3116 {
3117 CHECK_ERROR(sessionMachine, COMSETTER(TeleporterPort)(ValueUnion.u32));
3118 break;
3119 }
3120
3121 case MODIFYVM_TELEPORTER_ADDRESS:
3122 {
3123 CHECK_ERROR(sessionMachine, COMSETTER(TeleporterAddress)(Bstr(ValueUnion.psz).raw()));
3124 break;
3125 }
3126
3127 case MODIFYVM_TELEPORTER_PASSWORD:
3128 {
3129 CHECK_ERROR(sessionMachine, COMSETTER(TeleporterPassword)(Bstr(ValueUnion.psz).raw()));
3130 break;
3131 }
3132
3133 case MODIFYVM_TELEPORTER_PASSWORD_FILE:
3134 {
3135 Utf8Str password;
3136 RTEXITCODE rcExit = readPasswordFile(ValueUnion.psz, &password);
3137 if (rcExit != RTEXITCODE_SUCCESS)
3138 hrc = E_FAIL;
3139 else
3140 CHECK_ERROR(sessionMachine, COMSETTER(TeleporterPassword)(Bstr(password).raw()));
3141 break;
3142 }
3143
3144 case MODIFYVM_TRACING_ENABLED:
3145 {
3146 CHECK_ERROR(sessionMachine, COMSETTER(TracingEnabled)(ValueUnion.f));
3147 break;
3148 }
3149
3150 case MODIFYVM_TRACING_CONFIG:
3151 {
3152 CHECK_ERROR(sessionMachine, COMSETTER(TracingConfig)(Bstr(ValueUnion.psz).raw()));
3153 break;
3154 }
3155
3156 case MODIFYVM_TRACING_ALLOW_VM_ACCESS:
3157 {
3158 CHECK_ERROR(sessionMachine, COMSETTER(AllowTracingToAccessVM)(ValueUnion.f));
3159 break;
3160 }
3161
3162 case MODIFYVM_HARDWARE_UUID:
3163 {
3164 CHECK_ERROR(sessionMachine, COMSETTER(HardwareUUID)(Bstr(ValueUnion.psz).raw()));
3165 break;
3166 }
3167
3168 case MODIFYVM_HPET:
3169 {
3170 CHECK_ERROR(sessionMachine, COMSETTER(HPETEnabled)(ValueUnion.f));
3171 break;
3172 }
3173
3174 case MODIFYVM_IOCACHE:
3175 {
3176 CHECK_ERROR(sessionMachine, COMSETTER(IOCacheEnabled)(ValueUnion.f));
3177 break;
3178 }
3179
3180 case MODIFYVM_IOCACHESIZE:
3181 {
3182 CHECK_ERROR(sessionMachine, COMSETTER(IOCacheSize)(ValueUnion.u32));
3183 break;
3184 }
3185
3186 case MODIFYVM_CHIPSET:
3187 {
3188 if (!RTStrICmp(ValueUnion.psz, "piix3"))
3189 {
3190 CHECK_ERROR(sessionMachine, COMSETTER(ChipsetType)(ChipsetType_PIIX3));
3191 }
3192 else if (!RTStrICmp(ValueUnion.psz, "ich9"))
3193 {
3194 CHECK_ERROR(sessionMachine, COMSETTER(ChipsetType)(ChipsetType_ICH9));
3195 BOOL fIoApic = FALSE;
3196 CHECK_ERROR(biosSettings, COMGETTER(IOAPICEnabled)(&fIoApic));
3197 if (!fIoApic)
3198 {
3199 RTStrmPrintf(g_pStdErr, ModifyVM::tr("*** I/O APIC must be enabled for ICH9, enabling. ***\n"));
3200 CHECK_ERROR(biosSettings, COMSETTER(IOAPICEnabled)(TRUE));
3201 }
3202 }
3203 else
3204 {
3205 errorArgument(ModifyVM::tr("Invalid --chipset argument '%s' (valid: piix3,ich9)"), ValueUnion.psz);
3206 hrc = E_FAIL;
3207 }
3208 break;
3209 }
3210#if defined(VBOX_WITH_IOMMU_AMD) || defined(VBOX_WITH_IOMMU_INTEL)
3211 case MODIFYVM_IOMMU:
3212 {
3213 if ( !RTStrICmp(ValueUnion.psz, "none")
3214 || !RTStrICmp(ValueUnion.psz, "disabled"))
3215 CHECK_ERROR(sessionMachine, COMSETTER(IommuType)(IommuType_None));
3216 else if (!RTStrICmp(ValueUnion.psz, "amd"))
3217 CHECK_ERROR(sessionMachine, COMSETTER(IommuType)(IommuType_AMD));
3218 else if (!RTStrICmp(ValueUnion.psz, "intel"))
3219 {
3220#ifdef VBOX_WITH_IOMMU_INTEL
3221 CHECK_ERROR(sessionMachine, COMSETTER(IommuType)(IommuType_Intel));
3222#else
3223 errorArgument(ModifyVM::tr("Invalid --iommu argument '%s' (valid: none,amd,automatic)"), ValueUnion.psz);
3224 hrc = E_FAIL;
3225#endif
3226 }
3227 else if (!RTStrICmp(ValueUnion.psz, "automatic"))
3228 {
3229 CHECK_ERROR(sessionMachine, COMSETTER(IommuType)(IommuType_Automatic));
3230#ifndef VBOX_WITH_IOMMU_INTEL
3231 RTStrmPrintf(g_pStdErr,
3232 ModifyVM::tr("Warning: On Intel hosts, 'automatic' will not enable an IOMMU since the Intel IOMMU device is not supported yet.\n"));
3233#endif
3234 }
3235 else
3236 {
3237 errorArgument(ModifyVM::tr("Invalid --iommu argument '%s'"), ValueUnion.psz);
3238 hrc = E_FAIL;
3239 }
3240 break;
3241 }
3242#endif
3243#if defined(VBOX_WITH_TPM)
3244 case MODIFYVM_TPM_TYPE:
3245 {
3246 ComPtr<ITrustedPlatformModule> tpm;
3247 sessionMachine->COMGETTER(TrustedPlatformModule)(tpm.asOutParam());
3248
3249 if ( !RTStrICmp(ValueUnion.psz, "none")
3250 || !RTStrICmp(ValueUnion.psz, "disabled"))
3251 CHECK_ERROR(tpm, COMSETTER(Type)(TpmType_None));
3252 else if (!RTStrICmp(ValueUnion.psz, "1.2"))
3253 CHECK_ERROR(tpm, COMSETTER(Type)(TpmType_v1_2));
3254 else if (!RTStrICmp(ValueUnion.psz, "2.0"))
3255 CHECK_ERROR(tpm, COMSETTER(Type)(TpmType_v2_0));
3256 else if (!RTStrICmp(ValueUnion.psz, "host"))
3257 CHECK_ERROR(tpm, COMSETTER(Type)(TpmType_Host));
3258 else if (!RTStrICmp(ValueUnion.psz, "swtpm"))
3259 CHECK_ERROR(tpm, COMSETTER(Type)(TpmType_Swtpm));
3260 else
3261 {
3262 errorArgument(ModifyVM::tr("Invalid --tpm-type argument '%s'"), ValueUnion.psz);
3263 hrc = E_FAIL;
3264 }
3265 break;
3266 }
3267
3268 case MODIFYVM_TPM_LOCATION:
3269 {
3270 ComPtr<ITrustedPlatformModule> tpm;
3271 sessionMachine->COMGETTER(TrustedPlatformModule)(tpm.asOutParam());
3272
3273 CHECK_ERROR(tpm, COMSETTER(Location)(Bstr(ValueUnion.psz).raw()));
3274 break;
3275 }
3276#endif
3277#ifdef VBOX_WITH_RECORDING
3278 case MODIFYVM_RECORDING:
3279 RT_FALL_THROUGH();
3280 case MODIFYVM_RECORDING_SCREENS:
3281 RT_FALL_THROUGH();
3282 case MODIFYVM_RECORDING_FILENAME:
3283 RT_FALL_THROUGH();
3284 case MODIFYVM_RECORDING_VIDEO_WIDTH:
3285 RT_FALL_THROUGH();
3286 case MODIFYVM_RECORDING_VIDEO_HEIGHT:
3287 RT_FALL_THROUGH();
3288 case MODIFYVM_RECORDING_VIDEO_RES:
3289 RT_FALL_THROUGH();
3290 case MODIFYVM_RECORDING_VIDEO_RATE:
3291 RT_FALL_THROUGH();
3292 case MODIFYVM_RECORDING_VIDEO_FPS:
3293 RT_FALL_THROUGH();
3294 case MODIFYVM_RECORDING_MAXTIME:
3295 RT_FALL_THROUGH();
3296 case MODIFYVM_RECORDING_MAXSIZE:
3297 RT_FALL_THROUGH();
3298 case MODIFYVM_RECORDING_OPTIONS:
3299 {
3300 ComPtr<IRecordingSettings> recordingSettings;
3301 CHECK_ERROR_BREAK(sessionMachine, COMGETTER(RecordingSettings)(recordingSettings.asOutParam()));
3302 SafeIfaceArray <IRecordingScreenSettings> saRecordingScreenScreens;
3303 CHECK_ERROR_BREAK(recordingSettings, COMGETTER(Screens)(ComSafeArrayAsOutParam(saRecordingScreenScreens)));
3304
3305 switch (c)
3306 {
3307 case MODIFYVM_RECORDING:
3308 {
3309 CHECK_ERROR(recordingSettings, COMSETTER(Enabled)(ValueUnion.f));
3310 break;
3311 }
3312 case MODIFYVM_RECORDING_SCREENS:
3313 {
3314 ULONG cMonitors = 64;
3315 CHECK_ERROR(pGraphicsAdapter, COMGETTER(MonitorCount)(&cMonitors));
3316 com::SafeArray<BOOL> screens(cMonitors);
3317 if (RT_FAILURE(parseScreens(ValueUnion.psz, &screens)))
3318 {
3319 errorArgument(ModifyVM::tr("Invalid list of screens specified\n"));
3320 hrc = E_FAIL;
3321 break;
3322 }
3323
3324 if (cMonitors > saRecordingScreenScreens.size()) /* Paranoia. */
3325 cMonitors = (ULONG)saRecordingScreenScreens.size();
3326
3327 for (size_t i = 0; i < cMonitors; ++i)
3328 CHECK_ERROR_BREAK(saRecordingScreenScreens[i], COMSETTER(Enabled)(screens[i]));
3329 break;
3330 }
3331 case MODIFYVM_RECORDING_FILENAME:
3332 {
3333 Bstr bstr;
3334 /* empty string will fall through, leaving bstr empty */
3335 if (*ValueUnion.psz)
3336 {
3337 char szVCFileAbs[RTPATH_MAX] = "";
3338 int vrc = RTPathAbs(ValueUnion.psz, szVCFileAbs, sizeof(szVCFileAbs));
3339 if (RT_FAILURE(vrc))
3340 {
3341 errorArgument(ModifyVM::tr("Cannot convert filename \"%s\" to absolute path\n"), ValueUnion.psz);
3342 hrc = E_FAIL;
3343 break;
3344 }
3345 bstr = szVCFileAbs;
3346 }
3347
3348 for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
3349 CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(Filename)(bstr.raw()));
3350 break;
3351 }
3352 case MODIFYVM_RECORDING_VIDEO_WIDTH:
3353 {
3354 for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
3355 CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(VideoWidth)(ValueUnion.u32));
3356 break;
3357 }
3358 case MODIFYVM_RECORDING_VIDEO_HEIGHT:
3359 {
3360 for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
3361 CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(VideoHeight)(ValueUnion.u32));
3362 break;
3363 }
3364 case MODIFYVM_RECORDING_VIDEO_RES:
3365 {
3366 uint32_t uWidth = 0;
3367 char *pszNext;
3368 int vrc = RTStrToUInt32Ex(ValueUnion.psz, &pszNext, 0, &uWidth);
3369 if (RT_FAILURE(vrc) || vrc != VWRN_TRAILING_CHARS || !pszNext || *pszNext != 'x')
3370 {
3371 errorArgument(ModifyVM::tr("Error parsing video resolution '%s' (expected <width>x<height>)"),
3372 ValueUnion.psz);
3373 hrc = E_FAIL;
3374 break;
3375 }
3376 uint32_t uHeight = 0;
3377 vrc = RTStrToUInt32Ex(pszNext+1, NULL, 0, &uHeight);
3378 if (vrc != VINF_SUCCESS)
3379 {
3380 errorArgument(ModifyVM::tr("Error parsing video resolution '%s' (expected <width>x<height>)"),
3381 ValueUnion.psz);
3382 hrc = E_FAIL;
3383 break;
3384 }
3385
3386 for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
3387 {
3388 CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(VideoWidth)(uWidth));
3389 CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(VideoHeight)(uHeight));
3390 }
3391 break;
3392 }
3393 case MODIFYVM_RECORDING_VIDEO_RATE:
3394 {
3395 for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
3396 CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(VideoRate)(ValueUnion.u32));
3397 break;
3398 }
3399 case MODIFYVM_RECORDING_VIDEO_FPS:
3400 {
3401 for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
3402 CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(VideoFPS)(ValueUnion.u32));
3403 break;
3404 }
3405 case MODIFYVM_RECORDING_MAXTIME:
3406 {
3407 for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
3408 CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(MaxTime)(ValueUnion.u32));
3409 break;
3410 }
3411 case MODIFYVM_RECORDING_MAXSIZE:
3412 {
3413 for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
3414 CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(MaxFileSize)(ValueUnion.u32));
3415 break;
3416 }
3417 case MODIFYVM_RECORDING_OPTIONS:
3418 {
3419 Bstr bstr(ValueUnion.psz);
3420 for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
3421 CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(Options)(bstr.raw()));
3422 break;
3423 }
3424 }
3425
3426 break;
3427 }
3428#endif
3429 case MODIFYVM_AUTOSTART_ENABLED:
3430 {
3431 CHECK_ERROR(sessionMachine, COMSETTER(AutostartEnabled)(ValueUnion.f));
3432 break;
3433 }
3434
3435 case MODIFYVM_AUTOSTART_DELAY:
3436 {
3437 CHECK_ERROR(sessionMachine, COMSETTER(AutostartDelay)(ValueUnion.u32));
3438 break;
3439 }
3440
3441 case MODIFYVM_AUTOSTOP_TYPE:
3442 {
3443 AutostopType_T enmAutostopType = AutostopType_Disabled;
3444
3445 if (!RTStrICmp(ValueUnion.psz, "disabled"))
3446 enmAutostopType = AutostopType_Disabled;
3447 else if (!RTStrICmp(ValueUnion.psz, "savestate"))
3448 enmAutostopType = AutostopType_SaveState;
3449 else if (!RTStrICmp(ValueUnion.psz, "poweroff"))
3450 enmAutostopType = AutostopType_PowerOff;
3451 else if (!RTStrICmp(ValueUnion.psz, "acpishutdown"))
3452 enmAutostopType = AutostopType_AcpiShutdown;
3453 else
3454 {
3455 errorArgument(ModifyVM::tr("Invalid --autostop-type argument '%s' (valid: disabled, savestate, poweroff, acpishutdown)"),
3456 ValueUnion.psz);
3457 hrc = E_FAIL;
3458 }
3459
3460 if (SUCCEEDED(hrc))
3461 CHECK_ERROR(sessionMachine, COMSETTER(AutostopType)(enmAutostopType));
3462 break;
3463 }
3464#ifdef VBOX_WITH_PCI_PASSTHROUGH
3465 case MODIFYVM_ATTACH_PCI:
3466 {
3467 const char* pAt = strchr(ValueUnion.psz, '@');
3468 int32_t iHostAddr, iGuestAddr;
3469
3470 iHostAddr = parsePci(ValueUnion.psz);
3471 iGuestAddr = pAt != NULL ? parsePci(pAt + 1) : iHostAddr;
3472
3473 if (iHostAddr == -1 || iGuestAddr == -1)
3474 {
3475 errorArgument(ModifyVM::tr("Invalid --pciattach argument '%s' (valid: 'HB:HD.HF@GB:GD.GF' or just 'HB:HD.HF')"),
3476 ValueUnion.psz);
3477 hrc = E_FAIL;
3478 }
3479 else
3480 {
3481 CHECK_ERROR(sessionMachine, AttachHostPCIDevice(iHostAddr, iGuestAddr, TRUE));
3482 }
3483
3484 break;
3485 }
3486 case MODIFYVM_DETACH_PCI:
3487 {
3488 int32_t iHostAddr;
3489
3490 iHostAddr = parsePci(ValueUnion.psz);
3491 if (iHostAddr == -1)
3492 {
3493 errorArgument(ModifyVM::tr("Invalid --pcidetach argument '%s' (valid: 'HB:HD.HF')"), ValueUnion.psz);
3494 hrc = E_FAIL;
3495 }
3496 else
3497 {
3498 CHECK_ERROR(sessionMachine, DetachHostPCIDevice(iHostAddr));
3499 }
3500
3501 break;
3502 }
3503#endif
3504
3505#ifdef VBOX_WITH_USB_CARDREADER
3506 case MODIFYVM_USBCARDREADER:
3507 {
3508 CHECK_ERROR(sessionMachine, COMSETTER(EmulatedUSBCardReaderEnabled)(ValueUnion.f));
3509 break;
3510 }
3511#endif /* VBOX_WITH_USB_CARDREADER */
3512
3513 case MODIFYVM_DEFAULTFRONTEND:
3514 {
3515 Bstr bstr(ValueUnion.psz);
3516 if (bstr == "default")
3517 bstr = Bstr::Empty;
3518 CHECK_ERROR(sessionMachine, COMSETTER(DefaultFrontend)(bstr.raw()));
3519 break;
3520 }
3521
3522 case MODIFYVM_VMPROC_PRIORITY:
3523 {
3524 VMProcPriority_T enmPriority = nameToVMProcPriority(ValueUnion.psz);
3525 if (enmPriority == VMProcPriority_Invalid)
3526 {
3527 errorArgument(ModifyVM::tr("Invalid --vm-process-priority '%s'"), ValueUnion.psz);
3528 hrc = E_FAIL;
3529 }
3530 else
3531 {
3532 CHECK_ERROR(sessionMachine, COMSETTER(VMProcessPriority)(enmPriority));
3533 }
3534 break;
3535 }
3536
3537 case MODIFYVM_TESTING_ENABLED:
3538 hrc = setExtraData(sessionMachine, "VBoxInternal/Devices/VMMDev/0/Config/TestingEnabled", ValueUnion.f ? "1" : "");
3539 break;
3540
3541 case MODIFYVM_TESTING_MMIO:
3542 hrc = setExtraData(sessionMachine, "VBoxInternal/Devices/VMMDev/0/Config/TestingMMIO", ValueUnion.f ? "1" : "");
3543 break;
3544
3545 case MODIFYVM_TESTING_CFG_DWORD:
3546 if (GetOptState.uIndex <= 9)
3547 {
3548 char szVar[128];
3549 RTStrPrintf(szVar, sizeof(szVar), "VBoxInternal/Devices/VMMDev/0/Config/TestingCfgDword%u",
3550 GetOptState.uIndex);
3551 char szValue[32];
3552 RTStrPrintf(szValue, sizeof(szValue), "%u", ValueUnion.u32);
3553 hrc = setExtraData(sessionMachine, szVar, szValue);
3554 }
3555 else
3556 hrc = errorArgumentHr(ModifyVM::tr("--testing-cfg-dword index %u is out of range: 0 thru 9"),
3557 GetOptState.uIndex);
3558 break;
3559
3560 case MODIFYVM_GUEST_DEBUG_PROVIDER:
3561 {
3562 ComPtr<IGuestDebugControl> gstDbgCtrl;
3563 CHECK_ERROR_BREAK(sessionMachine, COMGETTER(GuestDebugControl)(gstDbgCtrl.asOutParam()));
3564
3565 GuestDebugProvider_T enmDebugProvider = GuestDebugProvider_None;
3566
3567 if (!RTStrICmp(ValueUnion.psz, "none"))
3568 enmDebugProvider = GuestDebugProvider_None;
3569 else if (!RTStrICmp(ValueUnion.psz, "native"))
3570 enmDebugProvider = GuestDebugProvider_Native;
3571 else if (!RTStrICmp(ValueUnion.psz, "gdb"))
3572 enmDebugProvider = GuestDebugProvider_GDB;
3573 else if (!RTStrICmp(ValueUnion.psz, "kd"))
3574 enmDebugProvider = GuestDebugProvider_KD;
3575 else
3576 {
3577 errorArgument(ModifyVM::tr("Invalid --guest-debug-provider '%s' (valid: none, native, gdb, kd)"),
3578 ValueUnion.psz);
3579 hrc = E_FAIL;
3580 }
3581
3582 if (SUCCEEDED(hrc))
3583 CHECK_ERROR(gstDbgCtrl, COMSETTER(DebugProvider)(enmDebugProvider));
3584 break;
3585 }
3586
3587 case MODIFYVM_GUEST_DEBUG_IO_PROVIDER:
3588 {
3589 ComPtr<IGuestDebugControl> gstDbgCtrl;
3590 CHECK_ERROR_BREAK(sessionMachine, COMGETTER(GuestDebugControl)(gstDbgCtrl.asOutParam()));
3591
3592 GuestDebugIoProvider_T enmDebugIoProvider = GuestDebugIoProvider_None;
3593
3594 if (!RTStrICmp(ValueUnion.psz, "none"))
3595 enmDebugIoProvider = GuestDebugIoProvider_None;
3596 else if (!RTStrICmp(ValueUnion.psz, "tcp"))
3597 enmDebugIoProvider = GuestDebugIoProvider_TCP;
3598 else if (!RTStrICmp(ValueUnion.psz, "udp"))
3599 enmDebugIoProvider = GuestDebugIoProvider_UDP;
3600 else if (!RTStrICmp(ValueUnion.psz, "ipc"))
3601 enmDebugIoProvider = GuestDebugIoProvider_IPC;
3602 else
3603 {
3604 errorArgument(ModifyVM::tr("Invalid --guest-debug-io-provider '%s' (valid: none, tcp, udp, ipc)"),
3605 ValueUnion.psz);
3606 hrc = E_FAIL;
3607 }
3608
3609 if (SUCCEEDED(hrc))
3610 CHECK_ERROR(gstDbgCtrl, COMSETTER(DebugIoProvider)(enmDebugIoProvider));
3611 break;
3612 }
3613
3614 case MODIFYVM_GUEST_DEBUG_ADDRESS:
3615 {
3616 ComPtr<IGuestDebugControl> gstDbgCtrl;
3617 CHECK_ERROR_BREAK(sessionMachine, COMGETTER(GuestDebugControl)(gstDbgCtrl.asOutParam()));
3618
3619 Bstr bstr(ValueUnion.psz);
3620 CHECK_ERROR(gstDbgCtrl, COMSETTER(DebugAddress)(bstr.raw()));
3621 break;
3622 }
3623
3624 case MODIFYVM_GUEST_DEBUG_PORT:
3625 {
3626 ComPtr<IGuestDebugControl> gstDbgCtrl;
3627 CHECK_ERROR_BREAK(sessionMachine, COMGETTER(GuestDebugControl)(gstDbgCtrl.asOutParam()));
3628 CHECK_ERROR(gstDbgCtrl, COMSETTER(DebugPort)(ValueUnion.u32));
3629 break;
3630 }
3631
3632 default:
3633 errorGetOpt(c, &ValueUnion);
3634 hrc = E_FAIL;
3635 break;
3636 }
3637 }
3638
3639 /* commit changes */
3640 if (SUCCEEDED(hrc))
3641 CHECK_ERROR(sessionMachine, SaveSettings());
3642
3643 /* it's important to always close sessions */
3644 a->session->UnlockMachine();
3645
3646 return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
3647}
Note: See TracBrowser for help on using the repository browser.

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