VirtualBox

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

Last change on this file since 94070 was 94070, checked in by vboxsync, 3 years ago

CloudNet: ​bugref:9469 Dropped local gateway parameters in VBoxManage cloud network setup, added support for cloud network attachment in VBoxManage modifyvm, updated help for both, bug fixes and minor improvements in error reporting.

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