VirtualBox

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

Last change on this file since 82290 was 81964, checked in by vboxsync, 5 years ago

Main/GraphicsAdapter: Split off a few attributes from Machine interface, which affects quite a few other interfaces.
Frontends/VirtualBox+VBoxManage+VBoxSDL+VBoxShell: Adapt accordingly.

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

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