VirtualBox

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

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

Main/Console: Correctly handle mouse and keyboard type of None, which in principle was always allowed but still added the hardware.

Frontends/VBoxManage: For modifyvm, allow configuring a VM to have no mouse and/or keyboard.
So far undocumented because it needs more testing, but should be safe.

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

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