VirtualBox

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

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

Main: bugref:1909: Added translation marks around messages of VBoxManage output

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