VirtualBox

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

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

Main,FE/VBoxManage: Add the necessary Main API bits to control the trusted platform module settings as well as implementing support in VBoxManage, bugref:10075

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