VirtualBox

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

Last change on this file since 75138 was 75138, checked in by vboxsync, 7 years ago

FE/VBoxManage: Renamed the video capturing options to better reflect which option is generic to capturing and which is bound to the video recording feature. This also should make space for the upcoming audio feature options. Got rid of the deprecated stuff which was in there for too long.

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette