VirtualBox

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

Last change on this file since 99844 was 98298, checked in by vboxsync, 23 months ago

VBoxManage: rc -> vrc/hrc. Make scm check. bugref:10223

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