VirtualBox

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

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

Devices: bugref:9932 DrvVMNet and host-only network initial implementation

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