VirtualBox

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

Last change on this file since 88989 was 88363, checked in by vboxsync, 4 years ago

Intel IOMMU: bugref:9967 VBoxManage: Allow enabling Intel IOMMU (when VBOX_WITH_IOMMU_INTEL is defined).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 140.2 KB
Line 
1/* $Id: VBoxManageModifyVM.cpp 88363 2021-04-05 06:22:36Z vboxsync $ */
2/** @file
3 * VBoxManage - Implementation of modifyvm command.
4 */
5
6/*
7 * Copyright (C) 2006-2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#ifndef VBOX_ONLY_DOCS
23#include <VBox/com/com.h>
24#include <VBox/com/array.h>
25#include <VBox/com/ErrorInfo.h>
26#include <VBox/com/errorprint.h>
27#include <VBox/com/VirtualBox.h>
28#endif /* !VBOX_ONLY_DOCS */
29
30#include <iprt/cidr.h>
31#include <iprt/ctype.h>
32#include <iprt/file.h>
33#include <iprt/param.h>
34#include <iprt/path.h>
35#include <iprt/stream.h>
36#include <iprt/string.h>
37#include <iprt/getopt.h>
38#include <VBox/log.h>
39#include "VBoxManage.h"
40#include "VBoxManageUtils.h"
41
42#ifndef VBOX_ONLY_DOCS
43using namespace com;
44/** @todo refine this after HDD changes; MSC 8.0/64 has trouble with handleModifyVM. */
45#if defined(_MSC_VER)
46# pragma optimize("g", off)
47# if _MSC_VER < RT_MSC_VER_VC120
48# pragma warning(disable:4748)
49# endif
50#endif
51
52enum
53{
54 MODIFYVM_NAME = 1000,
55 MODIFYVM_GROUPS,
56 MODIFYVM_DESCRIPTION,
57 MODIFYVM_OSTYPE,
58 MODIFYVM_ICONFILE,
59 MODIFYVM_MEMORY,
60 MODIFYVM_PAGEFUSION,
61 MODIFYVM_VRAM,
62 MODIFYVM_FIRMWARE,
63 MODIFYVM_ACPI,
64 MODIFYVM_IOAPIC,
65 MODIFYVM_PAE,
66 MODIFYVM_LONGMODE,
67 MODIFYVM_CPUID_PORTABILITY,
68 MODIFYVM_TFRESET,
69 MODIFYVM_APIC,
70 MODIFYVM_X2APIC,
71 MODIFYVM_PARAVIRTPROVIDER,
72 MODIFYVM_PARAVIRTDEBUG,
73 MODIFYVM_HWVIRTEX,
74 MODIFYVM_NESTEDPAGING,
75 MODIFYVM_LARGEPAGES,
76 MODIFYVM_VTXVPID,
77 MODIFYVM_VTXUX,
78 MODIFYVM_VIRT_VMSAVE_VMLOAD,
79 MODIFYVM_IBPB_ON_VM_EXIT,
80 MODIFYVM_IBPB_ON_VM_ENTRY,
81 MODIFYVM_SPEC_CTRL,
82 MODIFYVM_L1D_FLUSH_ON_SCHED,
83 MODIFYVM_L1D_FLUSH_ON_VM_ENTRY,
84 MODIFYVM_MDS_CLEAR_ON_SCHED,
85 MODIFYVM_MDS_CLEAR_ON_VM_ENTRY,
86 MODIFYVM_NESTED_HW_VIRT,
87 MODIFYVM_CPUS,
88 MODIFYVM_CPUHOTPLUG,
89 MODIFYVM_CPU_PROFILE,
90 MODIFYVM_PLUGCPU,
91 MODIFYVM_UNPLUGCPU,
92 MODIFYVM_SETCPUID,
93 MODIFYVM_SETCPUID_OLD,
94 MODIFYVM_DELCPUID,
95 MODIFYVM_DELCPUID_OLD,
96 MODIFYVM_DELALLCPUID,
97 MODIFYVM_GRAPHICSCONTROLLER,
98 MODIFYVM_MONITORCOUNT,
99 MODIFYVM_ACCELERATE3D,
100#ifdef VBOX_WITH_VIDEOHWACCEL
101 MODIFYVM_ACCELERATE2DVIDEO,
102#endif
103 MODIFYVM_BIOSLOGOFADEIN,
104 MODIFYVM_BIOSLOGOFADEOUT,
105 MODIFYVM_BIOSLOGODISPLAYTIME,
106 MODIFYVM_BIOSLOGOIMAGEPATH,
107 MODIFYVM_BIOSBOOTMENU,
108 MODIFYVM_BIOSAPIC,
109 MODIFYVM_BIOSSYSTEMTIMEOFFSET,
110 MODIFYVM_BIOSPXEDEBUG,
111 MODIFYVM_SYSTEMUUIDLE,
112 MODIFYVM_BOOT,
113 MODIFYVM_HDA, // deprecated
114 MODIFYVM_HDB, // deprecated
115 MODIFYVM_HDD, // deprecated
116 MODIFYVM_IDECONTROLLER, // deprecated
117 MODIFYVM_SATAPORTCOUNT, // deprecated
118 MODIFYVM_SATAPORT, // deprecated
119 MODIFYVM_SATA, // deprecated
120 MODIFYVM_SCSIPORT, // deprecated
121 MODIFYVM_SCSITYPE, // deprecated
122 MODIFYVM_SCSI, // deprecated
123 MODIFYVM_DVDPASSTHROUGH, // deprecated
124 MODIFYVM_DVD, // deprecated
125 MODIFYVM_FLOPPY, // deprecated
126 MODIFYVM_NICTRACEFILE,
127 MODIFYVM_NICTRACE,
128 MODIFYVM_NICPROPERTY,
129 MODIFYVM_NICTYPE,
130 MODIFYVM_NICSPEED,
131 MODIFYVM_NICBOOTPRIO,
132 MODIFYVM_NICPROMISC,
133 MODIFYVM_NICBWGROUP,
134 MODIFYVM_NIC,
135 MODIFYVM_CABLECONNECTED,
136 MODIFYVM_BRIDGEADAPTER,
137 MODIFYVM_HOSTONLYADAPTER,
138 MODIFYVM_INTNET,
139 MODIFYVM_GENERICDRV,
140 MODIFYVM_NATNETWORKNAME,
141 MODIFYVM_NATNET,
142 MODIFYVM_NATBINDIP,
143 MODIFYVM_NATSETTINGS,
144 MODIFYVM_NATPF,
145 MODIFYVM_NATALIASMODE,
146 MODIFYVM_NATTFTPPREFIX,
147 MODIFYVM_NATTFTPFILE,
148 MODIFYVM_NATTFTPSERVER,
149 MODIFYVM_NATDNSPASSDOMAIN,
150 MODIFYVM_NATDNSPROXY,
151 MODIFYVM_NATDNSHOSTRESOLVER,
152 MODIFYVM_MACADDRESS,
153 MODIFYVM_HIDPTR,
154 MODIFYVM_HIDKBD,
155 MODIFYVM_UARTMODE,
156 MODIFYVM_UARTTYPE,
157 MODIFYVM_UART,
158#if defined(RT_OS_LINUX) || defined(RT_OS_WINDOWS)
159 MODIFYVM_LPTMODE,
160 MODIFYVM_LPT,
161#endif
162 MODIFYVM_GUESTMEMORYBALLOON,
163 MODIFYVM_AUDIOCONTROLLER,
164 MODIFYVM_AUDIOCODEC,
165 MODIFYVM_AUDIO,
166 MODIFYVM_AUDIOIN,
167 MODIFYVM_AUDIOOUT,
168#ifdef VBOX_WITH_SHARED_CLIPBOARD
169 MODIFYVM_CLIPBOARD_MODE,
170# ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
171 MODIFYVM_CLIPBOARD_FILE_TRANSFERS,
172# endif
173#endif
174 MODIFYVM_DRAGANDDROP,
175 MODIFYVM_VRDPPORT, /* VRDE: deprecated */
176 MODIFYVM_VRDPADDRESS, /* VRDE: deprecated */
177 MODIFYVM_VRDPAUTHTYPE, /* VRDE: deprecated */
178 MODIFYVM_VRDPMULTICON, /* VRDE: deprecated */
179 MODIFYVM_VRDPREUSECON, /* VRDE: deprecated */
180 MODIFYVM_VRDPVIDEOCHANNEL, /* VRDE: deprecated */
181 MODIFYVM_VRDPVIDEOCHANNELQUALITY, /* VRDE: deprecated */
182 MODIFYVM_VRDP, /* VRDE: deprecated */
183 MODIFYVM_VRDEPROPERTY,
184 MODIFYVM_VRDEPORT,
185 MODIFYVM_VRDEADDRESS,
186 MODIFYVM_VRDEAUTHTYPE,
187 MODIFYVM_VRDEAUTHLIBRARY,
188 MODIFYVM_VRDEMULTICON,
189 MODIFYVM_VRDEREUSECON,
190 MODIFYVM_VRDEVIDEOCHANNEL,
191 MODIFYVM_VRDEVIDEOCHANNELQUALITY,
192 MODIFYVM_VRDE_EXTPACK,
193 MODIFYVM_VRDE,
194 MODIFYVM_RTCUSEUTC,
195 MODIFYVM_USBRENAME,
196 MODIFYVM_USBXHCI,
197 MODIFYVM_USBEHCI,
198 MODIFYVM_USBOHCI,
199 MODIFYVM_SNAPSHOTFOLDER,
200 MODIFYVM_TELEPORTER_ENABLED,
201 MODIFYVM_TELEPORTER_PORT,
202 MODIFYVM_TELEPORTER_ADDRESS,
203 MODIFYVM_TELEPORTER_PASSWORD,
204 MODIFYVM_TELEPORTER_PASSWORD_FILE,
205 MODIFYVM_TRACING_ENABLED,
206 MODIFYVM_TRACING_CONFIG,
207 MODIFYVM_TRACING_ALLOW_VM_ACCESS,
208 MODIFYVM_HARDWARE_UUID,
209 MODIFYVM_HPET,
210 MODIFYVM_IOCACHE,
211 MODIFYVM_IOCACHESIZE,
212 MODIFYVM_CPU_EXECTUION_CAP,
213 MODIFYVM_AUTOSTART_ENABLED,
214 MODIFYVM_AUTOSTART_DELAY,
215 MODIFYVM_AUTOSTOP_TYPE,
216#ifdef VBOX_WITH_PCI_PASSTHROUGH
217 MODIFYVM_ATTACH_PCI,
218 MODIFYVM_DETACH_PCI,
219#endif
220#ifdef VBOX_WITH_USB_CARDREADER
221 MODIFYVM_USBCARDREADER,
222#endif
223#ifdef VBOX_WITH_RECORDING
224 MODIFYVM_RECORDING,
225 MODIFYVM_RECORDING_FEATURES,
226 MODIFYVM_RECORDING_SCREENS,
227 MODIFYVM_RECORDING_FILENAME,
228 MODIFYVM_RECORDING_VIDEO_WIDTH,
229 MODIFYVM_RECORDING_VIDEO_HEIGHT,
230 MODIFYVM_RECORDING_VIDEO_RES,
231 MODIFYVM_RECORDING_VIDEO_RATE,
232 MODIFYVM_RECORDING_VIDEO_FPS,
233 MODIFYVM_RECORDING_MAXTIME,
234 MODIFYVM_RECORDING_MAXSIZE,
235 MODIFYVM_RECORDING_OPTIONS,
236#endif
237 MODIFYVM_CHIPSET,
238#if defined(VBOX_WITH_IOMMU_AMD) || defined(VBOX_WITH_IOMMU_INTEL)
239 MODIFYVM_IOMMU,
240#endif
241 MODIFYVM_DEFAULTFRONTEND,
242 MODIFYVM_VMPROC_PRIORITY
243};
244
245static const RTGETOPTDEF g_aModifyVMOptions[] =
246{
247/** @todo Convert to dash separated names like --triple-fault-reset! Please
248 * do that for all new options as we don't need more character soups
249 * around VirtualBox - typedefs more than covers that demand! */
250 { "--name", MODIFYVM_NAME, RTGETOPT_REQ_STRING },
251 { "--groups", MODIFYVM_GROUPS, RTGETOPT_REQ_STRING },
252 { "--description", MODIFYVM_DESCRIPTION, RTGETOPT_REQ_STRING },
253 { "--ostype", MODIFYVM_OSTYPE, RTGETOPT_REQ_STRING },
254 { "--iconfile", MODIFYVM_ICONFILE, RTGETOPT_REQ_STRING },
255 { "--memory", MODIFYVM_MEMORY, RTGETOPT_REQ_UINT32 },
256 { "--pagefusion", MODIFYVM_PAGEFUSION, RTGETOPT_REQ_BOOL_ONOFF },
257 { "--vram", MODIFYVM_VRAM, RTGETOPT_REQ_UINT32 },
258 { "--firmware", MODIFYVM_FIRMWARE, RTGETOPT_REQ_STRING },
259 { "--acpi", MODIFYVM_ACPI, RTGETOPT_REQ_BOOL_ONOFF },
260 { "--ioapic", MODIFYVM_IOAPIC, RTGETOPT_REQ_BOOL_ONOFF },
261 { "--pae", MODIFYVM_PAE, RTGETOPT_REQ_BOOL_ONOFF },
262 { "--longmode", MODIFYVM_LONGMODE, RTGETOPT_REQ_BOOL_ONOFF },
263 { "--cpuid-portability-level", MODIFYVM_CPUID_PORTABILITY, RTGETOPT_REQ_UINT32 },
264 { "--triplefaultreset", MODIFYVM_TFRESET, RTGETOPT_REQ_BOOL_ONOFF },
265 { "--apic", MODIFYVM_APIC, RTGETOPT_REQ_BOOL_ONOFF },
266 { "--x2apic", MODIFYVM_X2APIC, RTGETOPT_REQ_BOOL_ONOFF },
267 { "--paravirtprovider", MODIFYVM_PARAVIRTPROVIDER, RTGETOPT_REQ_STRING },
268 { "--paravirtdebug", MODIFYVM_PARAVIRTDEBUG, RTGETOPT_REQ_STRING },
269 { "--hwvirtex", MODIFYVM_HWVIRTEX, RTGETOPT_REQ_BOOL_ONOFF },
270 { "--nestedpaging", MODIFYVM_NESTEDPAGING, RTGETOPT_REQ_BOOL_ONOFF },
271 { "--largepages", MODIFYVM_LARGEPAGES, RTGETOPT_REQ_BOOL_ONOFF },
272 { "--vtxvpid", MODIFYVM_VTXVPID, RTGETOPT_REQ_BOOL_ONOFF },
273 { "--vtxux", MODIFYVM_VTXUX, RTGETOPT_REQ_BOOL_ONOFF },
274 { "--virt-vmsave-vmload", MODIFYVM_VIRT_VMSAVE_VMLOAD, RTGETOPT_REQ_BOOL_ONOFF },
275 { "--ibpb-on-vm-exit", MODIFYVM_IBPB_ON_VM_EXIT, RTGETOPT_REQ_BOOL_ONOFF },
276 { "--ibpb-on-vm-entry", MODIFYVM_IBPB_ON_VM_ENTRY, RTGETOPT_REQ_BOOL_ONOFF },
277 { "--spec-ctrl", MODIFYVM_SPEC_CTRL, RTGETOPT_REQ_BOOL_ONOFF },
278 { "--l1d-flush-on-sched", MODIFYVM_L1D_FLUSH_ON_SCHED, RTGETOPT_REQ_BOOL_ONOFF },
279 { "--l1d-flush-on-vm-entry", MODIFYVM_L1D_FLUSH_ON_VM_ENTRY, RTGETOPT_REQ_BOOL_ONOFF },
280 { "--mds-clear-on-sched", MODIFYVM_MDS_CLEAR_ON_SCHED, RTGETOPT_REQ_BOOL_ONOFF },
281 { "--mds-clear-on-vm-entry", MODIFYVM_MDS_CLEAR_ON_VM_ENTRY, RTGETOPT_REQ_BOOL_ONOFF },
282 { "--nested-hw-virt", MODIFYVM_NESTED_HW_VIRT, RTGETOPT_REQ_BOOL_ONOFF },
283 { "--cpuid-set", MODIFYVM_SETCPUID, RTGETOPT_REQ_UINT32_OPTIONAL_PAIR | RTGETOPT_FLAG_HEX },
284 { "--cpuid-remove", MODIFYVM_DELCPUID, RTGETOPT_REQ_UINT32_OPTIONAL_PAIR | RTGETOPT_FLAG_HEX },
285 { "--cpuidset", MODIFYVM_SETCPUID_OLD, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_HEX },
286 { "--cpuidremove", MODIFYVM_DELCPUID_OLD, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_HEX },
287 { "--cpuidremoveall", MODIFYVM_DELALLCPUID, RTGETOPT_REQ_NOTHING},
288 { "--cpus", MODIFYVM_CPUS, RTGETOPT_REQ_UINT32 },
289 { "--cpuhotplug", MODIFYVM_CPUHOTPLUG, RTGETOPT_REQ_BOOL_ONOFF },
290 { "--cpu-profile", MODIFYVM_CPU_PROFILE, RTGETOPT_REQ_STRING },
291 { "--plugcpu", MODIFYVM_PLUGCPU, RTGETOPT_REQ_UINT32 },
292 { "--unplugcpu", MODIFYVM_UNPLUGCPU, RTGETOPT_REQ_UINT32 },
293 { "--cpuexecutioncap", MODIFYVM_CPU_EXECTUION_CAP, RTGETOPT_REQ_UINT32 },
294 { "--rtcuseutc", MODIFYVM_RTCUSEUTC, RTGETOPT_REQ_BOOL_ONOFF },
295 { "--graphicscontroller", MODIFYVM_GRAPHICSCONTROLLER, RTGETOPT_REQ_STRING },
296 { "--monitorcount", MODIFYVM_MONITORCOUNT, RTGETOPT_REQ_UINT32 },
297 { "--accelerate3d", MODIFYVM_ACCELERATE3D, RTGETOPT_REQ_BOOL_ONOFF },
298#ifdef VBOX_WITH_VIDEOHWACCEL
299 { "--accelerate2dvideo", MODIFYVM_ACCELERATE2DVIDEO, RTGETOPT_REQ_BOOL_ONOFF },
300#endif
301 { "--bioslogofadein", MODIFYVM_BIOSLOGOFADEIN, RTGETOPT_REQ_BOOL_ONOFF },
302 { "--bioslogofadeout", MODIFYVM_BIOSLOGOFADEOUT, RTGETOPT_REQ_BOOL_ONOFF },
303 { "--bioslogodisplaytime", MODIFYVM_BIOSLOGODISPLAYTIME, RTGETOPT_REQ_UINT32 },
304 { "--bioslogoimagepath", MODIFYVM_BIOSLOGOIMAGEPATH, RTGETOPT_REQ_STRING },
305 { "--biosbootmenu", MODIFYVM_BIOSBOOTMENU, RTGETOPT_REQ_STRING },
306 { "--biossystemtimeoffset", MODIFYVM_BIOSSYSTEMTIMEOFFSET, RTGETOPT_REQ_INT64 },
307 { "--biosapic", MODIFYVM_BIOSAPIC, RTGETOPT_REQ_STRING },
308 { "--biospxedebug", MODIFYVM_BIOSPXEDEBUG, RTGETOPT_REQ_BOOL_ONOFF },
309 { "--system-uuid-le", MODIFYVM_SYSTEMUUIDLE, RTGETOPT_REQ_BOOL_ONOFF },
310 { "--boot", MODIFYVM_BOOT, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
311 { "--hda", MODIFYVM_HDA, RTGETOPT_REQ_STRING },
312 { "--hdb", MODIFYVM_HDB, RTGETOPT_REQ_STRING },
313 { "--hdd", MODIFYVM_HDD, RTGETOPT_REQ_STRING },
314 { "--idecontroller", MODIFYVM_IDECONTROLLER, RTGETOPT_REQ_STRING },
315 { "--sataportcount", MODIFYVM_SATAPORTCOUNT, RTGETOPT_REQ_UINT32 },
316 { "--sataport", MODIFYVM_SATAPORT, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
317 { "--sata", MODIFYVM_SATA, RTGETOPT_REQ_STRING },
318 { "--scsiport", MODIFYVM_SCSIPORT, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
319 { "--scsitype", MODIFYVM_SCSITYPE, RTGETOPT_REQ_STRING },
320 { "--scsi", MODIFYVM_SCSI, RTGETOPT_REQ_STRING },
321 { "--dvdpassthrough", MODIFYVM_DVDPASSTHROUGH, RTGETOPT_REQ_STRING },
322 { "--dvd", MODIFYVM_DVD, RTGETOPT_REQ_STRING },
323 { "--floppy", MODIFYVM_FLOPPY, RTGETOPT_REQ_STRING },
324 { "--nictracefile", MODIFYVM_NICTRACEFILE, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
325 { "--nictrace", MODIFYVM_NICTRACE, RTGETOPT_REQ_BOOL_ONOFF | RTGETOPT_FLAG_INDEX },
326 { "--nicproperty", MODIFYVM_NICPROPERTY, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
327 { "--nictype", MODIFYVM_NICTYPE, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
328 { "--nicspeed", MODIFYVM_NICSPEED, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_INDEX },
329 { "--nicbootprio", MODIFYVM_NICBOOTPRIO, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_INDEX },
330 { "--nicpromisc", MODIFYVM_NICPROMISC, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
331 { "--nicbandwidthgroup", MODIFYVM_NICBWGROUP, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
332 { "--nic", MODIFYVM_NIC, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
333 { "--cableconnected", MODIFYVM_CABLECONNECTED, RTGETOPT_REQ_BOOL_ONOFF | RTGETOPT_FLAG_INDEX },
334 { "--bridgeadapter", MODIFYVM_BRIDGEADAPTER, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
335 { "--hostonlyadapter", MODIFYVM_HOSTONLYADAPTER, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
336 { "--intnet", MODIFYVM_INTNET, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
337 { "--nicgenericdrv", MODIFYVM_GENERICDRV, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
338 { "--nat-network", MODIFYVM_NATNETWORKNAME, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
339 { "--natnetwork", MODIFYVM_NATNETWORKNAME, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
340 { "--natnet", MODIFYVM_NATNET, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
341 { "--natbindip", MODIFYVM_NATBINDIP, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
342 { "--natsettings", MODIFYVM_NATSETTINGS, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
343 { "--natpf", MODIFYVM_NATPF, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
344 { "--nataliasmode", MODIFYVM_NATALIASMODE, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
345 { "--nattftpprefix", MODIFYVM_NATTFTPPREFIX, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
346 { "--nattftpfile", MODIFYVM_NATTFTPFILE, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
347 { "--nattftpserver", MODIFYVM_NATTFTPSERVER, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
348 { "--natdnspassdomain", MODIFYVM_NATDNSPASSDOMAIN, RTGETOPT_REQ_BOOL_ONOFF | RTGETOPT_FLAG_INDEX },
349 { "--natdnsproxy", MODIFYVM_NATDNSPROXY, RTGETOPT_REQ_BOOL_ONOFF | RTGETOPT_FLAG_INDEX },
350 { "--natdnshostresolver", MODIFYVM_NATDNSHOSTRESOLVER, RTGETOPT_REQ_BOOL_ONOFF | RTGETOPT_FLAG_INDEX },
351 { "--macaddress", MODIFYVM_MACADDRESS, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
352 { "--mouse", MODIFYVM_HIDPTR, RTGETOPT_REQ_STRING },
353 { "--keyboard", MODIFYVM_HIDKBD, RTGETOPT_REQ_STRING },
354 { "--uartmode", MODIFYVM_UARTMODE, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
355 { "--uarttype", MODIFYVM_UARTTYPE, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
356 { "--uart", MODIFYVM_UART, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
357#if defined(RT_OS_LINUX) || defined(RT_OS_WINDOWS)
358 { "--lptmode", MODIFYVM_LPTMODE, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
359 { "--lpt", MODIFYVM_LPT, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
360#endif
361 { "--guestmemoryballoon", MODIFYVM_GUESTMEMORYBALLOON, RTGETOPT_REQ_UINT32 },
362 { "--audiocontroller", MODIFYVM_AUDIOCONTROLLER, RTGETOPT_REQ_STRING },
363 { "--audiocodec", MODIFYVM_AUDIOCODEC, RTGETOPT_REQ_STRING },
364 { "--audio", MODIFYVM_AUDIO, RTGETOPT_REQ_STRING },
365 { "--audioin", MODIFYVM_AUDIOIN, RTGETOPT_REQ_BOOL_ONOFF },
366 { "--audioout", MODIFYVM_AUDIOOUT, RTGETOPT_REQ_BOOL_ONOFF },
367#ifdef VBOX_WITH_SHARED_CLIPBOARD
368 { "--clipboard-mode", MODIFYVM_CLIPBOARD_MODE, RTGETOPT_REQ_STRING },
369 { "--clipboard", MODIFYVM_CLIPBOARD_MODE, RTGETOPT_REQ_STRING }, /* deprecated */
370# ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
371 { "--clipboard-file-transfers", MODIFYVM_CLIPBOARD_FILE_TRANSFERS, RTGETOPT_REQ_STRING },
372# endif
373#endif
374 { "--draganddrop", MODIFYVM_DRAGANDDROP, RTGETOPT_REQ_STRING },
375 { "--vrdpport", MODIFYVM_VRDPPORT, RTGETOPT_REQ_STRING }, /* deprecated */
376 { "--vrdpaddress", MODIFYVM_VRDPADDRESS, RTGETOPT_REQ_STRING }, /* deprecated */
377 { "--vrdpauthtype", MODIFYVM_VRDPAUTHTYPE, RTGETOPT_REQ_STRING }, /* deprecated */
378 { "--vrdpmulticon", MODIFYVM_VRDPMULTICON, RTGETOPT_REQ_BOOL_ONOFF }, /* deprecated */
379 { "--vrdpreusecon", MODIFYVM_VRDPREUSECON, RTGETOPT_REQ_BOOL_ONOFF }, /* deprecated */
380 { "--vrdpvideochannel", MODIFYVM_VRDPVIDEOCHANNEL, RTGETOPT_REQ_BOOL_ONOFF }, /* deprecated */
381 { "--vrdpvideochannelquality", MODIFYVM_VRDPVIDEOCHANNELQUALITY, RTGETOPT_REQ_STRING }, /* deprecated */
382 { "--vrdp", MODIFYVM_VRDP, RTGETOPT_REQ_BOOL_ONOFF }, /* deprecated */
383 { "--vrdeproperty", MODIFYVM_VRDEPROPERTY, RTGETOPT_REQ_STRING },
384 { "--vrdeport", MODIFYVM_VRDEPORT, RTGETOPT_REQ_STRING },
385 { "--vrdeaddress", MODIFYVM_VRDEADDRESS, RTGETOPT_REQ_STRING },
386 { "--vrdeauthtype", MODIFYVM_VRDEAUTHTYPE, RTGETOPT_REQ_STRING },
387 { "--vrdeauthlibrary", MODIFYVM_VRDEAUTHLIBRARY, RTGETOPT_REQ_STRING },
388 { "--vrdemulticon", MODIFYVM_VRDEMULTICON, RTGETOPT_REQ_BOOL_ONOFF },
389 { "--vrdereusecon", MODIFYVM_VRDEREUSECON, RTGETOPT_REQ_BOOL_ONOFF },
390 { "--vrdevideochannel", MODIFYVM_VRDEVIDEOCHANNEL, RTGETOPT_REQ_BOOL_ONOFF },
391 { "--vrdevideochannelquality", MODIFYVM_VRDEVIDEOCHANNELQUALITY, RTGETOPT_REQ_STRING },
392 { "--vrdeextpack", MODIFYVM_VRDE_EXTPACK, RTGETOPT_REQ_STRING },
393 { "--vrde", MODIFYVM_VRDE, RTGETOPT_REQ_BOOL_ONOFF },
394 { "--usbrename", MODIFYVM_USBRENAME, RTGETOPT_REQ_STRING },
395 { "--usbxhci", MODIFYVM_USBXHCI, RTGETOPT_REQ_BOOL_ONOFF },
396 { "--usbehci", MODIFYVM_USBEHCI, RTGETOPT_REQ_BOOL_ONOFF },
397 { "--usbohci", MODIFYVM_USBOHCI, RTGETOPT_REQ_BOOL_ONOFF },
398 { "--usb", MODIFYVM_USBOHCI, RTGETOPT_REQ_BOOL_ONOFF }, /* deprecated */
399 { "--snapshotfolder", MODIFYVM_SNAPSHOTFOLDER, RTGETOPT_REQ_STRING },
400 { "--teleporter", MODIFYVM_TELEPORTER_ENABLED, RTGETOPT_REQ_BOOL_ONOFF },
401 { "--teleporterenabled", MODIFYVM_TELEPORTER_ENABLED, RTGETOPT_REQ_BOOL_ONOFF }, /* deprecated */
402 { "--teleporterport", MODIFYVM_TELEPORTER_PORT, RTGETOPT_REQ_UINT32 },
403 { "--teleporteraddress", MODIFYVM_TELEPORTER_ADDRESS, RTGETOPT_REQ_STRING },
404 { "--teleporterpassword", MODIFYVM_TELEPORTER_PASSWORD, RTGETOPT_REQ_STRING },
405 { "--teleporterpasswordfile", MODIFYVM_TELEPORTER_PASSWORD_FILE, RTGETOPT_REQ_STRING },
406 { "--tracing-enabled", MODIFYVM_TRACING_ENABLED, RTGETOPT_REQ_BOOL_ONOFF },
407 { "--tracing-config", MODIFYVM_TRACING_CONFIG, RTGETOPT_REQ_STRING },
408 { "--tracing-allow-vm-access", MODIFYVM_TRACING_ALLOW_VM_ACCESS, RTGETOPT_REQ_BOOL_ONOFF },
409 { "--hardwareuuid", MODIFYVM_HARDWARE_UUID, RTGETOPT_REQ_STRING },
410 { "--hpet", MODIFYVM_HPET, RTGETOPT_REQ_BOOL_ONOFF },
411 { "--iocache", MODIFYVM_IOCACHE, RTGETOPT_REQ_BOOL_ONOFF },
412 { "--iocachesize", MODIFYVM_IOCACHESIZE, RTGETOPT_REQ_UINT32 },
413 { "--chipset", MODIFYVM_CHIPSET, RTGETOPT_REQ_STRING },
414#if defined(VBOX_WITH_IOMMU_AMD) || defined(VBOX_WITH_IOMMU_INTEL)
415 { "--iommu", MODIFYVM_IOMMU, RTGETOPT_REQ_STRING },
416#endif
417#ifdef VBOX_WITH_RECORDING
418 { "--recording", MODIFYVM_RECORDING, RTGETOPT_REQ_BOOL_ONOFF },
419 { "--recordingscreens", MODIFYVM_RECORDING_SCREENS, RTGETOPT_REQ_STRING },
420 { "--recordingfile", MODIFYVM_RECORDING_FILENAME, RTGETOPT_REQ_STRING },
421 { "--recordingmaxtime", MODIFYVM_RECORDING_MAXTIME, RTGETOPT_REQ_INT32 },
422 { "--recordingmaxsize", MODIFYVM_RECORDING_MAXSIZE, RTGETOPT_REQ_INT32 },
423 { "--recordingopts", MODIFYVM_RECORDING_OPTIONS, RTGETOPT_REQ_STRING },
424 { "--recordingoptions", MODIFYVM_RECORDING_OPTIONS, RTGETOPT_REQ_STRING },
425 { "--recordingvideores", MODIFYVM_RECORDING_VIDEO_RES, RTGETOPT_REQ_STRING },
426 { "--recordingvideoresolution", MODIFYVM_RECORDING_VIDEO_RES, RTGETOPT_REQ_STRING },
427 { "--recordingvideorate", MODIFYVM_RECORDING_VIDEO_RATE, RTGETOPT_REQ_UINT32 },
428 { "--recordingvideofps", MODIFYVM_RECORDING_VIDEO_FPS, RTGETOPT_REQ_UINT32 },
429#endif
430 { "--autostart-enabled", MODIFYVM_AUTOSTART_ENABLED, RTGETOPT_REQ_BOOL_ONOFF },
431 { "--autostart-delay", MODIFYVM_AUTOSTART_DELAY, RTGETOPT_REQ_UINT32 },
432 { "--autostop-type", MODIFYVM_AUTOSTOP_TYPE, RTGETOPT_REQ_STRING },
433#ifdef VBOX_WITH_PCI_PASSTHROUGH
434 { "--pciattach", MODIFYVM_ATTACH_PCI, RTGETOPT_REQ_STRING },
435 { "--pcidetach", MODIFYVM_DETACH_PCI, RTGETOPT_REQ_STRING },
436#endif
437#ifdef VBOX_WITH_USB_CARDREADER
438 { "--usbcardreader", MODIFYVM_USBCARDREADER, RTGETOPT_REQ_BOOL_ONOFF },
439#endif
440 { "--defaultfrontend", MODIFYVM_DEFAULTFRONTEND, RTGETOPT_REQ_STRING },
441 { "--vm-process-priority", MODIFYVM_VMPROC_PRIORITY, RTGETOPT_REQ_STRING },
442};
443
444static void vrdeWarningDeprecatedOption(const char *pszOption)
445{
446 RTStrmPrintf(g_pStdErr, "Warning: '--vrdp%s' is deprecated. Use '--vrde%s'.\n", pszOption, pszOption);
447}
448
449#ifdef VBOX_WITH_PCI_PASSTHROUGH
450/** Parse PCI address in format 01:02.03 and convert it to the numeric representation. */
451static int32_t parsePci(const char* szPciAddr)
452{
453 char* pszNext = (char*)szPciAddr;
454 int rc;
455 uint8_t aVals[3] = {0, 0, 0};
456
457 rc = RTStrToUInt8Ex(pszNext, &pszNext, 16, &aVals[0]);
458 if (RT_FAILURE(rc) || pszNext == NULL || *pszNext != ':')
459 return -1;
460
461 rc = RTStrToUInt8Ex(pszNext+1, &pszNext, 16, &aVals[1]);
462 if (RT_FAILURE(rc) || pszNext == NULL || *pszNext != '.')
463 return -1;
464
465 rc = RTStrToUInt8Ex(pszNext+1, &pszNext, 16, &aVals[2]);
466 if (RT_FAILURE(rc) || pszNext == NULL)
467 return -1;
468
469 return (aVals[0] << 8) | (aVals[1] << 3) | (aVals[2] << 0);
470}
471#endif
472
473void parseGroups(const char *pcszGroups, com::SafeArray<BSTR> *pGroups)
474{
475 while (pcszGroups)
476 {
477 char *pComma = RTStrStr(pcszGroups, ",");
478 if (pComma)
479 {
480 Bstr(pcszGroups, pComma - pcszGroups).detachTo(pGroups->appendedRaw());
481 pcszGroups = pComma + 1;
482 }
483 else
484 {
485 Bstr(pcszGroups).detachTo(pGroups->appendedRaw());
486 pcszGroups = NULL;
487 }
488 }
489}
490
491#ifdef VBOX_WITH_RECORDING
492static int parseScreens(const char *pcszScreens, com::SafeArray<BOOL> *pScreens)
493{
494 while (pcszScreens && *pcszScreens)
495 {
496 char *pszNext;
497 uint32_t iScreen;
498 int rc = RTStrToUInt32Ex(pcszScreens, &pszNext, 0, &iScreen);
499 if (RT_FAILURE(rc))
500 return 1;
501 if (iScreen >= pScreens->size())
502 return 1;
503 if (pszNext && *pszNext)
504 {
505 pszNext = RTStrStripL(pszNext);
506 if (*pszNext != ',')
507 return 1;
508 pszNext++;
509 }
510 (*pScreens)[iScreen] = true;
511 pcszScreens = pszNext;
512 }
513 return 0;
514}
515#endif
516
517static int parseNum(uint32_t uIndex, unsigned cMaxIndex, const char *pszName)
518{
519 if ( uIndex >= 1
520 && uIndex <= cMaxIndex)
521 return uIndex;
522 errorArgument("Invalid %s number %u", pszName, uIndex);
523 return 0;
524}
525
526VMProcPriority_T nameToVMProcPriority(const char *pszName)
527{
528 if (!RTStrICmp(pszName, "default"))
529 return VMProcPriority_Default;
530 if (!RTStrICmp(pszName, "flat"))
531 return VMProcPriority_Flat;
532 if (!RTStrICmp(pszName, "low"))
533 return VMProcPriority_Low;
534 if (!RTStrICmp(pszName, "normal"))
535 return VMProcPriority_Normal;
536 if (!RTStrICmp(pszName, "high"))
537 return VMProcPriority_High;
538
539 return VMProcPriority_Invalid;
540}
541
542RTEXITCODE handleModifyVM(HandlerArg *a)
543{
544 int c;
545 HRESULT rc;
546 Bstr name;
547
548 /* VM ID + at least one parameter. Parameter arguments are checked
549 * individually. */
550 if (a->argc < 2)
551 return errorSyntax(USAGE_MODIFYVM, "Not enough parameters");
552
553 /* try to find the given sessionMachine */
554 ComPtr<IMachine> machine;
555 CHECK_ERROR_RET(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(),
556 machine.asOutParam()), RTEXITCODE_FAILURE);
557
558
559 /* Get the number of network adapters */
560 ULONG NetworkAdapterCount = getMaxNics(a->virtualBox, machine);
561
562 /* open a session for the VM */
563 CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Write), RTEXITCODE_FAILURE);
564
565 /* get the mutable session sessionMachine */
566 ComPtr<IMachine> sessionMachine;
567 CHECK_ERROR_RET(a->session, COMGETTER(Machine)(sessionMachine.asOutParam()), RTEXITCODE_FAILURE);
568
569 ComPtr<IBIOSSettings> biosSettings;
570 sessionMachine->COMGETTER(BIOSSettings)(biosSettings.asOutParam());
571
572 ComPtr<IGraphicsAdapter> pGraphicsAdapter;
573 sessionMachine->COMGETTER(GraphicsAdapter)(pGraphicsAdapter.asOutParam());
574
575 RTGETOPTSTATE GetOptState;
576 RTGetOptInit(&GetOptState, a->argc, a->argv, g_aModifyVMOptions,
577 RT_ELEMENTS(g_aModifyVMOptions), 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
578
579 RTGETOPTUNION ValueUnion;
580 while ( SUCCEEDED (rc)
581 && (c = RTGetOpt(&GetOptState, &ValueUnion)))
582 {
583 switch (c)
584 {
585 case MODIFYVM_NAME:
586 {
587 CHECK_ERROR(sessionMachine, COMSETTER(Name)(Bstr(ValueUnion.psz).raw()));
588 break;
589 }
590 case MODIFYVM_GROUPS:
591 {
592 com::SafeArray<BSTR> groups;
593 parseGroups(ValueUnion.psz, &groups);
594 CHECK_ERROR(sessionMachine, COMSETTER(Groups)(ComSafeArrayAsInParam(groups)));
595 break;
596 }
597 case MODIFYVM_DESCRIPTION:
598 {
599 CHECK_ERROR(sessionMachine, COMSETTER(Description)(Bstr(ValueUnion.psz).raw()));
600 break;
601 }
602 case MODIFYVM_OSTYPE:
603 {
604 CHECK_ERROR(sessionMachine, COMSETTER(OSTypeId)(Bstr(ValueUnion.psz).raw()));
605 break;
606 }
607
608 case MODIFYVM_ICONFILE:
609 {
610 RTFILE iconFile;
611 int vrc = RTFileOpen(&iconFile, ValueUnion.psz, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
612 if (RT_FAILURE(vrc))
613 {
614 RTMsgError("Cannot open file \"%s\": %Rrc", ValueUnion.psz, vrc);
615 rc = E_FAIL;
616 break;
617 }
618 uint64_t cbSize;
619 vrc = RTFileQuerySize(iconFile, &cbSize);
620 if (RT_FAILURE(vrc))
621 {
622 RTMsgError("Cannot get size of file \"%s\": %Rrc", ValueUnion.psz, vrc);
623 rc = E_FAIL;
624 break;
625 }
626 if (cbSize > _256K)
627 {
628 RTMsgError("File \"%s\" is bigger than 256KByte", ValueUnion.psz);
629 rc = E_FAIL;
630 break;
631 }
632 SafeArray<BYTE> icon((size_t)cbSize);
633 rc = RTFileRead(iconFile, icon.raw(), (size_t)cbSize, NULL);
634 if (RT_FAILURE(vrc))
635 {
636 RTMsgError("Cannot read contents of file \"%s\": %Rrc", ValueUnion.psz, vrc);
637 rc = E_FAIL;
638 break;
639 }
640 RTFileClose(iconFile);
641 CHECK_ERROR(sessionMachine, COMSETTER(Icon)(ComSafeArrayAsInParam(icon)));
642 break;
643 }
644
645 case MODIFYVM_MEMORY:
646 {
647 CHECK_ERROR(sessionMachine, COMSETTER(MemorySize)(ValueUnion.u32));
648 break;
649 }
650
651 case MODIFYVM_PAGEFUSION:
652 {
653 CHECK_ERROR(sessionMachine, COMSETTER(PageFusionEnabled)(ValueUnion.f));
654 break;
655 }
656
657 case MODIFYVM_VRAM:
658 {
659 CHECK_ERROR(pGraphicsAdapter, COMSETTER(VRAMSize)(ValueUnion.u32));
660 break;
661 }
662
663 case MODIFYVM_FIRMWARE:
664 {
665 if (!RTStrICmp(ValueUnion.psz, "efi"))
666 {
667 CHECK_ERROR(sessionMachine, COMSETTER(FirmwareType)(FirmwareType_EFI));
668 }
669 else if (!RTStrICmp(ValueUnion.psz, "efi32"))
670 {
671 CHECK_ERROR(sessionMachine, COMSETTER(FirmwareType)(FirmwareType_EFI32));
672 }
673 else if (!RTStrICmp(ValueUnion.psz, "efi64"))
674 {
675 CHECK_ERROR(sessionMachine, COMSETTER(FirmwareType)(FirmwareType_EFI64));
676 }
677 else if (!RTStrICmp(ValueUnion.psz, "efidual"))
678 {
679 CHECK_ERROR(sessionMachine, COMSETTER(FirmwareType)(FirmwareType_EFIDUAL));
680 }
681 else if (!RTStrICmp(ValueUnion.psz, "bios"))
682 {
683 CHECK_ERROR(sessionMachine, COMSETTER(FirmwareType)(FirmwareType_BIOS));
684 }
685 else
686 {
687 errorArgument("Invalid --firmware argument '%s'", ValueUnion.psz);
688 rc = E_FAIL;
689 }
690 break;
691 }
692
693 case MODIFYVM_ACPI:
694 {
695 CHECK_ERROR(biosSettings, COMSETTER(ACPIEnabled)(ValueUnion.f));
696 break;
697 }
698
699 case MODIFYVM_IOAPIC:
700 {
701 CHECK_ERROR(biosSettings, COMSETTER(IOAPICEnabled)(ValueUnion.f));
702 break;
703 }
704
705 case MODIFYVM_PAE:
706 {
707 CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_PAE, ValueUnion.f));
708 break;
709 }
710
711 case MODIFYVM_LONGMODE:
712 {
713 CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_LongMode, ValueUnion.f));
714 break;
715 }
716
717 case MODIFYVM_CPUID_PORTABILITY:
718 {
719 CHECK_ERROR(sessionMachine, COMSETTER(CPUIDPortabilityLevel)(ValueUnion.u32));
720 break;
721 }
722
723 case MODIFYVM_TFRESET:
724 {
725 CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_TripleFaultReset, ValueUnion.f));
726 break;
727 }
728
729 case MODIFYVM_APIC:
730 {
731 CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_APIC, ValueUnion.f));
732 break;
733 }
734
735 case MODIFYVM_X2APIC:
736 {
737 CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_X2APIC, ValueUnion.f));
738 break;
739 }
740
741 case MODIFYVM_PARAVIRTPROVIDER:
742 {
743 if ( !RTStrICmp(ValueUnion.psz, "none")
744 || !RTStrICmp(ValueUnion.psz, "disabled"))
745 CHECK_ERROR(sessionMachine, COMSETTER(ParavirtProvider)(ParavirtProvider_None));
746 else if (!RTStrICmp(ValueUnion.psz, "default"))
747 CHECK_ERROR(sessionMachine, COMSETTER(ParavirtProvider)(ParavirtProvider_Default));
748 else if (!RTStrICmp(ValueUnion.psz, "legacy"))
749 CHECK_ERROR(sessionMachine, COMSETTER(ParavirtProvider)(ParavirtProvider_Legacy));
750 else if (!RTStrICmp(ValueUnion.psz, "minimal"))
751 CHECK_ERROR(sessionMachine, COMSETTER(ParavirtProvider)(ParavirtProvider_Minimal));
752 else if (!RTStrICmp(ValueUnion.psz, "hyperv"))
753 CHECK_ERROR(sessionMachine, COMSETTER(ParavirtProvider)(ParavirtProvider_HyperV));
754 else if (!RTStrICmp(ValueUnion.psz, "kvm"))
755 CHECK_ERROR(sessionMachine, COMSETTER(ParavirtProvider)(ParavirtProvider_KVM));
756 else
757 {
758 errorArgument("Invalid --paravirtprovider argument '%s'", ValueUnion.psz);
759 rc = E_FAIL;
760 }
761 break;
762 }
763
764 case MODIFYVM_PARAVIRTDEBUG:
765 {
766 CHECK_ERROR(sessionMachine, COMSETTER(ParavirtDebug)(Bstr(ValueUnion.psz).raw()));
767 break;
768 }
769
770 case MODIFYVM_HWVIRTEX:
771 {
772 CHECK_ERROR(sessionMachine, SetHWVirtExProperty(HWVirtExPropertyType_Enabled, ValueUnion.f));
773 break;
774 }
775
776 case MODIFYVM_SETCPUID:
777 case MODIFYVM_SETCPUID_OLD:
778 {
779 uint32_t const idx = c == MODIFYVM_SETCPUID ? ValueUnion.PairU32.uFirst : ValueUnion.u32;
780 uint32_t const idxSub = c == MODIFYVM_SETCPUID ? ValueUnion.PairU32.uSecond : UINT32_MAX;
781 uint32_t aValue[4];
782 for (unsigned i = 0; i < 4; i++)
783 {
784 int vrc = RTGetOptFetchValue(&GetOptState, &ValueUnion, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_HEX);
785 if (RT_FAILURE(vrc))
786 return errorSyntax(USAGE_MODIFYVM, "Missing or Invalid argument to '%s'", GetOptState.pDef->pszLong);
787 aValue[i] = ValueUnion.u32;
788 }
789 CHECK_ERROR(sessionMachine, SetCPUIDLeaf(idx, idxSub, aValue[0], aValue[1], aValue[2], aValue[3]));
790 break;
791 }
792
793 case MODIFYVM_DELCPUID:
794 CHECK_ERROR(sessionMachine, RemoveCPUIDLeaf(ValueUnion.PairU32.uFirst, ValueUnion.PairU32.uSecond));
795 break;
796
797 case MODIFYVM_DELCPUID_OLD:
798 CHECK_ERROR(sessionMachine, RemoveCPUIDLeaf(ValueUnion.u32, UINT32_MAX));
799 break;
800
801 case MODIFYVM_DELALLCPUID:
802 {
803 CHECK_ERROR(sessionMachine, RemoveAllCPUIDLeaves());
804 break;
805 }
806
807 case MODIFYVM_NESTEDPAGING:
808 {
809 CHECK_ERROR(sessionMachine, SetHWVirtExProperty(HWVirtExPropertyType_NestedPaging, ValueUnion.f));
810 break;
811 }
812
813 case MODIFYVM_LARGEPAGES:
814 {
815 CHECK_ERROR(sessionMachine, SetHWVirtExProperty(HWVirtExPropertyType_LargePages, ValueUnion.f));
816 break;
817 }
818
819 case MODIFYVM_VTXVPID:
820 {
821 CHECK_ERROR(sessionMachine, SetHWVirtExProperty(HWVirtExPropertyType_VPID, ValueUnion.f));
822 break;
823 }
824
825 case MODIFYVM_VTXUX:
826 {
827 CHECK_ERROR(sessionMachine, SetHWVirtExProperty(HWVirtExPropertyType_UnrestrictedExecution, ValueUnion.f));
828 break;
829 }
830
831 case MODIFYVM_VIRT_VMSAVE_VMLOAD:
832 CHECK_ERROR(sessionMachine, SetHWVirtExProperty(HWVirtExPropertyType_VirtVmsaveVmload, ValueUnion.f));
833 break;
834
835 case MODIFYVM_IBPB_ON_VM_EXIT:
836 CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_IBPBOnVMExit, ValueUnion.f));
837 break;
838
839 case MODIFYVM_IBPB_ON_VM_ENTRY:
840 CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_IBPBOnVMEntry, ValueUnion.f));
841 break;
842
843 case MODIFYVM_SPEC_CTRL:
844 CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_SpecCtrl, ValueUnion.f));
845 break;
846
847 case MODIFYVM_L1D_FLUSH_ON_SCHED:
848 CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_L1DFlushOnEMTScheduling, ValueUnion.f));
849 break;
850
851 case MODIFYVM_L1D_FLUSH_ON_VM_ENTRY:
852 CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_L1DFlushOnVMEntry, ValueUnion.f));
853 break;
854
855 case MODIFYVM_MDS_CLEAR_ON_SCHED:
856 CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_MDSClearOnEMTScheduling, ValueUnion.f));
857 break;
858
859 case MODIFYVM_MDS_CLEAR_ON_VM_ENTRY:
860 CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_MDSClearOnVMEntry, ValueUnion.f));
861 break;
862
863 case MODIFYVM_NESTED_HW_VIRT:
864 CHECK_ERROR(sessionMachine, SetCPUProperty(CPUPropertyType_HWVirt, ValueUnion.f));
865 break;
866
867 case MODIFYVM_CPUS:
868 {
869 CHECK_ERROR(sessionMachine, COMSETTER(CPUCount)(ValueUnion.u32));
870 break;
871 }
872
873 case MODIFYVM_RTCUSEUTC:
874 {
875 CHECK_ERROR(sessionMachine, COMSETTER(RTCUseUTC)(ValueUnion.f));
876 break;
877 }
878
879 case MODIFYVM_CPUHOTPLUG:
880 {
881 CHECK_ERROR(sessionMachine, COMSETTER(CPUHotPlugEnabled)(ValueUnion.f));
882 break;
883 }
884
885 case MODIFYVM_CPU_PROFILE:
886 {
887 CHECK_ERROR(sessionMachine, COMSETTER(CPUProfile)(Bstr(ValueUnion.psz).raw()));
888 break;
889 }
890
891 case MODIFYVM_PLUGCPU:
892 {
893 CHECK_ERROR(sessionMachine, HotPlugCPU(ValueUnion.u32));
894 break;
895 }
896
897 case MODIFYVM_UNPLUGCPU:
898 {
899 CHECK_ERROR(sessionMachine, HotUnplugCPU(ValueUnion.u32));
900 break;
901 }
902
903 case MODIFYVM_CPU_EXECTUION_CAP:
904 {
905 CHECK_ERROR(sessionMachine, COMSETTER(CPUExecutionCap)(ValueUnion.u32));
906 break;
907 }
908
909 case MODIFYVM_GRAPHICSCONTROLLER:
910 {
911 if ( !RTStrICmp(ValueUnion.psz, "none")
912 || !RTStrICmp(ValueUnion.psz, "disabled"))
913 CHECK_ERROR(pGraphicsAdapter, COMSETTER(GraphicsControllerType)(GraphicsControllerType_Null));
914 else if ( !RTStrICmp(ValueUnion.psz, "vboxvga")
915 || !RTStrICmp(ValueUnion.psz, "vbox")
916 || !RTStrICmp(ValueUnion.psz, "vga")
917 || !RTStrICmp(ValueUnion.psz, "vesa"))
918 CHECK_ERROR(pGraphicsAdapter, COMSETTER(GraphicsControllerType)(GraphicsControllerType_VBoxVGA));
919#ifdef VBOX_WITH_VMSVGA
920 else if ( !RTStrICmp(ValueUnion.psz, "vmsvga")
921 || !RTStrICmp(ValueUnion.psz, "vmware"))
922 CHECK_ERROR(pGraphicsAdapter, COMSETTER(GraphicsControllerType)(GraphicsControllerType_VMSVGA));
923 else if ( !RTStrICmp(ValueUnion.psz, "vboxsvga")
924 || !RTStrICmp(ValueUnion.psz, "svga"))
925 CHECK_ERROR(pGraphicsAdapter, COMSETTER(GraphicsControllerType)(GraphicsControllerType_VBoxSVGA));
926#endif
927 else
928 {
929 errorArgument("Invalid --graphicscontroller argument '%s'", ValueUnion.psz);
930 rc = E_FAIL;
931 }
932 break;
933 }
934
935 case MODIFYVM_MONITORCOUNT:
936 {
937 CHECK_ERROR(pGraphicsAdapter, COMSETTER(MonitorCount)(ValueUnion.u32));
938 break;
939 }
940
941 case MODIFYVM_ACCELERATE3D:
942 {
943 CHECK_ERROR(pGraphicsAdapter, COMSETTER(Accelerate3DEnabled)(ValueUnion.f));
944 break;
945 }
946
947#ifdef VBOX_WITH_VIDEOHWACCEL
948 case MODIFYVM_ACCELERATE2DVIDEO:
949 {
950 CHECK_ERROR(pGraphicsAdapter, COMSETTER(Accelerate2DVideoEnabled)(ValueUnion.f));
951 break;
952 }
953#endif
954
955 case MODIFYVM_BIOSLOGOFADEIN:
956 {
957 CHECK_ERROR(biosSettings, COMSETTER(LogoFadeIn)(ValueUnion.f));
958 break;
959 }
960
961 case MODIFYVM_BIOSLOGOFADEOUT:
962 {
963 CHECK_ERROR(biosSettings, COMSETTER(LogoFadeOut)(ValueUnion.f));
964 break;
965 }
966
967 case MODIFYVM_BIOSLOGODISPLAYTIME:
968 {
969 CHECK_ERROR(biosSettings, COMSETTER(LogoDisplayTime)(ValueUnion.u32));
970 break;
971 }
972
973 case MODIFYVM_BIOSLOGOIMAGEPATH:
974 {
975 CHECK_ERROR(biosSettings, COMSETTER(LogoImagePath)(Bstr(ValueUnion.psz).raw()));
976 break;
977 }
978
979 case MODIFYVM_BIOSBOOTMENU:
980 {
981 if (!RTStrICmp(ValueUnion.psz, "disabled"))
982 {
983 CHECK_ERROR(biosSettings, COMSETTER(BootMenuMode)(BIOSBootMenuMode_Disabled));
984 }
985 else if (!RTStrICmp(ValueUnion.psz, "menuonly"))
986 {
987 CHECK_ERROR(biosSettings, COMSETTER(BootMenuMode)(BIOSBootMenuMode_MenuOnly));
988 }
989 else if (!RTStrICmp(ValueUnion.psz, "messageandmenu"))
990 {
991 CHECK_ERROR(biosSettings, COMSETTER(BootMenuMode)(BIOSBootMenuMode_MessageAndMenu));
992 }
993 else
994 {
995 errorArgument("Invalid --biosbootmenu argument '%s'", ValueUnion.psz);
996 rc = E_FAIL;
997 }
998 break;
999 }
1000
1001 case MODIFYVM_BIOSAPIC:
1002 {
1003 if (!RTStrICmp(ValueUnion.psz, "disabled"))
1004 {
1005 CHECK_ERROR(biosSettings, COMSETTER(APICMode)(APICMode_Disabled));
1006 }
1007 else if ( !RTStrICmp(ValueUnion.psz, "apic")
1008 || !RTStrICmp(ValueUnion.psz, "lapic")
1009 || !RTStrICmp(ValueUnion.psz, "xapic"))
1010 {
1011 CHECK_ERROR(biosSettings, COMSETTER(APICMode)(APICMode_APIC));
1012 }
1013 else if (!RTStrICmp(ValueUnion.psz, "x2apic"))
1014 {
1015 CHECK_ERROR(biosSettings, COMSETTER(APICMode)(APICMode_X2APIC));
1016 }
1017 else
1018 {
1019 errorArgument("Invalid --biosapic argument '%s'", ValueUnion.psz);
1020 rc = E_FAIL;
1021 }
1022 break;
1023 }
1024
1025 case MODIFYVM_BIOSSYSTEMTIMEOFFSET:
1026 {
1027 CHECK_ERROR(biosSettings, COMSETTER(TimeOffset)(ValueUnion.i64));
1028 break;
1029 }
1030
1031 case MODIFYVM_BIOSPXEDEBUG:
1032 {
1033 CHECK_ERROR(biosSettings, COMSETTER(PXEDebugEnabled)(ValueUnion.f));
1034 break;
1035 }
1036
1037 case MODIFYVM_SYSTEMUUIDLE:
1038 {
1039 CHECK_ERROR(biosSettings, COMSETTER(SMBIOSUuidLittleEndian)(ValueUnion.f));
1040 break;
1041 }
1042
1043 case MODIFYVM_BOOT:
1044 {
1045 if (!RTStrICmp(ValueUnion.psz, "none"))
1046 {
1047 CHECK_ERROR(sessionMachine, SetBootOrder(GetOptState.uIndex, DeviceType_Null));
1048 }
1049 else if (!RTStrICmp(ValueUnion.psz, "floppy"))
1050 {
1051 CHECK_ERROR(sessionMachine, SetBootOrder(GetOptState.uIndex, DeviceType_Floppy));
1052 }
1053 else if (!RTStrICmp(ValueUnion.psz, "dvd"))
1054 {
1055 CHECK_ERROR(sessionMachine, SetBootOrder(GetOptState.uIndex, DeviceType_DVD));
1056 }
1057 else if (!RTStrICmp(ValueUnion.psz, "disk"))
1058 {
1059 CHECK_ERROR(sessionMachine, SetBootOrder(GetOptState.uIndex, DeviceType_HardDisk));
1060 }
1061 else if (!RTStrICmp(ValueUnion.psz, "net"))
1062 {
1063 CHECK_ERROR(sessionMachine, SetBootOrder(GetOptState.uIndex, DeviceType_Network));
1064 }
1065 else
1066 return errorArgument("Invalid boot device '%s'", ValueUnion.psz);
1067 break;
1068 }
1069
1070 case MODIFYVM_HDA: // deprecated
1071 case MODIFYVM_HDB: // deprecated
1072 case MODIFYVM_HDD: // deprecated
1073 case MODIFYVM_SATAPORT: // deprecated
1074 {
1075 uint32_t u1 = 0, u2 = 0;
1076 Bstr bstrController = L"IDE Controller";
1077
1078 switch (c)
1079 {
1080 case MODIFYVM_HDA: // deprecated
1081 u1 = 0;
1082 break;
1083
1084 case MODIFYVM_HDB: // deprecated
1085 u1 = 0;
1086 u2 = 1;
1087 break;
1088
1089 case MODIFYVM_HDD: // deprecated
1090 u1 = 1;
1091 u2 = 1;
1092 break;
1093
1094 case MODIFYVM_SATAPORT: // deprecated
1095 u1 = GetOptState.uIndex;
1096 bstrController = L"SATA";
1097 break;
1098 }
1099
1100 if (!RTStrICmp(ValueUnion.psz, "none"))
1101 {
1102 sessionMachine->DetachDevice(bstrController.raw(), u1, u2);
1103 }
1104 else
1105 {
1106 ComPtr<IMedium> hardDisk;
1107 rc = openMedium(a, ValueUnion.psz, DeviceType_HardDisk,
1108 AccessMode_ReadWrite, hardDisk,
1109 false /* fForceNewUuidOnOpen */,
1110 false /* fSilent */);
1111 if (FAILED(rc))
1112 break;
1113 if (hardDisk)
1114 {
1115 CHECK_ERROR(sessionMachine, AttachDevice(bstrController.raw(),
1116 u1, u2,
1117 DeviceType_HardDisk,
1118 hardDisk));
1119 }
1120 else
1121 rc = E_FAIL;
1122 }
1123 break;
1124 }
1125
1126 case MODIFYVM_IDECONTROLLER: // deprecated
1127 {
1128 ComPtr<IStorageController> storageController;
1129 CHECK_ERROR(sessionMachine, GetStorageControllerByName(Bstr("IDE Controller").raw(),
1130 storageController.asOutParam()));
1131
1132 if (!RTStrICmp(ValueUnion.psz, "PIIX3"))
1133 {
1134 CHECK_ERROR(storageController, COMSETTER(ControllerType)(StorageControllerType_PIIX3));
1135 }
1136 else if (!RTStrICmp(ValueUnion.psz, "PIIX4"))
1137 {
1138 CHECK_ERROR(storageController, COMSETTER(ControllerType)(StorageControllerType_PIIX4));
1139 }
1140 else if (!RTStrICmp(ValueUnion.psz, "ICH6"))
1141 {
1142 CHECK_ERROR(storageController, COMSETTER(ControllerType)(StorageControllerType_ICH6));
1143 }
1144 else
1145 {
1146 errorArgument("Invalid --idecontroller argument '%s'", ValueUnion.psz);
1147 rc = E_FAIL;
1148 }
1149 break;
1150 }
1151
1152 case MODIFYVM_SATAPORTCOUNT: // deprecated
1153 {
1154 ComPtr<IStorageController> SataCtl;
1155 CHECK_ERROR(sessionMachine, GetStorageControllerByName(Bstr("SATA").raw(),
1156 SataCtl.asOutParam()));
1157
1158 if (SUCCEEDED(rc) && ValueUnion.u32 > 0)
1159 CHECK_ERROR(SataCtl, COMSETTER(PortCount)(ValueUnion.u32));
1160 break;
1161 }
1162
1163 case MODIFYVM_SATA: // deprecated
1164 {
1165 if (!RTStrICmp(ValueUnion.psz, "on") || !RTStrICmp(ValueUnion.psz, "enable"))
1166 {
1167 ComPtr<IStorageController> ctl;
1168 CHECK_ERROR(sessionMachine, AddStorageController(Bstr("SATA").raw(),
1169 StorageBus_SATA,
1170 ctl.asOutParam()));
1171 CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_IntelAhci));
1172 }
1173 else if (!RTStrICmp(ValueUnion.psz, "off") || !RTStrICmp(ValueUnion.psz, "disable"))
1174 CHECK_ERROR(sessionMachine, RemoveStorageController(Bstr("SATA").raw()));
1175 else
1176 return errorArgument("Invalid --usb argument '%s'", ValueUnion.psz);
1177 break;
1178 }
1179
1180 case MODIFYVM_SCSIPORT: // deprecated
1181 {
1182 if (!RTStrICmp(ValueUnion.psz, "none"))
1183 {
1184 rc = sessionMachine->DetachDevice(Bstr("LsiLogic").raw(),
1185 GetOptState.uIndex, 0);
1186 if (FAILED(rc))
1187 CHECK_ERROR(sessionMachine, DetachDevice(Bstr("BusLogic").raw(),
1188 GetOptState.uIndex, 0));
1189 }
1190 else
1191 {
1192 ComPtr<IMedium> hardDisk;
1193 rc = openMedium(a, ValueUnion.psz, DeviceType_HardDisk,
1194 AccessMode_ReadWrite, hardDisk,
1195 false /* fForceNewUuidOnOpen */,
1196 false /* fSilent */);
1197 if (FAILED(rc))
1198 break;
1199 if (hardDisk)
1200 {
1201 rc = sessionMachine->AttachDevice(Bstr("LsiLogic").raw(),
1202 GetOptState.uIndex, 0,
1203 DeviceType_HardDisk,
1204 hardDisk);
1205 if (FAILED(rc))
1206 CHECK_ERROR(sessionMachine,
1207 AttachDevice(Bstr("BusLogic").raw(),
1208 GetOptState.uIndex, 0,
1209 DeviceType_HardDisk,
1210 hardDisk));
1211 }
1212 else
1213 rc = E_FAIL;
1214 }
1215 break;
1216 }
1217
1218 case MODIFYVM_SCSITYPE: // deprecated
1219 {
1220 ComPtr<IStorageController> ctl;
1221
1222 if (!RTStrICmp(ValueUnion.psz, "LsiLogic"))
1223 {
1224 rc = sessionMachine->RemoveStorageController(Bstr("BusLogic").raw());
1225 if (FAILED(rc))
1226 CHECK_ERROR(sessionMachine, RemoveStorageController(Bstr("LsiLogic").raw()));
1227
1228 CHECK_ERROR(sessionMachine,
1229 AddStorageController(Bstr("LsiLogic").raw(),
1230 StorageBus_SCSI,
1231 ctl.asOutParam()));
1232
1233 if (SUCCEEDED(rc))
1234 CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_LsiLogic));
1235 }
1236 else if (!RTStrICmp(ValueUnion.psz, "BusLogic"))
1237 {
1238 rc = sessionMachine->RemoveStorageController(Bstr("LsiLogic").raw());
1239 if (FAILED(rc))
1240 CHECK_ERROR(sessionMachine, RemoveStorageController(Bstr("BusLogic").raw()));
1241
1242 CHECK_ERROR(sessionMachine,
1243 AddStorageController(Bstr("BusLogic").raw(),
1244 StorageBus_SCSI,
1245 ctl.asOutParam()));
1246
1247 if (SUCCEEDED(rc))
1248 CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_BusLogic));
1249 }
1250 else
1251 return errorArgument("Invalid --scsitype argument '%s'", ValueUnion.psz);
1252 break;
1253 }
1254
1255 case MODIFYVM_SCSI: // deprecated
1256 {
1257 if (!RTStrICmp(ValueUnion.psz, "on") || !RTStrICmp(ValueUnion.psz, "enable"))
1258 {
1259 ComPtr<IStorageController> ctl;
1260
1261 CHECK_ERROR(sessionMachine, AddStorageController(Bstr("BusLogic").raw(),
1262 StorageBus_SCSI,
1263 ctl.asOutParam()));
1264 if (SUCCEEDED(rc))
1265 CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_BusLogic));
1266 }
1267 else if (!RTStrICmp(ValueUnion.psz, "off") || !RTStrICmp(ValueUnion.psz, "disable"))
1268 {
1269 rc = sessionMachine->RemoveStorageController(Bstr("BusLogic").raw());
1270 if (FAILED(rc))
1271 CHECK_ERROR(sessionMachine, RemoveStorageController(Bstr("LsiLogic").raw()));
1272 }
1273 break;
1274 }
1275
1276 case MODIFYVM_DVDPASSTHROUGH: // deprecated
1277 {
1278 CHECK_ERROR(sessionMachine, PassthroughDevice(Bstr("IDE Controller").raw(),
1279 1, 0,
1280 !RTStrICmp(ValueUnion.psz, "on")));
1281 break;
1282 }
1283
1284 case MODIFYVM_DVD: // deprecated
1285 {
1286 ComPtr<IMedium> dvdMedium;
1287
1288 /* unmount? */
1289 if (!RTStrICmp(ValueUnion.psz, "none"))
1290 {
1291 /* nothing to do, NULL object will cause unmount */
1292 }
1293 /* host drive? */
1294 else if (!RTStrNICmp(ValueUnion.psz, RT_STR_TUPLE("host:")))
1295 {
1296 ComPtr<IHost> host;
1297 CHECK_ERROR(a->virtualBox, COMGETTER(Host)(host.asOutParam()));
1298 rc = host->FindHostDVDDrive(Bstr(ValueUnion.psz + 5).raw(),
1299 dvdMedium.asOutParam());
1300 if (!dvdMedium)
1301 {
1302 /* 2nd try: try with the real name, important on Linux+libhal */
1303 char szPathReal[RTPATH_MAX];
1304 if (RT_FAILURE(RTPathReal(ValueUnion.psz + 5, szPathReal, sizeof(szPathReal))))
1305 {
1306 errorArgument("Invalid host DVD drive name \"%s\"", ValueUnion.psz + 5);
1307 rc = E_FAIL;
1308 break;
1309 }
1310 rc = host->FindHostDVDDrive(Bstr(szPathReal).raw(),
1311 dvdMedium.asOutParam());
1312 if (!dvdMedium)
1313 {
1314 errorArgument("Invalid host DVD drive name \"%s\"", ValueUnion.psz + 5);
1315 rc = E_FAIL;
1316 break;
1317 }
1318 }
1319 }
1320 else
1321 {
1322 rc = openMedium(a, ValueUnion.psz, DeviceType_DVD,
1323 AccessMode_ReadOnly, dvdMedium,
1324 false /* fForceNewUuidOnOpen */,
1325 false /* fSilent */);
1326 if (FAILED(rc))
1327 break;
1328 if (!dvdMedium)
1329 {
1330 rc = E_FAIL;
1331 break;
1332 }
1333 }
1334
1335 CHECK_ERROR(sessionMachine, MountMedium(Bstr("IDE Controller").raw(),
1336 1, 0,
1337 dvdMedium,
1338 FALSE /* aForce */));
1339 break;
1340 }
1341
1342 case MODIFYVM_FLOPPY: // deprecated
1343 {
1344 ComPtr<IMedium> floppyMedium;
1345 ComPtr<IMediumAttachment> floppyAttachment;
1346 sessionMachine->GetMediumAttachment(Bstr("Floppy Controller").raw(),
1347 0, 0, floppyAttachment.asOutParam());
1348
1349 /* disable? */
1350 if (!RTStrICmp(ValueUnion.psz, "disabled"))
1351 {
1352 /* disable the controller */
1353 if (floppyAttachment)
1354 CHECK_ERROR(sessionMachine, DetachDevice(Bstr("Floppy Controller").raw(),
1355 0, 0));
1356 }
1357 else
1358 {
1359 /* enable the controller */
1360 if (!floppyAttachment)
1361 CHECK_ERROR(sessionMachine, AttachDeviceWithoutMedium(Bstr("Floppy Controller").raw(),
1362 0, 0,
1363 DeviceType_Floppy));
1364
1365 /* unmount? */
1366 if ( !RTStrICmp(ValueUnion.psz, "none")
1367 || !RTStrICmp(ValueUnion.psz, "empty")) // deprecated
1368 {
1369 /* nothing to do, NULL object will cause unmount */
1370 }
1371 /* host drive? */
1372 else if (!RTStrNICmp(ValueUnion.psz, RT_STR_TUPLE("host:")))
1373 {
1374 ComPtr<IHost> host;
1375 CHECK_ERROR(a->virtualBox, COMGETTER(Host)(host.asOutParam()));
1376 rc = host->FindHostFloppyDrive(Bstr(ValueUnion.psz + 5).raw(),
1377 floppyMedium.asOutParam());
1378 if (!floppyMedium)
1379 {
1380 errorArgument("Invalid host floppy drive name \"%s\"", ValueUnion.psz + 5);
1381 rc = E_FAIL;
1382 break;
1383 }
1384 }
1385 else
1386 {
1387 rc = openMedium(a, ValueUnion.psz, DeviceType_Floppy,
1388 AccessMode_ReadWrite, floppyMedium,
1389 false /* fForceNewUuidOnOpen */,
1390 false /* fSilent */);
1391 if (FAILED(rc))
1392 break;
1393 if (!floppyMedium)
1394 {
1395 rc = E_FAIL;
1396 break;
1397 }
1398 }
1399 CHECK_ERROR(sessionMachine, MountMedium(Bstr("Floppy Controller").raw(),
1400 0, 0,
1401 floppyMedium,
1402 FALSE /* aForce */));
1403 }
1404 break;
1405 }
1406
1407 case MODIFYVM_NICTRACEFILE:
1408 {
1409
1410 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1411 break;
1412
1413 ComPtr<INetworkAdapter> nic;
1414 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1415 ASSERT(nic);
1416
1417 CHECK_ERROR(nic, COMSETTER(TraceFile)(Bstr(ValueUnion.psz).raw()));
1418 break;
1419 }
1420
1421 case MODIFYVM_NICTRACE:
1422 {
1423 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1424 break;
1425
1426 ComPtr<INetworkAdapter> nic;
1427 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1428 ASSERT(nic);
1429
1430 CHECK_ERROR(nic, COMSETTER(TraceEnabled)(ValueUnion.f));
1431 break;
1432 }
1433
1434 case MODIFYVM_NICPROPERTY:
1435 {
1436 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1437 break;
1438
1439 ComPtr<INetworkAdapter> nic;
1440 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1441 ASSERT(nic);
1442
1443 if (nic)
1444 {
1445 /* Parse 'name=value' */
1446 char *pszProperty = RTStrDup(ValueUnion.psz);
1447 if (pszProperty)
1448 {
1449 char *pDelimiter = strchr(pszProperty, '=');
1450 if (pDelimiter)
1451 {
1452 *pDelimiter = '\0';
1453
1454 Bstr bstrName = pszProperty;
1455 Bstr bstrValue = &pDelimiter[1];
1456 CHECK_ERROR(nic, SetProperty(bstrName.raw(), bstrValue.raw()));
1457 }
1458 else
1459 {
1460 errorArgument("Invalid --nicproperty%d argument '%s'", GetOptState.uIndex, ValueUnion.psz);
1461 rc = E_FAIL;
1462 }
1463 RTStrFree(pszProperty);
1464 }
1465 else
1466 {
1467 RTStrmPrintf(g_pStdErr, "Error: Failed to allocate memory for --nicproperty%d '%s'\n", GetOptState.uIndex, ValueUnion.psz);
1468 rc = E_FAIL;
1469 }
1470 }
1471 break;
1472 }
1473 case MODIFYVM_NICTYPE:
1474 {
1475 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1476 break;
1477
1478 ComPtr<INetworkAdapter> nic;
1479 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1480 ASSERT(nic);
1481
1482 if (!RTStrICmp(ValueUnion.psz, "Am79C970A"))
1483 {
1484 CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_Am79C970A));
1485 }
1486 else if (!RTStrICmp(ValueUnion.psz, "Am79C973"))
1487 {
1488 CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_Am79C973));
1489 }
1490 else if (!RTStrICmp(ValueUnion.psz, "Am79C960"))
1491 {
1492 CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_Am79C960));
1493 }
1494#ifdef VBOX_WITH_E1000
1495 else if (!RTStrICmp(ValueUnion.psz, "82540EM"))
1496 {
1497 CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_I82540EM));
1498 }
1499 else if (!RTStrICmp(ValueUnion.psz, "82543GC"))
1500 {
1501 CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_I82543GC));
1502 }
1503 else if (!RTStrICmp(ValueUnion.psz, "82545EM"))
1504 {
1505 CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_I82545EM));
1506 }
1507#endif
1508#ifdef VBOX_WITH_VIRTIO
1509 else if (!RTStrICmp(ValueUnion.psz, "virtio"))
1510 {
1511 CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_Virtio));
1512 }
1513#endif /* VBOX_WITH_VIRTIO */
1514#ifdef VBOX_WITH_VIRTIO_NET_1_0
1515 else if (!RTStrICmp(ValueUnion.psz, "virtio_1.0"))
1516 {
1517 CHECK_ERROR(nic, COMSETTER(AdapterType)(NetworkAdapterType_Virtio_1_0));
1518 }
1519#endif /* VBOX_WITH_VIRTIO_NET_1_0 */
1520 else
1521 {
1522 errorArgument("Invalid NIC type '%s' specified for NIC %u", ValueUnion.psz, GetOptState.uIndex);
1523 rc = E_FAIL;
1524 }
1525 break;
1526 }
1527
1528 case MODIFYVM_NICSPEED:
1529 {
1530 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1531 break;
1532
1533 ComPtr<INetworkAdapter> nic;
1534 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1535 ASSERT(nic);
1536
1537 CHECK_ERROR(nic, COMSETTER(LineSpeed)(ValueUnion.u32));
1538 break;
1539 }
1540
1541 case MODIFYVM_NICBOOTPRIO:
1542 {
1543 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1544 break;
1545
1546 ComPtr<INetworkAdapter> nic;
1547 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1548 ASSERT(nic);
1549
1550 /* Somewhat arbitrary limitation - we can pass a list of up to 4 PCI devices
1551 * to the PXE ROM, hence only boot priorities 1-4 are allowed (in addition to
1552 * 0 for the default lowest priority).
1553 */
1554 if (ValueUnion.u32 > 4)
1555 {
1556 errorArgument("Invalid boot priority '%u' specfied for NIC %u", ValueUnion.u32, GetOptState.uIndex);
1557 rc = E_FAIL;
1558 }
1559 else
1560 {
1561 CHECK_ERROR(nic, COMSETTER(BootPriority)(ValueUnion.u32));
1562 }
1563 break;
1564 }
1565
1566 case MODIFYVM_NICPROMISC:
1567 {
1568 NetworkAdapterPromiscModePolicy_T enmPromiscModePolicy;
1569 if (!RTStrICmp(ValueUnion.psz, "deny"))
1570 enmPromiscModePolicy = NetworkAdapterPromiscModePolicy_Deny;
1571 else if ( !RTStrICmp(ValueUnion.psz, "allow-vms")
1572 || !RTStrICmp(ValueUnion.psz, "allow-network"))
1573 enmPromiscModePolicy = NetworkAdapterPromiscModePolicy_AllowNetwork;
1574 else if (!RTStrICmp(ValueUnion.psz, "allow-all"))
1575 enmPromiscModePolicy = NetworkAdapterPromiscModePolicy_AllowAll;
1576 else
1577 {
1578 errorArgument("Unknown promiscuous mode policy '%s'", ValueUnion.psz);
1579 rc = E_INVALIDARG;
1580 break;
1581 }
1582
1583 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1584 break;
1585
1586 ComPtr<INetworkAdapter> nic;
1587 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1588 ASSERT(nic);
1589
1590 CHECK_ERROR(nic, COMSETTER(PromiscModePolicy)(enmPromiscModePolicy));
1591 break;
1592 }
1593
1594 case MODIFYVM_NICBWGROUP:
1595 {
1596 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1597 break;
1598
1599 ComPtr<INetworkAdapter> nic;
1600 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1601 ASSERT(nic);
1602
1603 if (!RTStrICmp(ValueUnion.psz, "none"))
1604 {
1605 /* Just remove the bandwidth group. */
1606 CHECK_ERROR(nic, COMSETTER(BandwidthGroup)(NULL));
1607 }
1608 else
1609 {
1610 ComPtr<IBandwidthControl> bwCtrl;
1611 ComPtr<IBandwidthGroup> bwGroup;
1612
1613 CHECK_ERROR(sessionMachine, COMGETTER(BandwidthControl)(bwCtrl.asOutParam()));
1614
1615 if (SUCCEEDED(rc))
1616 {
1617 CHECK_ERROR(bwCtrl, GetBandwidthGroup(Bstr(ValueUnion.psz).raw(), bwGroup.asOutParam()));
1618 if (SUCCEEDED(rc))
1619 {
1620 CHECK_ERROR(nic, COMSETTER(BandwidthGroup)(bwGroup));
1621 }
1622 }
1623 }
1624 break;
1625 }
1626
1627 case MODIFYVM_NIC:
1628 {
1629 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1630 break;
1631
1632 ComPtr<INetworkAdapter> nic;
1633 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1634 ASSERT(nic);
1635
1636 /*
1637 * Check if the NIC is already enabled. Do not try to
1638 * enable it if it already is. That makes a
1639 * difference for saved VMs for which you can change
1640 * the NIC attachment, but can't change the NIC
1641 * enabled status (yes, the setter also should not
1642 * freak out about a no-op request).
1643 */
1644 BOOL fEnabled;;
1645 CHECK_ERROR(nic, COMGETTER(Enabled)(&fEnabled));
1646
1647 if (!RTStrICmp(ValueUnion.psz, "none"))
1648 {
1649 if (RT_BOOL(fEnabled))
1650 CHECK_ERROR(nic, COMSETTER(Enabled)(FALSE));
1651 }
1652 else if (!RTStrICmp(ValueUnion.psz, "null"))
1653 {
1654 if (!fEnabled)
1655 CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE));
1656 CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_Null));
1657 }
1658 else if (!RTStrICmp(ValueUnion.psz, "nat"))
1659 {
1660 if (!fEnabled)
1661 CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE));
1662 CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_NAT));
1663 }
1664 else if ( !RTStrICmp(ValueUnion.psz, "bridged")
1665 || !RTStrICmp(ValueUnion.psz, "hostif")) /* backward compatibility */
1666 {
1667 if (!fEnabled)
1668 CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE));
1669 CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_Bridged));
1670 }
1671 else if (!RTStrICmp(ValueUnion.psz, "intnet"))
1672 {
1673 if (!fEnabled)
1674 CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE));
1675 CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_Internal));
1676 }
1677 else if (!RTStrICmp(ValueUnion.psz, "hostonly"))
1678 {
1679 if (!fEnabled)
1680 CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE));
1681 CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_HostOnly));
1682 }
1683 else if (!RTStrICmp(ValueUnion.psz, "generic"))
1684 {
1685 if (!fEnabled)
1686 CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE));
1687 CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_Generic));
1688 }
1689 else if (!RTStrICmp(ValueUnion.psz, "natnetwork"))
1690 {
1691 if (!fEnabled)
1692 CHECK_ERROR(nic, COMSETTER(Enabled)(TRUE));
1693 CHECK_ERROR(nic, COMSETTER(AttachmentType)(NetworkAttachmentType_NATNetwork));
1694 }
1695 else
1696 {
1697 errorArgument("Invalid type '%s' specfied for NIC %u", ValueUnion.psz, GetOptState.uIndex);
1698 rc = E_FAIL;
1699 }
1700 break;
1701 }
1702
1703 case MODIFYVM_CABLECONNECTED:
1704 {
1705 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1706 break;
1707
1708 ComPtr<INetworkAdapter> nic;
1709 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1710 ASSERT(nic);
1711
1712 CHECK_ERROR(nic, COMSETTER(CableConnected)(ValueUnion.f));
1713 break;
1714 }
1715
1716 case MODIFYVM_BRIDGEADAPTER:
1717 {
1718 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1719 break;
1720
1721 ComPtr<INetworkAdapter> nic;
1722 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1723 ASSERT(nic);
1724
1725 /* remove it? */
1726 if (!RTStrICmp(ValueUnion.psz, "none"))
1727 {
1728 CHECK_ERROR(nic, COMSETTER(BridgedInterface)(Bstr().raw()));
1729 }
1730 else
1731 {
1732 CHECK_ERROR(nic, COMSETTER(BridgedInterface)(Bstr(ValueUnion.psz).raw()));
1733 verifyHostNetworkInterfaceName(a->virtualBox, ValueUnion.psz,
1734 HostNetworkInterfaceType_Bridged);
1735 }
1736 break;
1737 }
1738
1739 case MODIFYVM_HOSTONLYADAPTER:
1740 {
1741 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1742 break;
1743
1744 ComPtr<INetworkAdapter> nic;
1745 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1746 ASSERT(nic);
1747
1748 /* remove it? */
1749 if (!RTStrICmp(ValueUnion.psz, "none"))
1750 {
1751 CHECK_ERROR(nic, COMSETTER(HostOnlyInterface)(Bstr().raw()));
1752 }
1753 else
1754 {
1755 CHECK_ERROR(nic, COMSETTER(HostOnlyInterface)(Bstr(ValueUnion.psz).raw()));
1756 verifyHostNetworkInterfaceName(a->virtualBox, ValueUnion.psz,
1757 HostNetworkInterfaceType_HostOnly);
1758 }
1759 break;
1760 }
1761
1762 case MODIFYVM_INTNET:
1763 {
1764 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1765 break;
1766
1767 ComPtr<INetworkAdapter> nic;
1768 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1769 ASSERT(nic);
1770
1771 /* remove it? */
1772 if (!RTStrICmp(ValueUnion.psz, "none"))
1773 {
1774 CHECK_ERROR(nic, COMSETTER(InternalNetwork)(Bstr().raw()));
1775 }
1776 else
1777 {
1778 CHECK_ERROR(nic, COMSETTER(InternalNetwork)(Bstr(ValueUnion.psz).raw()));
1779 }
1780 break;
1781 }
1782
1783 case MODIFYVM_GENERICDRV:
1784 {
1785 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1786 break;
1787
1788 ComPtr<INetworkAdapter> nic;
1789 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1790 ASSERT(nic);
1791
1792 CHECK_ERROR(nic, COMSETTER(GenericDriver)(Bstr(ValueUnion.psz).raw()));
1793 break;
1794 }
1795
1796 case MODIFYVM_NATNETWORKNAME:
1797 {
1798 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1799 break;
1800
1801 ComPtr<INetworkAdapter> nic;
1802 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1803 ASSERT(nic);
1804
1805 CHECK_ERROR(nic, COMSETTER(NATNetwork)(Bstr(ValueUnion.psz).raw()));
1806 break;
1807 }
1808
1809 case MODIFYVM_NATNET:
1810 {
1811 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1812 break;
1813
1814 ComPtr<INetworkAdapter> nic;
1815 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1816 ASSERT(nic);
1817
1818 ComPtr<INATEngine> engine;
1819 CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
1820
1821 const char *psz = ValueUnion.psz;
1822 if (!RTStrICmp("default", psz))
1823 psz = "";
1824
1825 CHECK_ERROR(engine, COMSETTER(Network)(Bstr(psz).raw()));
1826 break;
1827 }
1828
1829 case MODIFYVM_NATBINDIP:
1830 {
1831 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1832 break;
1833
1834 ComPtr<INetworkAdapter> nic;
1835 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1836 ASSERT(nic);
1837
1838 ComPtr<INATEngine> engine;
1839 CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
1840
1841 CHECK_ERROR(engine, COMSETTER(HostIP)(Bstr(ValueUnion.psz).raw()));
1842 break;
1843 }
1844
1845#define ITERATE_TO_NEXT_TERM(ch) \
1846 do { \
1847 while (*ch != ',') \
1848 { \
1849 if (*ch == 0) \
1850 { \
1851 return errorSyntax(USAGE_MODIFYVM, \
1852 "Missing or Invalid argument to '%s'", \
1853 GetOptState.pDef->pszLong); \
1854 } \
1855 ch++; \
1856 } \
1857 *ch = '\0'; \
1858 ch++; \
1859 } while(0)
1860
1861 case MODIFYVM_NATSETTINGS:
1862 {
1863 ComPtr<INetworkAdapter> nic;
1864 ComPtr<INATEngine> engine;
1865 char *strMtu;
1866 char *strSockSnd;
1867 char *strSockRcv;
1868 char *strTcpSnd;
1869 char *strTcpRcv;
1870 char *strRaw = RTStrDup(ValueUnion.psz);
1871 char *ch = strRaw;
1872 strMtu = RTStrStrip(ch);
1873 ITERATE_TO_NEXT_TERM(ch);
1874 strSockSnd = RTStrStrip(ch);
1875 ITERATE_TO_NEXT_TERM(ch);
1876 strSockRcv = RTStrStrip(ch);
1877 ITERATE_TO_NEXT_TERM(ch);
1878 strTcpSnd = RTStrStrip(ch);
1879 ITERATE_TO_NEXT_TERM(ch);
1880 strTcpRcv = RTStrStrip(ch);
1881
1882 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1883 break;
1884
1885 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1886 ASSERT(nic);
1887
1888 CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
1889 CHECK_ERROR(engine, SetNetworkSettings(RTStrToUInt32(strMtu), RTStrToUInt32(strSockSnd), RTStrToUInt32(strSockRcv),
1890 RTStrToUInt32(strTcpSnd), RTStrToUInt32(strTcpRcv)));
1891 break;
1892 }
1893
1894
1895 case MODIFYVM_NATPF:
1896 {
1897 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1898 break;
1899
1900 ComPtr<INetworkAdapter> nic;
1901 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1902 ASSERT(nic);
1903
1904 ComPtr<INATEngine> engine;
1905 CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
1906
1907 /* format name:proto:hostip:hostport:guestip:guestport*/
1908 if (RTStrCmp(ValueUnion.psz, "delete") != 0)
1909 {
1910 char *strName;
1911 char *strProto;
1912 char *strHostIp;
1913 char *strHostPort;
1914 char *strGuestIp;
1915 char *strGuestPort;
1916 char *strRaw = RTStrDup(ValueUnion.psz);
1917 char *ch = strRaw;
1918 strName = RTStrStrip(ch);
1919 ITERATE_TO_NEXT_TERM(ch);
1920 strProto = RTStrStrip(ch);
1921 ITERATE_TO_NEXT_TERM(ch);
1922 strHostIp = RTStrStrip(ch);
1923 ITERATE_TO_NEXT_TERM(ch);
1924 strHostPort = RTStrStrip(ch);
1925 ITERATE_TO_NEXT_TERM(ch);
1926 strGuestIp = RTStrStrip(ch);
1927 ITERATE_TO_NEXT_TERM(ch);
1928 strGuestPort = RTStrStrip(ch);
1929 NATProtocol_T proto;
1930 if (RTStrICmp(strProto, "udp") == 0)
1931 proto = NATProtocol_UDP;
1932 else if (RTStrICmp(strProto, "tcp") == 0)
1933 proto = NATProtocol_TCP;
1934 else
1935 {
1936 errorArgument("Invalid proto '%s' specfied for NIC %u", ValueUnion.psz, GetOptState.uIndex);
1937 rc = E_FAIL;
1938 break;
1939 }
1940 CHECK_ERROR(engine, AddRedirect(Bstr(strName).raw(), proto,
1941 Bstr(strHostIp).raw(),
1942 RTStrToUInt16(strHostPort),
1943 Bstr(strGuestIp).raw(),
1944 RTStrToUInt16(strGuestPort)));
1945 }
1946 else
1947 {
1948 /* delete NAT Rule operation */
1949 int vrc;
1950 vrc = RTGetOptFetchValue(&GetOptState, &ValueUnion, RTGETOPT_REQ_STRING);
1951 if (RT_FAILURE(vrc))
1952 return errorSyntax(USAGE_MODIFYVM, "Not enough parameters");
1953 CHECK_ERROR(engine, RemoveRedirect(Bstr(ValueUnion.psz).raw()));
1954 }
1955 break;
1956 }
1957 #undef ITERATE_TO_NEXT_TERM
1958 case MODIFYVM_NATALIASMODE:
1959 {
1960 ComPtr<INetworkAdapter> nic;
1961 ComPtr<INATEngine> engine;
1962 uint32_t aliasMode = 0;
1963
1964 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1965 ASSERT(nic);
1966
1967 CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
1968 if (RTStrCmp(ValueUnion.psz, "default") == 0)
1969 aliasMode = 0;
1970 else
1971 {
1972 char *token = (char *)ValueUnion.psz;
1973 while (token)
1974 {
1975 if (RTStrNCmp(token, RT_STR_TUPLE("log")) == 0)
1976 aliasMode |= NATAliasMode_AliasLog;
1977 else if (RTStrNCmp(token, RT_STR_TUPLE("proxyonly")) == 0)
1978 aliasMode |= NATAliasMode_AliasProxyOnly;
1979 else if (RTStrNCmp(token, RT_STR_TUPLE("sameports")) == 0)
1980 aliasMode |= NATAliasMode_AliasUseSamePorts;
1981 token = RTStrStr(token, ",");
1982 if (token == NULL)
1983 break;
1984 token++;
1985 }
1986 }
1987 CHECK_ERROR(engine, COMSETTER(AliasMode)(aliasMode));
1988 break;
1989 }
1990
1991 case MODIFYVM_NATTFTPPREFIX:
1992 {
1993 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
1994 break;
1995
1996 ComPtr<INetworkAdapter> nic;
1997 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
1998 ASSERT(nic);
1999
2000 ComPtr<INATEngine> engine;
2001 CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
2002
2003 CHECK_ERROR(engine, COMSETTER(TFTPPrefix)(Bstr(ValueUnion.psz).raw()));
2004 break;
2005 }
2006
2007 case MODIFYVM_NATTFTPFILE:
2008 {
2009 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
2010 break;
2011
2012 ComPtr<INetworkAdapter> nic;
2013 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
2014 ASSERT(nic);
2015
2016 ComPtr<INATEngine> engine;
2017 CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
2018
2019 CHECK_ERROR(engine, COMSETTER(TFTPBootFile)(Bstr(ValueUnion.psz).raw()));
2020 break;
2021 }
2022
2023 case MODIFYVM_NATTFTPSERVER:
2024 {
2025 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
2026 break;
2027
2028 ComPtr<INetworkAdapter> nic;
2029 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
2030 ASSERT(nic);
2031
2032 ComPtr<INATEngine> engine;
2033 CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
2034
2035 CHECK_ERROR(engine, COMSETTER(TFTPNextServer)(Bstr(ValueUnion.psz).raw()));
2036 break;
2037 }
2038 case MODIFYVM_NATDNSPASSDOMAIN:
2039 {
2040 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
2041 break;
2042
2043 ComPtr<INetworkAdapter> nic;
2044 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
2045 ASSERT(nic);
2046
2047 ComPtr<INATEngine> engine;
2048 CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
2049
2050 CHECK_ERROR(engine, COMSETTER(DNSPassDomain)(ValueUnion.f));
2051 break;
2052 }
2053
2054 case MODIFYVM_NATDNSPROXY:
2055 {
2056 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
2057 break;
2058
2059 ComPtr<INetworkAdapter> nic;
2060 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
2061 ASSERT(nic);
2062
2063 ComPtr<INATEngine> engine;
2064 CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
2065
2066 CHECK_ERROR(engine, COMSETTER(DNSProxy)(ValueUnion.f));
2067 break;
2068 }
2069
2070 case MODIFYVM_NATDNSHOSTRESOLVER:
2071 {
2072 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
2073 break;
2074
2075 ComPtr<INetworkAdapter> nic;
2076 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
2077 ASSERT(nic);
2078
2079 ComPtr<INATEngine> engine;
2080 CHECK_ERROR(nic, COMGETTER(NATEngine)(engine.asOutParam()));
2081
2082 CHECK_ERROR(engine, COMSETTER(DNSUseHostResolver)(ValueUnion.f));
2083 break;
2084 }
2085 case MODIFYVM_MACADDRESS:
2086 {
2087 if (!parseNum(GetOptState.uIndex, NetworkAdapterCount, "NIC"))
2088 break;
2089
2090 ComPtr<INetworkAdapter> nic;
2091 CHECK_ERROR_BREAK(sessionMachine, GetNetworkAdapter(GetOptState.uIndex - 1, nic.asOutParam()));
2092 ASSERT(nic);
2093
2094 /* generate one? */
2095 if (!RTStrICmp(ValueUnion.psz, "auto"))
2096 {
2097 CHECK_ERROR(nic, COMSETTER(MACAddress)(Bstr().raw()));
2098 }
2099 else
2100 {
2101 CHECK_ERROR(nic, COMSETTER(MACAddress)(Bstr(ValueUnion.psz).raw()));
2102 }
2103 break;
2104 }
2105
2106 case MODIFYVM_HIDPTR:
2107 {
2108 bool fEnableUsb = false;
2109 if (!RTStrICmp(ValueUnion.psz, "ps2"))
2110 {
2111 CHECK_ERROR(sessionMachine, COMSETTER(PointingHIDType)(PointingHIDType_PS2Mouse));
2112 }
2113 else if (!RTStrICmp(ValueUnion.psz, "usb"))
2114 {
2115 CHECK_ERROR(sessionMachine, COMSETTER(PointingHIDType)(PointingHIDType_USBMouse));
2116 if (SUCCEEDED(rc))
2117 fEnableUsb = true;
2118 }
2119 else if (!RTStrICmp(ValueUnion.psz, "usbtablet"))
2120 {
2121 CHECK_ERROR(sessionMachine, COMSETTER(PointingHIDType)(PointingHIDType_USBTablet));
2122 if (SUCCEEDED(rc))
2123 fEnableUsb = true;
2124 }
2125 else if (!RTStrICmp(ValueUnion.psz, "usbmultitouch"))
2126 {
2127 CHECK_ERROR(sessionMachine, COMSETTER(PointingHIDType)(PointingHIDType_USBMultiTouch));
2128 if (SUCCEEDED(rc))
2129 fEnableUsb = true;
2130 }
2131 else
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#if defined(VBOX_WITH_IOMMU_AMD) || defined(VBOX_WITH_IOMMU_INTEL)
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 else if (!RTStrICmp(ValueUnion.psz, "intel"))
3024 {
3025#ifdef VBOX_WITH_IOMMU_INTEL
3026 CHECK_ERROR(sessionMachine, COMSETTER(IommuType)(IommuType_Intel));
3027#else
3028 errorArgument("Invalid --iommu argument '%s' (valid: none,amd,automatic)", ValueUnion.psz);
3029 rc = E_FAIL;
3030#endif
3031 }
3032 else if (!RTStrICmp(ValueUnion.psz, "automatic"))
3033 {
3034 CHECK_ERROR(sessionMachine, COMSETTER(IommuType)(IommuType_Automatic));
3035#ifndef VBOX_WITH_IOMMU_INTEL
3036 RTStrmPrintf(g_pStdErr,
3037 "Warning: On Intel hosts, 'automatic' will not enable an IOMMU since the Intel IOMMU device is not supported yet.\n");
3038#endif
3039 }
3040 else
3041 {
3042 errorArgument("Invalid --iommu argument '%s'", ValueUnion.psz);
3043 rc = E_FAIL;
3044 }
3045 break;
3046 }
3047#endif
3048#ifdef VBOX_WITH_RECORDING
3049 case MODIFYVM_RECORDING:
3050 RT_FALL_THROUGH();
3051 case MODIFYVM_RECORDING_SCREENS:
3052 RT_FALL_THROUGH();
3053 case MODIFYVM_RECORDING_FILENAME:
3054 RT_FALL_THROUGH();
3055 case MODIFYVM_RECORDING_VIDEO_WIDTH:
3056 RT_FALL_THROUGH();
3057 case MODIFYVM_RECORDING_VIDEO_HEIGHT:
3058 RT_FALL_THROUGH();
3059 case MODIFYVM_RECORDING_VIDEO_RES:
3060 RT_FALL_THROUGH();
3061 case MODIFYVM_RECORDING_VIDEO_RATE:
3062 RT_FALL_THROUGH();
3063 case MODIFYVM_RECORDING_VIDEO_FPS:
3064 RT_FALL_THROUGH();
3065 case MODIFYVM_RECORDING_MAXTIME:
3066 RT_FALL_THROUGH();
3067 case MODIFYVM_RECORDING_MAXSIZE:
3068 RT_FALL_THROUGH();
3069 case MODIFYVM_RECORDING_OPTIONS:
3070 {
3071 ComPtr<IRecordingSettings> recordingSettings;
3072 CHECK_ERROR_BREAK(sessionMachine, COMGETTER(RecordingSettings)(recordingSettings.asOutParam()));
3073 SafeIfaceArray <IRecordingScreenSettings> saRecordingScreenScreens;
3074 CHECK_ERROR_BREAK(recordingSettings, COMGETTER(Screens)(ComSafeArrayAsOutParam(saRecordingScreenScreens)));
3075
3076 switch (c)
3077 {
3078 case MODIFYVM_RECORDING:
3079 {
3080 CHECK_ERROR(recordingSettings, COMSETTER(Enabled)(ValueUnion.f));
3081 break;
3082 }
3083 case MODIFYVM_RECORDING_SCREENS:
3084 {
3085 ULONG cMonitors = 64;
3086 CHECK_ERROR(pGraphicsAdapter, COMGETTER(MonitorCount)(&cMonitors));
3087 com::SafeArray<BOOL> screens(cMonitors);
3088 if (parseScreens(ValueUnion.psz, &screens))
3089 {
3090 errorArgument("Invalid list of screens specified\n");
3091 rc = E_FAIL;
3092 break;
3093 }
3094
3095 if (cMonitors > saRecordingScreenScreens.size()) /* Paranoia. */
3096 cMonitors = (ULONG)saRecordingScreenScreens.size();
3097
3098 for (size_t i = 0; i < cMonitors; ++i)
3099 CHECK_ERROR_BREAK(saRecordingScreenScreens[i], COMSETTER(Enabled)(screens[i]));
3100 break;
3101 }
3102 case MODIFYVM_RECORDING_FILENAME:
3103 {
3104 Bstr bstr;
3105 /* empty string will fall through, leaving bstr empty */
3106 if (*ValueUnion.psz)
3107 {
3108 char szVCFileAbs[RTPATH_MAX] = "";
3109 int vrc = RTPathAbs(ValueUnion.psz, szVCFileAbs, sizeof(szVCFileAbs));
3110 if (RT_FAILURE(vrc))
3111 {
3112 errorArgument("Cannot convert filename \"%s\" to absolute path\n", ValueUnion.psz);
3113 rc = E_FAIL;
3114 break;
3115 }
3116 bstr = szVCFileAbs;
3117 }
3118
3119 for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
3120 CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(Filename)(bstr.raw()));
3121 break;
3122 }
3123 case MODIFYVM_RECORDING_VIDEO_WIDTH:
3124 {
3125 for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
3126 CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(VideoWidth)(ValueUnion.u32));
3127 break;
3128 }
3129 case MODIFYVM_RECORDING_VIDEO_HEIGHT:
3130 {
3131 for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
3132 CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(VideoHeight)(ValueUnion.u32));
3133 break;
3134 }
3135 case MODIFYVM_RECORDING_VIDEO_RES:
3136 {
3137 uint32_t uWidth = 0;
3138 char *pszNext;
3139 int vrc = RTStrToUInt32Ex(ValueUnion.psz, &pszNext, 0, &uWidth);
3140 if (RT_FAILURE(vrc) || vrc != VWRN_TRAILING_CHARS || !pszNext || *pszNext != 'x')
3141 {
3142 errorArgument("Error parsing video resolution '%s' (expected <width>x<height>)", ValueUnion.psz);
3143 rc = E_FAIL;
3144 break;
3145 }
3146 uint32_t uHeight = 0;
3147 vrc = RTStrToUInt32Ex(pszNext+1, NULL, 0, &uHeight);
3148 if (vrc != VINF_SUCCESS)
3149 {
3150 errorArgument("Error parsing video resolution '%s' (expected <width>x<height>)", ValueUnion.psz);
3151 rc = E_FAIL;
3152 break;
3153 }
3154
3155 for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
3156 {
3157 CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(VideoWidth)(uWidth));
3158 CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(VideoHeight)(uHeight));
3159 }
3160 break;
3161 }
3162 case MODIFYVM_RECORDING_VIDEO_RATE:
3163 {
3164 for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
3165 CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(VideoRate)(ValueUnion.u32));
3166 break;
3167 }
3168 case MODIFYVM_RECORDING_VIDEO_FPS:
3169 {
3170 for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
3171 CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(VideoFPS)(ValueUnion.u32));
3172 break;
3173 }
3174 case MODIFYVM_RECORDING_MAXTIME:
3175 {
3176 for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
3177 CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(MaxTime)(ValueUnion.u32));
3178 break;
3179 }
3180 case MODIFYVM_RECORDING_MAXSIZE:
3181 {
3182 for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
3183 CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(MaxFileSize)(ValueUnion.u32));
3184 break;
3185 }
3186 case MODIFYVM_RECORDING_OPTIONS:
3187 {
3188 Bstr bstr(ValueUnion.psz);
3189 for (size_t i = 0; i < saRecordingScreenScreens.size(); ++i)
3190 CHECK_ERROR(saRecordingScreenScreens[i], COMSETTER(Options)(bstr.raw()));
3191 break;
3192 }
3193 }
3194
3195 break;
3196 }
3197#endif
3198 case MODIFYVM_AUTOSTART_ENABLED:
3199 {
3200 CHECK_ERROR(sessionMachine, COMSETTER(AutostartEnabled)(ValueUnion.f));
3201 break;
3202 }
3203
3204 case MODIFYVM_AUTOSTART_DELAY:
3205 {
3206 CHECK_ERROR(sessionMachine, COMSETTER(AutostartDelay)(ValueUnion.u32));
3207 break;
3208 }
3209
3210 case MODIFYVM_AUTOSTOP_TYPE:
3211 {
3212 AutostopType_T enmAutostopType = AutostopType_Disabled;
3213
3214 if (!RTStrICmp(ValueUnion.psz, "disabled"))
3215 enmAutostopType = AutostopType_Disabled;
3216 else if (!RTStrICmp(ValueUnion.psz, "savestate"))
3217 enmAutostopType = AutostopType_SaveState;
3218 else if (!RTStrICmp(ValueUnion.psz, "poweroff"))
3219 enmAutostopType = AutostopType_PowerOff;
3220 else if (!RTStrICmp(ValueUnion.psz, "acpishutdown"))
3221 enmAutostopType = AutostopType_AcpiShutdown;
3222 else
3223 {
3224 errorArgument("Invalid --autostop-type argument '%s' (valid: disabled, savestate, poweroff, acpishutdown)", ValueUnion.psz);
3225 rc = E_FAIL;
3226 }
3227
3228 if (SUCCEEDED(rc))
3229 CHECK_ERROR(sessionMachine, COMSETTER(AutostopType)(enmAutostopType));
3230 break;
3231 }
3232#ifdef VBOX_WITH_PCI_PASSTHROUGH
3233 case MODIFYVM_ATTACH_PCI:
3234 {
3235 const char* pAt = strchr(ValueUnion.psz, '@');
3236 int32_t iHostAddr, iGuestAddr;
3237
3238 iHostAddr = parsePci(ValueUnion.psz);
3239 iGuestAddr = pAt != NULL ? parsePci(pAt + 1) : iHostAddr;
3240
3241 if (iHostAddr == -1 || iGuestAddr == -1)
3242 {
3243 errorArgument("Invalid --pciattach argument '%s' (valid: 'HB:HD.HF@GB:GD.GF' or just 'HB:HD.HF')", ValueUnion.psz);
3244 rc = E_FAIL;
3245 }
3246 else
3247 {
3248 CHECK_ERROR(sessionMachine, AttachHostPCIDevice(iHostAddr, iGuestAddr, TRUE));
3249 }
3250
3251 break;
3252 }
3253 case MODIFYVM_DETACH_PCI:
3254 {
3255 int32_t iHostAddr;
3256
3257 iHostAddr = parsePci(ValueUnion.psz);
3258 if (iHostAddr == -1)
3259 {
3260 errorArgument("Invalid --pcidetach argument '%s' (valid: 'HB:HD.HF')", ValueUnion.psz);
3261 rc = E_FAIL;
3262 }
3263 else
3264 {
3265 CHECK_ERROR(sessionMachine, DetachHostPCIDevice(iHostAddr));
3266 }
3267
3268 break;
3269 }
3270#endif
3271
3272#ifdef VBOX_WITH_USB_CARDREADER
3273 case MODIFYVM_USBCARDREADER:
3274 {
3275 CHECK_ERROR(sessionMachine, COMSETTER(EmulatedUSBCardReaderEnabled)(ValueUnion.f));
3276 break;
3277 }
3278#endif /* VBOX_WITH_USB_CARDREADER */
3279
3280 case MODIFYVM_DEFAULTFRONTEND:
3281 {
3282 Bstr bstr(ValueUnion.psz);
3283 if (bstr == "default")
3284 bstr = Bstr::Empty;
3285 CHECK_ERROR(sessionMachine, COMSETTER(DefaultFrontend)(bstr.raw()));
3286 break;
3287 }
3288
3289 case MODIFYVM_VMPROC_PRIORITY:
3290 {
3291 VMProcPriority_T enmPriority = nameToVMProcPriority(ValueUnion.psz);
3292 if (enmPriority == VMProcPriority_Invalid)
3293 {
3294 errorArgument("Invalid --vm-process-priority '%s'", ValueUnion.psz);
3295 rc = E_FAIL;
3296 }
3297 else
3298 {
3299 CHECK_ERROR(sessionMachine, COMSETTER(VMProcessPriority)(enmPriority));
3300 }
3301 break;
3302 }
3303
3304 default:
3305 {
3306 errorGetOpt(USAGE_MODIFYVM, c, &ValueUnion);
3307 rc = E_FAIL;
3308 break;
3309 }
3310 }
3311 }
3312
3313 /* commit changes */
3314 if (SUCCEEDED(rc))
3315 CHECK_ERROR(sessionMachine, SaveSettings());
3316
3317 /* it's important to always close sessions */
3318 a->session->UnlockMachine();
3319
3320 return SUCCEEDED(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
3321}
3322
3323#endif /* !VBOX_ONLY_DOCS */
Note: See TracBrowser for help on using the repository browser.

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