VirtualBox

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

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

Main/FE: Added new audio driver type "default" to make it possible to move VMs (appliances) between different platforms without the need of changing the audio driver explicitly. When the "default" driver is selected, the best audio backend option for a platform will be used.

While at it, also added the "WAS" (Windows Audio Session) driver type for which we only had a hack so far. This now can be explicitly selected, also by the frontends [build fix]. bugref:10051

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