VirtualBox

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

Last change on this file since 88082 was 88079, checked in by vboxsync, 4 years ago

VBoxManage: When setting the host interface for bridging or hostonly
attachments do a sanity check on it. Make sure IHost knows about it
and that the interface is of correct type. Warn the user if that's
not the case, but the warning is non-fatal. The API setters don't do
this, so provide at least some protection from typos and mistakes.
bugref:9966.

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

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