VirtualBox

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

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

VBoxManage: Finish cleanup for 'modifyvm'.

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