VirtualBox

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

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

Main,FE/VBoxManage: Implement possiblity to configure some of the guest debugging facilities to make it more accessible, bugref:1098

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