VirtualBox

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

Last change on this file since 10288 was 10220, checked in by vboxsync, 17 years ago

Frontends/VBoxManage: reverted r32673, which was wrong, and added missing ifdefs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 284.1 KB
Line 
1/** @file
2 *
3 * VBox frontends: VBoxManage (command-line interface)
4 *
5 * VBoxManage is VirtualBox's command-line interface. This is its rather
6 * long source.
7 */
8
9/*
10 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
11 *
12 * This file is part of VirtualBox Open Source Edition (OSE), as
13 * available from http://www.virtualbox.org. This file is free software;
14 * you can redistribute it and/or modify it under the terms of the GNU
15 * General Public License (GPL) as published by the Free Software
16 * Foundation, in version 2 as it comes in the "COPYING" file of the
17 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
18 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
19 *
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
21 * Clara, CA 95054 USA or visit http://www.sun.com if you need
22 * additional information or have any questions.
23 */
24
25
26/*******************************************************************************
27* Header Files *
28*******************************************************************************/
29
30#include <VBox/com/com.h>
31#include <VBox/com/string.h>
32#include <VBox/com/Guid.h>
33#include <VBox/com/array.h>
34#include <VBox/com/ErrorInfo.h>
35#include <VBox/com/EventQueue.h>
36
37#include <VBox/com/VirtualBox.h>
38
39#include <stdlib.h>
40#include <stdarg.h>
41
42#include <vector>
43#include <list>
44
45#include <iprt/runtime.h>
46#include <iprt/stream.h>
47#include <iprt/string.h>
48#include <iprt/asm.h>
49#include <iprt/uuid.h>
50#include <iprt/thread.h>
51#include <iprt/path.h>
52#include <iprt/param.h>
53#include <iprt/dir.h>
54#include <iprt/file.h>
55#include <iprt/env.h>
56#include <iprt/cidr.h>
57#include <VBox/err.h>
58#include <VBox/version.h>
59#include <VBox/VBoxHDD.h>
60
61#include "VBoxManage.h"
62
63using namespace com;
64
65/* missing XPCOM <-> COM wrappers */
66#ifndef STDMETHOD_
67# define STDMETHOD_(ret, meth) NS_IMETHOD_(ret) meth
68#endif
69#ifndef NS_GET_IID
70# define NS_GET_IID(I) IID_##I
71#endif
72#ifndef RT_OS_WINDOWS
73#define IUnknown nsISupports
74#endif
75
76/** command handler type */
77typedef DECLCALLBACK(int) FNHANDLER(int argc, char *argv[], ComPtr<IVirtualBox> aVirtualBox, ComPtr<ISession> aSession);
78typedef FNHANDLER *PFNHANDLER;
79
80/**
81 * Quick IUSBDevice implementation for detaching / attaching
82 * devices to the USB Controller.
83 */
84class MyUSBDevice : public IUSBDevice
85{
86public:
87 // public initializer/uninitializer for internal purposes only
88 MyUSBDevice(uint16_t a_u16VendorId, uint16_t a_u16ProductId, uint16_t a_bcdRevision, uint64_t a_u64SerialHash, const char *a_pszComment)
89 : m_usVendorId(a_u16VendorId), m_usProductId(a_u16ProductId),
90 m_bcdRevision(a_bcdRevision), m_u64SerialHash(a_u64SerialHash),
91 m_bstrComment(a_pszComment),
92 m_cRefs(0)
93 {
94 }
95
96 STDMETHOD_(ULONG, AddRef)(void)
97 {
98 return ASMAtomicIncU32(&m_cRefs);
99 }
100 STDMETHOD_(ULONG, Release)(void)
101 {
102 ULONG cRefs = ASMAtomicDecU32(&m_cRefs);
103 if (!cRefs)
104 delete this;
105 return cRefs;
106 }
107 STDMETHOD(QueryInterface)(const IID &iid, void **ppvObject)
108 {
109 Guid guid(iid);
110 if (guid == Guid(NS_GET_IID(IUnknown)))
111 *ppvObject = (IUnknown *)this;
112 else if (guid == Guid(NS_GET_IID(IUSBDevice)))
113 *ppvObject = (IUSBDevice *)this;
114 else
115 return E_NOINTERFACE;
116 AddRef();
117 return S_OK;
118 }
119
120 STDMETHOD(COMGETTER(Id))(GUIDPARAMOUT a_pId) { return E_NOTIMPL; }
121 STDMETHOD(COMGETTER(VendorId))(USHORT *a_pusVendorId) { *a_pusVendorId = m_usVendorId; return S_OK; }
122 STDMETHOD(COMGETTER(ProductId))(USHORT *a_pusProductId) { *a_pusProductId = m_usProductId; return S_OK; }
123 STDMETHOD(COMGETTER(Revision))(USHORT *a_pusRevision) { *a_pusRevision = m_bcdRevision; return S_OK; }
124 STDMETHOD(COMGETTER(SerialHash))(ULONG64 *a_pullSerialHash) { *a_pullSerialHash = m_u64SerialHash; return S_OK; }
125 STDMETHOD(COMGETTER(Manufacturer))(BSTR *a_pManufacturer) { return E_NOTIMPL; }
126 STDMETHOD(COMGETTER(Product))(BSTR *a_pProduct) { return E_NOTIMPL; }
127 STDMETHOD(COMGETTER(SerialNumber))(BSTR *a_pSerialNumber) { return E_NOTIMPL; }
128 STDMETHOD(COMGETTER(Address))(BSTR *a_pAddress) { return E_NOTIMPL; }
129
130private:
131 /** The vendor id of this USB device. */
132 USHORT m_usVendorId;
133 /** The product id of this USB device. */
134 USHORT m_usProductId;
135 /** The product revision number of this USB device.
136 * (high byte = integer; low byte = decimal) */
137 USHORT m_bcdRevision;
138 /** The USB serial hash of the device. */
139 uint64_t m_u64SerialHash;
140 /** The user comment string. */
141 Bstr m_bstrComment;
142 /** Reference counter. */
143 uint32_t volatile m_cRefs;
144};
145
146
147// types
148///////////////////////////////////////////////////////////////////////////////
149
150template <typename T>
151class Nullable
152{
153public:
154
155 Nullable() : mIsNull (true) {}
156 Nullable (const T &aValue, bool aIsNull = false)
157 : mIsNull (aIsNull), mValue (aValue) {}
158
159 bool isNull() const { return mIsNull; };
160 void setNull (bool aIsNull = true) { mIsNull = aIsNull; }
161
162 operator const T&() const { return mValue; }
163
164 Nullable &operator= (const T &aValue)
165 {
166 mValue = aValue;
167 mIsNull = false;
168 return *this;
169 }
170
171private:
172
173 bool mIsNull;
174 T mValue;
175};
176
177/** helper structure to encapsulate USB filter manipulation commands */
178struct USBFilterCmd
179{
180 struct USBFilter
181 {
182 USBFilter ()
183 : mAction (USBDeviceFilterAction_Null)
184 {}
185
186 Bstr mName;
187 Nullable <bool> mActive;
188 Bstr mVendorId;
189 Bstr mProductId;
190 Bstr mRevision;
191 Bstr mManufacturer;
192 Bstr mProduct;
193 Bstr mRemote;
194 Bstr mSerialNumber;
195 Nullable <ULONG> mMaskedInterfaces;
196 USBDeviceFilterAction_T mAction;
197 };
198
199 enum Action { Invalid, Add, Modify, Remove };
200
201 USBFilterCmd() : mAction (Invalid), mIndex (0), mGlobal (false) {}
202
203 Action mAction;
204 ULONG mIndex;
205 /** flag whether the command target is a global filter */
206 bool mGlobal;
207 /** machine this command is targeted at (null for global filters) */
208 ComPtr<IMachine> mMachine;
209 USBFilter mFilter;
210};
211
212// funcs
213///////////////////////////////////////////////////////////////////////////////
214
215static void showLogo(void)
216{
217 static bool fShown; /* show only once */
218
219 if (!fShown)
220 {
221 RTPrintf("VirtualBox Command Line Management Interface Version "
222 VBOX_VERSION_STRING "\n"
223 "(C) 2005-2008 Sun Microsystems, Inc.\n"
224 "All rights reserved.\n"
225 "\n");
226 fShown = true;
227 }
228}
229
230static void printUsage(USAGECATEGORY u64Cmd)
231{
232#ifdef RT_OS_LINUX
233 bool fLinux = true;
234#else
235 bool fLinux = false;
236#endif
237#ifdef RT_OS_WINDOWS
238 bool fWin = true;
239#else
240 bool fWin = false;
241#endif
242#ifdef RT_OS_SOLARIS
243 bool fSolaris = true;
244#else
245 bool fSolaris = false;
246#endif
247#ifdef RT_OS_DARWIN
248 bool fDarwin = true;
249#else
250 bool fDarwin = false;
251#endif
252#ifdef VBOX_VRDP
253 bool fVRDP = true;
254#else
255 bool fVRDP = false;
256#endif
257
258 if (u64Cmd == USAGE_DUMPOPTS)
259 {
260 fLinux = true;
261 fWin = true;
262 fSolaris = true;
263 fDarwin = true;
264 fVRDP = true;
265 u64Cmd = USAGE_ALL;
266 }
267
268 RTPrintf("Usage:\n"
269 "\n");
270
271 if (u64Cmd == USAGE_ALL)
272 {
273 RTPrintf("VBoxManage [-v|-version] print version number and exit\n"
274 "VBoxManage -nologo ... suppress the logo\n"
275 "\n"
276 "VBoxManage -convertSettings ... allow to auto-convert settings files\n"
277 "VBoxManage -convertSettingsBackup ... allow to auto-convert settings files\n"
278 " but create backup copies before\n"
279 "VBoxManage -convertSettingsIgnore ... allow to auto-convert settings files\n"
280 " but don't explicitly save the results\n"
281 "\n");
282 }
283
284 if (u64Cmd & USAGE_LIST)
285 {
286 RTPrintf("VBoxManage list vms|runningvms|ostypes|hostdvds|hostfloppies|\n");
287 if (fWin)
288 RTPrintf( "hostifs|");
289 RTPrintf(" hdds|dvds|floppies|usbhost|usbfilters|\n"
290 " systemproperties\n"
291 "\n");
292 }
293
294 if (u64Cmd & USAGE_SHOWVMINFO)
295 {
296 RTPrintf("VBoxManage showvminfo <uuid>|<name>\n"
297 " [-details]\n"
298 " [-statistics]\n"
299 " [-machinereadable]\n"
300 "\n");
301 }
302
303 if (u64Cmd & USAGE_REGISTERVM)
304 {
305 RTPrintf("VBoxManage registervm <filename>\n"
306 "\n");
307 }
308
309 if (u64Cmd & USAGE_UNREGISTERVM)
310 {
311 RTPrintf("VBoxManage unregistervm <uuid>|<name>\n"
312 " [-delete]\n"
313 "\n");
314 }
315
316 if (u64Cmd & USAGE_CREATEVM)
317 {
318 RTPrintf("VBoxManage createvm -name <name>\n"
319 " [-register]\n"
320 " [-basefolder <path> | -settingsfile <path>]\n"
321 " [-uuid <uuid>]\n"
322 " \n"
323 "\n");
324 }
325
326 if (u64Cmd & USAGE_MODIFYVM)
327 {
328 RTPrintf("VBoxManage modifyvm <uuid|name>\n"
329 " [-name <name>]\n"
330 " [-ostype <ostype>]\n"
331 " [-memory <memorysize>]\n"
332 " [-vram <vramsize>]\n"
333 " [-acpi on|off]\n"
334 " [-ioapic on|off]\n"
335 " [-pae on|off]\n"
336 " [-hwvirtex on|off|default]\n"
337 " [-monitorcount <number>]\n"
338 " [-bioslogofadein on|off]\n"
339 " [-bioslogofadeout on|off]\n"
340 " [-bioslogodisplaytime <msec>]\n"
341 " [-bioslogoimagepath <imagepath>]\n"
342 " [-biosbootmenu disabled|menuonly|messageandmenu]\n"
343 " [-biossystemtimeoffset <msec>]\n"
344 " [-biospxedebug on|off]\n"
345 " [-boot<1-4> none|floppy|dvd|disk|net>]\n"
346 " [-hd<a|b|d> none|<uuid>|<filename>]\n"
347#ifdef VBOX_WITH_AHCI
348 " [-sata on|off]\n"
349 " [-sataportcount <1-30>]\n"
350 " [-sataport<1-30> none|<uuid>|<filename>]\n"
351 " [-sataideemulation<1-4> <1-30>]\n"
352#endif
353 " [-dvd none|<uuid>|<filename>|host:<drive>]\n"
354 " [-dvdpassthrough on|off]\n"
355 " [-floppy disabled|empty|<uuid>|\n"
356 " <filename>|host:<drive>]\n"
357 " [-nic<1-N> none|null|nat|hostif|intnet]\n"
358 " [-nictype<1-N> Am79C970A|Am79C973"
359#ifdef VBOX_WITH_E1000
360 "|82540EM|82543GC"
361#endif
362 "]\n"
363 " [-cableconnected<1-N> on|off]\n"
364 " [-nictrace<1-N> on|off]\n"
365 " [-nictracefile<1-N> <filename>]\n"
366 " [-nicspeed<1-N> <kbps>]\n"
367 " [-hostifdev<1-N> none|<devicename>]\n"
368 " [-intnet<1-N> <network name>]\n"
369 " [-natnet<1-N> <network>|default]\n"
370 " [-macaddress<1-N> auto|<mac>]\n"
371 " [-uart<1-N> off|<I/O base> <IRQ>]\n"
372 " [-uartmode<1-N> disconnected|\n"
373 " server <pipe>|\n"
374 " client <pipe>|\n"
375 " <devicename>]\n"
376#ifdef VBOX_WITH_MEM_BALLOONING
377 " [-guestmemoryballoon <balloonsize>]\n"
378#endif
379 " [-gueststatisticsinterval <seconds>]\n"
380 );
381 if (fLinux)
382 {
383 RTPrintf(" [-tapsetup<1-N> none|<application>]\n"
384 " [-tapterminate<1-N> none|<application>]\n");
385 }
386 RTPrintf(" [-audio none|null");
387 if (fWin)
388 {
389#ifdef VBOX_WITH_WINMM
390 RTPrintf( "|winmm|dsound");
391#else
392 RTPrintf( "|dsound");
393#endif
394 }
395 if (fSolaris)
396 {
397 RTPrintf( "|solaudio");
398 }
399 if (fLinux)
400 {
401 RTPrintf( "|oss"
402#ifdef VBOX_WITH_ALSA
403 "|alsa"
404#endif
405#ifdef VBOX_WITH_PULSE
406 "|pulse"
407#endif
408 );
409 }
410 if (fDarwin)
411 {
412 RTPrintf( "|coreaudio");
413 }
414 RTPrintf( "]\n");
415 RTPrintf(" [-audiocontroller ac97|sb16]\n"
416 " [-clipboard disabled|hosttoguest|guesttohost|\n"
417 " bidirectional]\n");
418 if (fVRDP)
419 {
420 RTPrintf(" [-vrdp on|off]\n"
421 " [-vrdpport default|<port>]\n"
422 " [-vrdpaddress <host>]\n"
423 " [-vrdpauthtype null|external|guest]\n"
424 " [-vrdpmulticon on|off]\n");
425 }
426 RTPrintf(" [-usb on|off]\n"
427 " [-usbehci on|off]\n"
428 " [-snapshotfolder default|<path>]\n");
429 RTPrintf("\n");
430 }
431
432 if (u64Cmd & USAGE_STARTVM)
433 {
434 RTPrintf("VBoxManage startvm <uuid>|<name>\n");
435 if (fVRDP)
436 RTPrintf(" [-type gui|vrdp]\n");
437 RTPrintf("\n");
438 }
439
440 if (u64Cmd & USAGE_CONTROLVM)
441 {
442 RTPrintf("VBoxManage controlvm <uuid>|<name>\n"
443 " pause|resume|reset|poweroff|savestate|\n"
444 " acpipowerbutton|acpisleepbutton|\n"
445 " keyboardputscancode <hex> [<hex> ...]|\n"
446 " setlinkstate<1-4> on|off |\n"
447 " usbattach <uuid>|<address> |\n"
448 " usbdetach <uuid>|<address> |\n"
449 " dvdattach none|<uuid>|<filename>|host:<drive> |\n"
450 " floppyattach none|<uuid>|<filename>|host:<drive> |\n"
451 " setvideomodehint <xres> <yres> <bpp> [display]|\n"
452 " setcredentials <username> <password> <domain>\n"
453 " [-allowlocallogon <yes|no>]\n"
454 "\n");
455 }
456
457 if (u64Cmd & USAGE_DISCARDSTATE)
458 {
459 RTPrintf("VBoxManage discardstate <uuid>|<name>\n"
460 "\n");
461 }
462
463 if (u64Cmd & USAGE_ADOPTSTATE)
464 {
465 RTPrintf("VBoxManage adoptstate <uuid>|<name> <state_file>\n"
466 "\n");
467 }
468
469 if (u64Cmd & USAGE_SNAPSHOT)
470 {
471 RTPrintf("VBoxManage snapshot <uuid>|<name>\n"
472 " take <name> [-desc <desc>] |\n"
473 " discard <uuid>|<name> |\n"
474 " discardcurrent -state|-all |\n"
475 " edit <uuid>|<name>|-current\n"
476 " [-newname <name>]\n"
477 " [-newdesc <desc>] |\n"
478 " showvminfo <uuid>|<name>\n"
479 "\n");
480 }
481
482 if (u64Cmd & USAGE_REGISTERIMAGE)
483 {
484 RTPrintf("VBoxManage registerimage disk|dvd|floppy <filename>\n"
485 " [-type normal|immutable|writethrough] (disk only)\n"
486 "\n");
487 }
488
489 if (u64Cmd & USAGE_UNREGISTERIMAGE)
490 {
491 RTPrintf("VBoxManage unregisterimage disk|dvd|floppy <uuid>|<filename>\n"
492 "\n");
493 }
494
495 if (u64Cmd & USAGE_SHOWVDIINFO)
496 {
497 RTPrintf("VBoxManage showvdiinfo <uuid>|<filename>\n"
498 "\n");
499 }
500
501 if (u64Cmd & USAGE_CREATEVDI)
502 {
503 RTPrintf("VBoxManage createvdi -filename <filename>\n"
504 " -size <megabytes>\n"
505 " [-static]\n"
506 " [-comment <comment>]\n"
507 " [-register]\n"
508 " [-type normal|writethrough] (default: normal)\n"
509 "\n");
510 }
511
512 if (u64Cmd & USAGE_MODIFYVDI)
513 {
514 RTPrintf("VBoxManage modifyvdi <uuid>|<filename>\n"
515#if 0 /* doesn't currently work */
516 " settype normal|writethrough|immutable |\n"
517#endif
518 " compact\n"
519 "\n");
520 }
521
522 if (u64Cmd & USAGE_CLONEVDI)
523 {
524 RTPrintf("VBoxManage clonevdi <uuid>|<filename> <outputfile>\n"
525 "\n");
526 }
527
528 if (u64Cmd & USAGE_CONVERTDD)
529 {
530 RTPrintf("VBoxManage convertdd [-static] <filename> <outputfile>\n"
531 "VBoxManage convertdd [-static] stdin <outputfile> <bytes>\n"
532 "\n");
533 }
534
535 if (u64Cmd & USAGE_ADDISCSIDISK)
536 {
537 RTPrintf("VBoxManage addiscsidisk -server <name>|<ip>\n"
538 " -target <target>\n"
539 " [-port <port>]\n"
540 " [-lun <lun>]\n"
541 " [-encodedlun <lun>]\n"
542 " [-username <username>]\n"
543 " [-password <password>]\n"
544 " [-comment <comment>]\n"
545 "\n");
546 }
547
548 if (u64Cmd & USAGE_CREATEHOSTIF && fWin)
549 {
550 RTPrintf("VBoxManage createhostif <name>\n"
551 "\n");
552 }
553
554 if (u64Cmd & USAGE_REMOVEHOSTIF && fWin)
555 {
556 RTPrintf("VBoxManage removehostif <uuid>|<name>\n"
557 "\n");
558 }
559
560 if (u64Cmd & USAGE_GETEXTRADATA)
561 {
562 RTPrintf("VBoxManage getextradata global|<uuid>|<name>\n"
563 " <key>|enumerate\n"
564 "\n");
565 }
566
567 if (u64Cmd & USAGE_SETEXTRADATA)
568 {
569 RTPrintf("VBoxManage setextradata global|<uuid>|<name>\n"
570 " <key>\n"
571 " [<value>] (no value deletes key)\n"
572 "\n");
573 }
574
575 if (u64Cmd & USAGE_SETPROPERTY)
576 {
577 RTPrintf("VBoxManage setproperty vdifolder default|<folder> |\n"
578 " machinefolder default|<folder> |\n"
579 " vrdpauthlibrary default|<library> |\n"
580 " websrvauthlibrary default|null|<library> |\n"
581 " hwvirtexenabled yes|no\n"
582 " loghistorycount <value>\n"
583 "\n");
584 }
585
586 if (u64Cmd & USAGE_USBFILTER_ADD)
587 {
588 RTPrintf("VBoxManage usbfilter add <index,0-N>\n"
589 " -target <uuid>|<name>|global\n"
590 " -name <string>\n"
591 " -action ignore|hold (global filters only)\n"
592 " [-active yes|no] (yes)\n"
593 " [-vendorid <XXXX>] (null)\n"
594 " [-productid <XXXX>] (null)\n"
595 " [-revision <IIFF>] (null)\n"
596 " [-manufacturer <string>] (null)\n"
597 " [-product <string>] (null)\n"
598 " [-remote yes|no] (null, VM filters only)\n"
599 " [-serialnumber <string>] (null)\n"
600 " [-maskedinterfaces <XXXXXXXX>]\n"
601 "\n");
602 }
603
604 if (u64Cmd & USAGE_USBFILTER_MODIFY)
605 {
606 RTPrintf("VBoxManage usbfilter modify <index,0-N>\n"
607 " -target <uuid>|<name>|global\n"
608 " [-name <string>]\n"
609 " [-action ignore|hold] (global filters only)\n"
610 " [-active yes|no]\n"
611 " [-vendorid <XXXX>|\"\"]\n"
612 " [-productid <XXXX>|\"\"]\n"
613 " [-revision <IIFF>|\"\"]\n"
614 " [-manufacturer <string>|\"\"]\n"
615 " [-product <string>|\"\"]\n"
616 " [-remote yes|no] (null, VM filters only)\n"
617 " [-serialnumber <string>|\"\"]\n"
618 " [-maskedinterfaces <XXXXXXXX>]\n"
619 "\n");
620 }
621
622 if (u64Cmd & USAGE_USBFILTER_REMOVE)
623 {
624 RTPrintf("VBoxManage usbfilter remove <index,0-N>\n"
625 " -target <uuid>|<name>|global\n"
626 "\n");
627 }
628
629 if (u64Cmd & USAGE_SHAREDFOLDER_ADD)
630 {
631 RTPrintf("VBoxManage sharedfolder add <vmname>|<uuid>\n"
632 " -name <name> -hostpath <hostpath>\n"
633 " [-transient] [-readonly]\n"
634 "\n");
635 }
636
637 if (u64Cmd & USAGE_SHAREDFOLDER_REMOVE)
638 {
639 RTPrintf("VBoxManage sharedfolder remove <vmname>|<uuid>\n"
640 " -name <name> [-transient]\n"
641 "\n");
642 }
643
644 if (u64Cmd & USAGE_VM_STATISTICS)
645 {
646 RTPrintf("VBoxManage vmstatistics <vmname>|<uuid> [-reset]\n"
647 " [-pattern <pattern>] [-descriptions]\n"
648 "\n");
649 }
650
651#ifdef VBOX_WITH_INFO_SVC
652 if (u64Cmd & USAGE_GETGUESTPROPERTY)
653 {
654 RTPrintf("VBoxManage getguestproperty <vmname>|<uuid> <key>\n"
655 "\n");
656 }
657
658 if (u64Cmd & USAGE_SETGUESTPROPERTY)
659 {
660 RTPrintf("VBoxManage setguestproperty <vmname>|<uuid> <key>\n"
661 " [<value>] (no value deletes key)\n"
662 "\n");
663 }
664#endif /* VBOX_WITH_INFO_SVC defined */
665
666}
667
668/**
669 * Print a usage synopsis and the syntax error message.
670 */
671int errorSyntax(USAGECATEGORY u64Cmd, const char *pszFormat, ...)
672{
673 va_list args;
674 showLogo(); // show logo even if suppressed
675 if (g_fInternalMode)
676 printUsageInternal(u64Cmd);
677 else
678 printUsage(u64Cmd);
679 va_start(args, pszFormat);
680 RTPrintf("\n"
681 "Syntax error: %N\n", pszFormat, &args);
682 va_end(args);
683 return 1;
684}
685
686/**
687 * Print an error message without the syntax stuff.
688 */
689int errorArgument(const char *pszFormat, ...)
690{
691 va_list args;
692 va_start(args, pszFormat);
693 RTPrintf("error: %N\n", pszFormat, &args);
694 va_end(args);
695 return 1;
696}
697
698/**
699 * Print out progress on the console
700 */
701static void showProgress(ComPtr<IProgress> progress)
702{
703 BOOL fCompleted;
704 LONG currentPercent;
705 LONG lastPercent = 0;
706
707 RTPrintf("0%%...");
708 RTStrmFlush(g_pStdOut);
709 while (SUCCEEDED(progress->COMGETTER(Completed(&fCompleted))))
710 {
711 progress->COMGETTER(Percent(&currentPercent));
712
713 /* did we cross a 10% mark? */
714 if (((currentPercent / 10) > (lastPercent / 10)))
715 {
716 /* make sure to also print out missed steps */
717 for (LONG curVal = (lastPercent / 10) * 10 + 10; curVal <= (currentPercent / 10) * 10; curVal += 10)
718 {
719 if (curVal < 100)
720 {
721 RTPrintf("%ld%%...", curVal);
722 RTStrmFlush(g_pStdOut);
723 }
724 }
725 lastPercent = (currentPercent / 10) * 10;
726 }
727 if (fCompleted)
728 break;
729
730 /* make sure the loop is not too tight */
731 progress->WaitForCompletion(100);
732 }
733
734 /* complete the line. */
735 HRESULT rc;
736 if (SUCCEEDED(progress->COMGETTER(ResultCode)(&rc)))
737 {
738 if (SUCCEEDED(rc))
739 RTPrintf("100%%\n");
740 else
741 RTPrintf("FAILED\n");
742 }
743 else
744 RTPrintf("\n");
745 RTStrmFlush(g_pStdOut);
746}
747
748static void showSnapshots(ComPtr<ISnapshot> rootSnapshot, VMINFO_DETAILS details, const Bstr &prefix = "", int level = 0)
749{
750 /* start with the root */
751 Bstr name;
752 Guid uuid;
753 rootSnapshot->COMGETTER(Name)(name.asOutParam());
754 rootSnapshot->COMGETTER(Id)(uuid.asOutParam());
755 if (details == VMINFO_MACHINEREADABLE)
756 {
757 /* print with hierarchical numbering */
758 RTPrintf("SnapshotName%lS=\"%lS\"\n", prefix.raw(), name.raw());
759 RTPrintf("SnapshotUUID%lS=\"%s\"\n", prefix.raw(), uuid.toString().raw());
760 }
761 else
762 {
763 /* print with indentation */
764 RTPrintf(" %lSName: %lS (UUID: %s)\n", prefix.raw(), name.raw(), uuid.toString().raw());
765 }
766
767 /* get the children */
768 ComPtr<ISnapshotCollection> coll;
769 rootSnapshot->COMGETTER(Children)(coll.asOutParam());
770 if (coll)
771 {
772 ComPtr<ISnapshotEnumerator> enumerator;
773 coll->Enumerate(enumerator.asOutParam());
774 ULONG index = 0;
775 BOOL hasMore = FALSE;
776 while (enumerator->HasMore(&hasMore), hasMore)
777 {
778 ComPtr<ISnapshot> snapshot;
779 enumerator->GetNext(snapshot.asOutParam());
780 if (snapshot)
781 {
782 Bstr newPrefix;
783 if (details == VMINFO_MACHINEREADABLE)
784 newPrefix = Utf8StrFmt("%lS-%d", prefix.raw(), index + 1);
785 else
786 newPrefix = Utf8StrFmt("%lS ", prefix.raw());
787 /* recursive call */
788 showSnapshots(snapshot, details, newPrefix, level + 1);
789 }
790 index++;
791 }
792 }
793}
794
795static void makeTimeStr (char *s, int cb, int64_t millies)
796{
797 RTTIME t;
798 RTTIMESPEC ts;
799
800 RTTimeSpecSetMilli(&ts, millies);
801
802 RTTimeExplode (&t, &ts);
803
804 RTStrPrintf(s, cb, "%04d/%02d/%02d %02d:%02d:%02d UTC",
805 t.i32Year, t.u8Month, t.u8MonthDay,
806 t.u8Hour, t.u8Minute, t.u8Second);
807}
808
809static HRESULT showVMInfo (ComPtr <IVirtualBox> virtualBox, ComPtr<IMachine> machine,
810 ComPtr <IConsole> console = ComPtr <IConsole> (),
811 VMINFO_DETAILS details = VMINFO_NONE)
812{
813 HRESULT rc;
814
815 /*
816 * The rules for output in -argdump format:
817 * 1) the key part (the [0-9a-zA-Z_]+ string before the '=' delimiter)
818 * is all lowercase for "VBoxManage modifyvm" parameters. Any
819 * other values printed are in CamelCase.
820 * 2) strings (anything non-decimal) are printed surrounded by
821 * double quotes '"'. If the strings themselves contain double
822 * quotes, these characters are escaped by '\'. Any '\' character
823 * in the original string is also escaped by '\'.
824 * 3) numbers (containing just [0-9\-]) are written out unchanged.
825 */
826
827 /** @todo the quoting is not yet implemented! */
828
829 BOOL accessible = FALSE;
830 CHECK_ERROR (machine, COMGETTER(Accessible) (&accessible));
831 CheckComRCReturnRC (rc);
832
833 if (!accessible)
834 {
835 if (details == VMINFO_MACHINEREADABLE)
836 RTPrintf("name=\"<inaccessible>\"\n");
837 else
838 RTPrintf ("Name: <inaccessible!>\n");
839 Guid uuid;
840 rc = machine->COMGETTER(Id) (uuid.asOutParam());
841 if (details == VMINFO_MACHINEREADABLE)
842 RTPrintf ("UUID=\"%s\"\n", uuid.toString().raw());
843 else
844 RTPrintf ("UUID: %s\n", uuid.toString().raw());
845 if (details != VMINFO_MACHINEREADABLE)
846 {
847 Bstr settingsFilePath;
848 rc = machine->COMGETTER(SettingsFilePath) (settingsFilePath.asOutParam());
849 RTPrintf ("Config file: %lS\n", settingsFilePath.raw());
850 ComPtr<IVirtualBoxErrorInfo> accessError;
851 rc = machine->COMGETTER(AccessError) (accessError.asOutParam());
852 RTPrintf ("Access error details:\n");
853 ErrorInfo ei (accessError);
854 PRINT_ERROR_INFO (ei);
855 RTPrintf ("\n");
856 }
857 return S_OK;
858 }
859
860 Bstr machineName;
861 rc = machine->COMGETTER(Name)(machineName.asOutParam());
862 if (details == VMINFO_MACHINEREADABLE)
863 RTPrintf("name=\"%lS\"\n", machineName.raw());
864 else
865 RTPrintf("Name: %lS\n", machineName.raw());
866
867 Bstr osTypeId;
868 rc = machine->COMGETTER(OSTypeId)(osTypeId.asOutParam());
869 ComPtr<IGuestOSType> osType;
870 rc = virtualBox->GetGuestOSType (osTypeId, osType.asOutParam());
871 Bstr osName;
872 rc = osType->COMGETTER(Description)(osName.asOutParam());
873 if (details == VMINFO_MACHINEREADABLE)
874 RTPrintf("ostype=\"%lS\"\n", osTypeId.raw());
875 else
876 RTPrintf("Guest OS: %lS\n", osName.raw());
877
878 Guid uuid;
879 rc = machine->COMGETTER(Id)(uuid.asOutParam());
880 if (details == VMINFO_MACHINEREADABLE)
881 RTPrintf("UUID=\"%s\"\n", uuid.toString().raw());
882 else
883 RTPrintf("UUID: %s\n", uuid.toString().raw());
884
885 Bstr settingsFilePath;
886 rc = machine->COMGETTER(SettingsFilePath)(settingsFilePath.asOutParam());
887 if (details == VMINFO_MACHINEREADABLE)
888 RTPrintf("CfgFile=\"%lS\"\n", settingsFilePath.raw());
889 else
890 RTPrintf("Config file: %lS\n", settingsFilePath.raw());
891
892 ULONG memorySize;
893 rc = machine->COMGETTER(MemorySize)(&memorySize);
894 if (details == VMINFO_MACHINEREADABLE)
895 RTPrintf("memory=%u\n", memorySize);
896 else
897 RTPrintf("Memory size: %uMB\n", memorySize);
898
899 ULONG vramSize;
900 rc = machine->COMGETTER(VRAMSize)(&vramSize);
901 if (details == VMINFO_MACHINEREADABLE)
902 RTPrintf("vram=%u\n", vramSize);
903 else
904 RTPrintf("VRAM size: %uMB\n", vramSize);
905
906 ComPtr <IBIOSSettings> biosSettings;
907 machine->COMGETTER(BIOSSettings)(biosSettings.asOutParam());
908
909 BIOSBootMenuMode_T bootMenuMode;
910 biosSettings->COMGETTER(BootMenuMode)(&bootMenuMode);
911 const char *pszBootMenu = NULL;
912 switch (bootMenuMode)
913 {
914 case BIOSBootMenuMode_Disabled:
915 pszBootMenu = "disabled";
916 break;
917 case BIOSBootMenuMode_MenuOnly:
918 if (details == VMINFO_MACHINEREADABLE)
919 pszBootMenu = "menuonly";
920 else
921 pszBootMenu = "menu only";
922 break;
923 default:
924 if (details == VMINFO_MACHINEREADABLE)
925 pszBootMenu = "messageandmenu";
926 else
927 pszBootMenu = "message and menu";
928 }
929 if (details == VMINFO_MACHINEREADABLE)
930 RTPrintf("bootmenu=\"%s\"\n", pszBootMenu);
931 else
932 RTPrintf("Boot menu mode: %s\n", pszBootMenu);
933
934 BOOL acpiEnabled;
935 biosSettings->COMGETTER(ACPIEnabled)(&acpiEnabled);
936 if (details == VMINFO_MACHINEREADABLE)
937 RTPrintf("acpi=\"%s\"\n", acpiEnabled ? "on" : "off");
938 else
939 RTPrintf("ACPI: %s\n", acpiEnabled ? "on" : "off");
940
941 BOOL ioapicEnabled;
942 biosSettings->COMGETTER(IOAPICEnabled)(&ioapicEnabled);
943 if (details == VMINFO_MACHINEREADABLE)
944 RTPrintf("ioapic=\"%s\"\n", ioapicEnabled ? "on" : "off");
945 else
946 RTPrintf("IOAPIC: %s\n", ioapicEnabled ? "on" : "off");
947
948 BOOL PAEEnabled;
949 machine->COMGETTER(PAEEnabled)(&PAEEnabled);
950 if (details == VMINFO_MACHINEREADABLE)
951 RTPrintf("pae=\"%s\"\n", PAEEnabled ? "on" : "off");
952 else
953 RTPrintf("PAE: %s\n", PAEEnabled ? "on" : "off");
954
955 LONG64 timeOffset;
956 biosSettings->COMGETTER(TimeOffset)(&timeOffset);
957 if (details == VMINFO_MACHINEREADABLE)
958 RTPrintf("biossystemtimeoffset=%lld\n", timeOffset);
959 else
960 RTPrintf("Time offset: %lld ms\n", timeOffset);
961
962 TSBool_T hwVirtExEnabled;
963 machine->COMGETTER(HWVirtExEnabled)(&hwVirtExEnabled);
964 if (hwVirtExEnabled == TSBool_Default)
965 {
966 BOOL fHWVirtExEnabled;
967 ComPtr<ISystemProperties> systemProperties;
968 virtualBox->COMGETTER(SystemProperties)(systemProperties.asOutParam());
969 systemProperties->COMGETTER(HWVirtExEnabled)(&fHWVirtExEnabled);
970 if (details == VMINFO_MACHINEREADABLE)
971 RTPrintf("hwvirtex=\"default\"\n");
972 else
973 RTPrintf("Hardw. virt.ext: Default (%s)\n", fHWVirtExEnabled ? "on" : "off");
974 }
975 else
976 {
977 if (details == VMINFO_MACHINEREADABLE)
978 RTPrintf("hwvirtex=\"%s\"\n", hwVirtExEnabled == TSBool_True ? "on" : "off");
979 else
980 RTPrintf("Hardw. virt.ext: %s\n", hwVirtExEnabled == TSBool_True ? "on" : "off");
981 }
982
983 MachineState_T machineState;
984 const char *pszState = NULL;
985 rc = machine->COMGETTER(State)(&machineState);
986 switch (machineState)
987 {
988 case MachineState_PoweredOff:
989 if (details == VMINFO_MACHINEREADABLE)
990 pszState = "poweroff";
991 else
992 pszState = "powered off";
993 break;
994 case MachineState_Saved:
995 pszState = "saved";
996 break;
997 case MachineState_Aborted:
998 pszState = "aborted";
999 break;
1000 case MachineState_Running:
1001 pszState = "running";
1002 break;
1003 case MachineState_Paused:
1004 pszState = "paused";
1005 break;
1006 case MachineState_Starting:
1007 pszState = "starting";
1008 break;
1009 case MachineState_Stopping:
1010 pszState = "stopping";
1011 break;
1012 case MachineState_Saving:
1013 pszState = "saving";
1014 break;
1015 case MachineState_Restoring:
1016 pszState = "restoring";
1017 break;
1018 default:
1019 pszState = "unknown";
1020 break;
1021 }
1022 LONG64 stateSince;
1023 machine->COMGETTER(LastStateChange)(&stateSince);
1024 RTTIMESPEC timeSpec;
1025 RTTimeSpecSetMilli(&timeSpec, stateSince);
1026 char pszTime[30] = {0};
1027 RTTimeSpecToString(&timeSpec, pszTime, 30);
1028 if (details == VMINFO_MACHINEREADABLE)
1029 {
1030 RTPrintf("VMState=\"%s\"\n", pszState);
1031 RTPrintf("VMStateChangeTime=\"%s\"\n", pszTime);
1032 }
1033 else
1034 RTPrintf("State: %s (since %s)\n", pszState, pszTime);
1035
1036 ULONG numMonitors;
1037 machine->COMGETTER(MonitorCount)(&numMonitors);
1038 if (details == VMINFO_MACHINEREADABLE)
1039 RTPrintf("monitorcount=%d\n", numMonitors);
1040 else
1041 RTPrintf("Monitor count: %d\n", numMonitors);
1042
1043 ComPtr<IFloppyDrive> floppyDrive;
1044 rc = machine->COMGETTER(FloppyDrive)(floppyDrive.asOutParam());
1045 if (SUCCEEDED(rc) && floppyDrive)
1046 {
1047 BOOL fFloppyEnabled;
1048 floppyDrive->COMGETTER(Enabled)(&fFloppyEnabled);
1049 Utf8Str pszFloppy = "invalid";
1050 if (fFloppyEnabled)
1051 {
1052 DriveState_T floppyState;
1053 floppyDrive->COMGETTER(State)(&floppyState);
1054 switch (floppyState)
1055 {
1056 case DriveState_ImageMounted:
1057 {
1058 ComPtr<IFloppyImage> floppyImage;
1059 rc = floppyDrive->GetImage(floppyImage.asOutParam());
1060 if (SUCCEEDED(rc) && floppyImage)
1061 {
1062 Bstr imagePath;
1063 floppyImage->COMGETTER(FilePath)(imagePath.asOutParam());
1064 Guid imageGuid;
1065 floppyImage->COMGETTER(Id)(imageGuid.asOutParam());
1066 if (details == VMINFO_MACHINEREADABLE)
1067 {
1068 RTPrintf("FloppyImageUUID=\"%s\"\n", imageGuid.toString().raw());
1069 pszFloppy = Utf8StrFmt("%lS", imagePath.raw());
1070 }
1071 else
1072 pszFloppy = Utf8StrFmt("%lS (UUID: %s)", imagePath.raw(), imageGuid.toString().raw());
1073 }
1074 break;
1075 }
1076
1077 case DriveState_HostDriveCaptured:
1078 {
1079 ComPtr<IHostFloppyDrive> hostFloppyDrive;
1080 rc = floppyDrive->GetHostDrive(hostFloppyDrive.asOutParam());
1081 if (SUCCEEDED(rc) && floppyDrive)
1082 {
1083 Bstr driveName;
1084 hostFloppyDrive->COMGETTER(Name)(driveName.asOutParam());
1085 if (details == VMINFO_MACHINEREADABLE)
1086 pszFloppy = Utf8StrFmt("host:%lS", driveName.raw());
1087 else
1088 pszFloppy = Utf8StrFmt("Host drive %lS", driveName.raw());
1089 }
1090 break;
1091 }
1092
1093 case DriveState_NotMounted:
1094 {
1095 pszFloppy = "empty";
1096 break;
1097 }
1098 }
1099 }
1100 else
1101 {
1102 pszFloppy = "disabled";
1103 }
1104 if (details == VMINFO_MACHINEREADABLE)
1105 RTPrintf("floppy=\"%s\"\n", pszFloppy.raw());
1106 else
1107 RTPrintf("Floppy: %s\n", pszFloppy.raw());
1108 }
1109
1110 /*
1111 * SATA.
1112 */
1113 ComPtr<ISATAController> SATACtl;
1114 rc = machine->COMGETTER(SATAController)(SATACtl.asOutParam());
1115 if (SUCCEEDED(rc))
1116 {
1117 BOOL fEnabled;
1118 rc = SATACtl->COMGETTER(Enabled)(&fEnabled);
1119 if (FAILED(rc))
1120 fEnabled = false;
1121 if (details == VMINFO_MACHINEREADABLE)
1122 RTPrintf("sata=\"%s\"\n", fEnabled ? "on" : "off");
1123 else
1124 RTPrintf("SATA: %s\n", fEnabled ? "enabled" : "disabled");
1125 }
1126
1127 /*
1128 * Hard disks
1129 */
1130 ComPtr<IHardDisk> hardDisk;
1131 Bstr filePath;
1132 rc = machine->GetHardDisk(StorageBus_IDE, 0, 0, hardDisk.asOutParam());
1133 if (SUCCEEDED(rc) && hardDisk)
1134 {
1135 /// @todo (dmik) we temporarily use the location property to
1136 // determine the image file name. This is subject to change
1137 // when iSCSI disks are here (we should either query a
1138 // storage-specific interface from IHardDisk, or "standardize"
1139 // the location property)
1140 hardDisk->COMGETTER(Location)(filePath.asOutParam());
1141 hardDisk->COMGETTER(Id)(uuid.asOutParam());
1142 if (details == VMINFO_MACHINEREADABLE)
1143 {
1144 RTPrintf("hda=\"%lS\"\n", filePath.raw());
1145 RTPrintf("HdaImageUUID=\"%s\"\n", uuid.toString().raw());
1146 }
1147 else
1148 RTPrintf("Primary master: %lS (UUID: %s)\n", filePath.raw(), uuid.toString().raw());
1149 }
1150 else
1151 {
1152 if (details == VMINFO_MACHINEREADABLE)
1153 RTPrintf("hda=\"none\"\n");
1154 }
1155 rc = machine->GetHardDisk(StorageBus_IDE, 0, 1, hardDisk.asOutParam());
1156 if (SUCCEEDED(rc) && hardDisk)
1157 {
1158 /// @todo (dmik) we temporarily use the location property to
1159 // determine the image file name. This is subject to change
1160 // when iSCSI disks are here (we should either query a
1161 // storage-specific interface from IHardDisk, or "standardize"
1162 // the location property)
1163 hardDisk->COMGETTER(Location)(filePath.asOutParam());
1164 hardDisk->COMGETTER(Id)(uuid.asOutParam());
1165 if (details == VMINFO_MACHINEREADABLE)
1166 {
1167 RTPrintf("hdb=\"%lS\"\n", filePath.raw());
1168 RTPrintf("HdbImageUUID=\"%s\"\n", uuid.toString().raw());
1169 }
1170 else
1171 RTPrintf("Primary slave: %lS (UUID: %s)\n", filePath.raw(), uuid.toString().raw());
1172 }
1173 else
1174 {
1175 if (details == VMINFO_MACHINEREADABLE)
1176 RTPrintf("hdb=\"none\"\n");
1177 }
1178 rc = machine->GetHardDisk(StorageBus_IDE, 1, 1, hardDisk.asOutParam());
1179 if (SUCCEEDED(rc) && hardDisk)
1180 {
1181 /// @todo (dmik) we temporarily use the location property to
1182 // determine the image file name. This is subject to change
1183 // when iSCSI disks are here (we should either query a
1184 // storage-specific interface from IHardDisk, or "standardize"
1185 // the location property)
1186 hardDisk->COMGETTER(Location)(filePath.asOutParam());
1187 hardDisk->COMGETTER(Id)(uuid.asOutParam());
1188 if (details == VMINFO_MACHINEREADABLE)
1189 {
1190 RTPrintf("hdd=\"%lS\"\n", filePath.raw());
1191 RTPrintf("HddImageUUID=\"%s\"\n", uuid.toString().raw());
1192 }
1193 else
1194 RTPrintf("Secondary slave: %lS (UUID: %s)\n", filePath.raw(), uuid.toString().raw());
1195 }
1196 else
1197 {
1198 if (details == VMINFO_MACHINEREADABLE)
1199 RTPrintf("hdd=\"none\"\n");
1200 }
1201 ComPtr<IDVDDrive> dvdDrive;
1202 rc = machine->COMGETTER(DVDDrive)(dvdDrive.asOutParam());
1203 if (SUCCEEDED(rc) && dvdDrive)
1204 {
1205 ComPtr<IDVDImage> dvdImage;
1206 rc = dvdDrive->GetImage(dvdImage.asOutParam());
1207 if (SUCCEEDED(rc) && dvdImage)
1208 {
1209 rc = dvdImage->COMGETTER(FilePath)(filePath.asOutParam());
1210 if (SUCCEEDED(rc) && filePath)
1211 {
1212 rc = dvdImage->COMGETTER(Id)(uuid.asOutParam());
1213 if (details == VMINFO_MACHINEREADABLE)
1214 {
1215 RTPrintf("dvd=\"%lS\"\n", filePath.raw());
1216 RTPrintf("DvdImageUUID=\"%s\"\n", uuid.toString().raw());
1217 }
1218 else
1219 RTPrintf("DVD: %lS (UUID: %s)\n", filePath.raw(), uuid.toString().raw());
1220 }
1221 }
1222 else
1223 {
1224 ComPtr<IHostDVDDrive> hostDVDDrive;
1225 rc = dvdDrive->GetHostDrive(hostDVDDrive.asOutParam());
1226 if (SUCCEEDED(rc) && hostDVDDrive)
1227 {
1228 Bstr name;
1229 hostDVDDrive->COMGETTER(Name)(name.asOutParam());
1230 if (details == VMINFO_MACHINEREADABLE)
1231 RTPrintf("dvd=\"host:%lS\"\n", name.raw());
1232 else
1233 RTPrintf("DVD: Host drive %lS", name.raw());
1234 }
1235 else
1236 {
1237 if (details == VMINFO_MACHINEREADABLE)
1238 RTPrintf("dvd=\"none\"\n");
1239 else
1240 RTPrintf("DVD: empty");
1241 }
1242 BOOL fPassthrough;
1243 dvdDrive->COMGETTER(Passthrough)(&fPassthrough);
1244 if (details == VMINFO_MACHINEREADABLE)
1245 {
1246 RTPrintf("dvdpassthrough=\"%s\"\n", fPassthrough ? "on" : "off");
1247 }
1248 else
1249 {
1250 if (fPassthrough)
1251 RTPrintf(" (passthrough enabled)");
1252 RTPrintf("\n");
1253 }
1254 }
1255 }
1256
1257 /* get the maximum amount of NICS */
1258 ComPtr<ISystemProperties> sysProps;
1259 virtualBox->COMGETTER(SystemProperties)(sysProps.asOutParam());
1260 ULONG maxNICs = 0;
1261 sysProps->COMGETTER(NetworkAdapterCount)(&maxNICs);
1262 for (ULONG currentNIC = 0; currentNIC < maxNICs; currentNIC++)
1263 {
1264 ComPtr<INetworkAdapter> nic;
1265 rc = machine->GetNetworkAdapter(currentNIC, nic.asOutParam());
1266 if (SUCCEEDED(rc) && nic)
1267 {
1268 BOOL fEnabled;
1269 nic->COMGETTER(Enabled)(&fEnabled);
1270 if (!fEnabled)
1271 {
1272 if (details == VMINFO_MACHINEREADABLE)
1273 RTPrintf("nic%d=\"none\"\n", currentNIC + 1);
1274 else
1275 RTPrintf("NIC %d: disabled\n", currentNIC + 1);
1276 }
1277 else
1278 {
1279 Bstr strMACAddress;
1280 nic->COMGETTER(MACAddress)(strMACAddress.asOutParam());
1281 Utf8Str strAttachment;
1282 NetworkAttachmentType_T attachment;
1283 nic->COMGETTER(AttachmentType)(&attachment);
1284 switch (attachment)
1285 {
1286 case NetworkAttachmentType_Null:
1287 if (details == VMINFO_MACHINEREADABLE)
1288 strAttachment = "null";
1289 else
1290 strAttachment = "none";
1291 break;
1292 case NetworkAttachmentType_NAT:
1293 {
1294 Bstr strNetwork;
1295 nic->COMGETTER(NATNetwork)(strNetwork.asOutParam());
1296 if (details == VMINFO_MACHINEREADABLE)
1297 {
1298 RTPrintf("natnet%d=\"%lS\"\n", currentNIC + 1, strNetwork.raw());
1299 strAttachment = "nat";
1300 }
1301 else if (!strNetwork.isEmpty())
1302 strAttachment = Utf8StrFmt("NAT (%lS)", strNetwork.raw());
1303 else
1304 strAttachment = "NAT";
1305 break;
1306 }
1307 case NetworkAttachmentType_HostInterface:
1308 {
1309 Bstr strHostIfDev;
1310 nic->COMGETTER(HostInterface)(strHostIfDev.asOutParam());
1311 if (details == VMINFO_MACHINEREADABLE)
1312 {
1313 RTPrintf("hostifdev%d=\"%lS\"\n", currentNIC + 1, strHostIfDev.raw());
1314 strAttachment = "hostif";
1315 }
1316 else
1317 strAttachment = Utf8StrFmt("Host Interface '%lS'", strHostIfDev.raw());
1318 break;
1319 }
1320 case NetworkAttachmentType_Internal:
1321 {
1322 Bstr strNetwork;
1323 nic->COMGETTER(InternalNetwork)(strNetwork.asOutParam());
1324 if (details == VMINFO_MACHINEREADABLE)
1325 {
1326 RTPrintf("intnet%d=\"%lS\"\n", currentNIC + 1, strNetwork.raw());
1327 strAttachment = "intnet";
1328 }
1329 else
1330 strAttachment = Utf8StrFmt("Internal Network '%s'", Utf8Str(strNetwork).raw());
1331 break;
1332 }
1333 default:
1334 strAttachment = "unknown";
1335 break;
1336 }
1337
1338 /* cable connected */
1339 BOOL fConnected;
1340 nic->COMGETTER(CableConnected)(&fConnected);
1341
1342 /* trace stuff */
1343 BOOL fTraceEnabled;
1344 nic->COMGETTER(TraceEnabled)(&fTraceEnabled);
1345 Bstr traceFile;
1346 nic->COMGETTER(TraceFile)(traceFile.asOutParam());
1347
1348 /* NIC type */
1349 Utf8Str strNICType;
1350 NetworkAdapterType_T NICType;
1351 nic->COMGETTER(AdapterType)(&NICType);
1352 switch (NICType) {
1353 case NetworkAdapterType_Am79C970A:
1354 strNICType = "Am79C970A";
1355 break;
1356 case NetworkAdapterType_Am79C973:
1357 strNICType = "Am79C973";
1358 break;
1359#ifdef VBOX_WITH_E1000
1360 case NetworkAdapterType_I82540EM:
1361 strNICType = "82540EM";
1362 break;
1363 case NetworkAdapterType_I82543GC:
1364 strNICType = "82543GC";
1365 break;
1366#endif
1367 default:
1368 strNICType = "unknown";
1369 break;
1370 }
1371
1372 /* reported line speed */
1373 ULONG ulLineSpeed;
1374 nic->COMGETTER(LineSpeed)(&ulLineSpeed);
1375
1376 if (details == VMINFO_MACHINEREADABLE)
1377 {
1378 RTPrintf("macaddress%d=\"%lS\"\n", currentNIC + 1, strMACAddress.raw());
1379 RTPrintf("cableconnected%d=\"%s\"\n", currentNIC + 1, fConnected ? "on" : "off");
1380 RTPrintf("nic%d=\"%s\"\n", currentNIC + 1, strAttachment.raw());
1381 }
1382 else
1383 RTPrintf("NIC %d: MAC: %lS, Attachment: %s, Cable connected: %s, Trace: %s (file: %lS), Type: %s, Reported speed: %d Mbps\n",
1384 currentNIC + 1, strMACAddress.raw(), strAttachment.raw(),
1385 fConnected ? "on" : "off",
1386 fTraceEnabled ? "on" : "off",
1387 traceFile.isEmpty() ? Bstr("none").raw() : traceFile.raw(),
1388 strNICType.raw(),
1389 ulLineSpeed / 1000);
1390 }
1391 }
1392 }
1393
1394 /* get the maximum amount of UARTs */
1395 ULONG maxUARTs = 0;
1396 sysProps->COMGETTER(SerialPortCount)(&maxUARTs);
1397 for (ULONG currentUART = 0; currentUART < maxUARTs; currentUART++)
1398 {
1399 ComPtr<ISerialPort> uart;
1400 rc = machine->GetSerialPort(currentUART, uart.asOutParam());
1401 if (SUCCEEDED(rc) && uart)
1402 {
1403 BOOL fEnabled;
1404 uart->COMGETTER(Enabled)(&fEnabled);
1405 if (!fEnabled)
1406 {
1407 if (details == VMINFO_MACHINEREADABLE)
1408 RTPrintf("uart%d=\"off\"\n", currentUART + 1);
1409 else
1410 RTPrintf("UART %d: disabled\n", currentUART + 1);
1411 }
1412 else
1413 {
1414 ULONG ulIRQ, ulIOBase;
1415 PortMode_T HostMode;
1416 Bstr path;
1417 BOOL fServer;
1418 uart->COMGETTER(IRQ)(&ulIRQ);
1419 uart->COMGETTER(IOBase)(&ulIOBase);
1420 uart->COMGETTER(Path)(path.asOutParam());
1421 uart->COMGETTER(Server)(&fServer);
1422 uart->COMGETTER(HostMode)(&HostMode);
1423
1424 if (details == VMINFO_MACHINEREADABLE)
1425 RTPrintf("uart%d=\"%#06x,%d\"\n", currentUART + 1,
1426 ulIOBase, ulIRQ);
1427 else
1428 RTPrintf("UART %d: I/O base: 0x%04x, IRQ: %d",
1429 currentUART + 1, ulIOBase, ulIRQ);
1430 switch (HostMode)
1431 {
1432 default:
1433 case PortMode_Disconnected:
1434 if (details == VMINFO_MACHINEREADABLE)
1435 RTPrintf("uartmode%d=\"disconnected\"\n", currentUART + 1);
1436 else
1437 RTPrintf(", disconnected\n");
1438 break;
1439 case PortMode_HostPipe:
1440 if (details == VMINFO_MACHINEREADABLE)
1441 RTPrintf("uartmode%d=\"%s,%lS\"\n", currentUART + 1,
1442 fServer ? "server" : "client", path.raw());
1443 else
1444 RTPrintf(", attached to pipe (%s) '%lS'\n",
1445 fServer ? "server" : "client", path.raw());
1446 break;
1447 case PortMode_HostDevice:
1448 if (details == VMINFO_MACHINEREADABLE)
1449 RTPrintf("uartmode%d=\"%lS\"\n", currentUART + 1,
1450 path.raw());
1451 else
1452 RTPrintf(", attached to device '%lS'\n", path.raw());
1453 break;
1454 }
1455 }
1456 }
1457 }
1458
1459 ComPtr<IAudioAdapter> AudioAdapter;
1460 rc = machine->COMGETTER(AudioAdapter)(AudioAdapter.asOutParam());
1461 if (SUCCEEDED(rc))
1462 {
1463 const char *pszDrv = "Unknown";
1464 const char *pszCtrl = "Unknown";
1465 BOOL fEnabled;
1466 rc = AudioAdapter->COMGETTER(Enabled)(&fEnabled);
1467 if (SUCCEEDED(rc) && fEnabled)
1468 {
1469 AudioDriverType_T enmDrvType;
1470 rc = AudioAdapter->COMGETTER(AudioDriver)(&enmDrvType);
1471 switch (enmDrvType)
1472 {
1473 case AudioDriverType_Null:
1474 if (details == VMINFO_MACHINEREADABLE)
1475 pszDrv = "null";
1476 else
1477 pszDrv = "Null";
1478 break;
1479 case AudioDriverType_WinMM:
1480 if (details == VMINFO_MACHINEREADABLE)
1481 pszDrv = "winmm";
1482 else
1483 pszDrv = "WINMM";
1484 break;
1485 case AudioDriverType_DirectSound:
1486 if (details == VMINFO_MACHINEREADABLE)
1487 pszDrv = "dsound";
1488 else
1489 pszDrv = "DSOUND";
1490 break;
1491 case AudioDriverType_OSS:
1492 if (details == VMINFO_MACHINEREADABLE)
1493 pszDrv = "oss";
1494 else
1495 pszDrv = "OSS";
1496 break;
1497 case AudioDriverType_ALSA:
1498 if (details == VMINFO_MACHINEREADABLE)
1499 pszDrv = "alsa";
1500 else
1501 pszDrv = "ALSA";
1502 break;
1503 case AudioDriverType_Pulse:
1504 if (details == VMINFO_MACHINEREADABLE)
1505 pszDrv = "pulse";
1506 else
1507 pszDrv = "PulseAudio";
1508 break;
1509 case AudioDriverType_CoreAudio:
1510 if (details == VMINFO_MACHINEREADABLE)
1511 pszDrv = "coreaudio";
1512 else
1513 pszDrv = "CoreAudio";
1514 break;
1515 case AudioDriverType_SolAudio:
1516 if (details == VMINFO_MACHINEREADABLE)
1517 pszDrv = "solaudio";
1518 else
1519 pszDrv = "SolAudio";
1520 break;
1521 default:
1522 if (details == VMINFO_MACHINEREADABLE)
1523 pszDrv = "unknown";
1524 break;
1525 }
1526 AudioControllerType_T enmCtrlType;
1527 rc = AudioAdapter->COMGETTER(AudioController)(&enmCtrlType);
1528 switch (enmCtrlType)
1529 {
1530 case AudioControllerType_AC97:
1531 if (details == VMINFO_MACHINEREADABLE)
1532 pszCtrl = "ac97";
1533 else
1534 pszCtrl = "AC97";
1535 break;
1536 case AudioControllerType_SB16:
1537 if (details == VMINFO_MACHINEREADABLE)
1538 pszCtrl = "sb16";
1539 else
1540 pszCtrl = "SB16";
1541 break;
1542 }
1543 }
1544 else
1545 fEnabled = FALSE;
1546 if (details == VMINFO_MACHINEREADABLE)
1547 {
1548 if (fEnabled)
1549 RTPrintf("audio=\"%s\"\n", pszDrv);
1550 else
1551 RTPrintf("audio=\"none\"\n");
1552 }
1553 else
1554 RTPrintf("Audio: %s (Driver: %s, Controller: %s)\n",
1555 fEnabled ? "enabled" : "disabled", pszDrv, pszCtrl);
1556 }
1557
1558 /* Shared clipboard */
1559 {
1560 const char *psz = "Unknown";
1561 ClipboardMode_T enmMode;
1562 rc = machine->COMGETTER(ClipboardMode)(&enmMode);
1563 switch (enmMode)
1564 {
1565 case ClipboardMode_Disabled:
1566 if (details == VMINFO_MACHINEREADABLE)
1567 psz = "disabled";
1568 else
1569 psz = "disabled";
1570 break;
1571 case ClipboardMode_HostToGuest:
1572 if (details == VMINFO_MACHINEREADABLE)
1573 psz = "hosttoguest";
1574 else
1575 psz = "HostToGuest";
1576 break;
1577 case ClipboardMode_GuestToHost:
1578 if (details == VMINFO_MACHINEREADABLE)
1579 psz = "guesttohost";
1580 else
1581 psz = "GuestToHost";
1582 break;
1583 case ClipboardMode_Bidirectional:
1584 if (details == VMINFO_MACHINEREADABLE)
1585 psz = "bidirectional";
1586 else
1587 psz = "Bidirectional";
1588 break;
1589 default:
1590 if (details == VMINFO_MACHINEREADABLE)
1591 psz = "unknown";
1592 break;
1593 }
1594 if (details == VMINFO_MACHINEREADABLE)
1595 RTPrintf("clipboard=\"%s\"\n", psz);
1596 else
1597 RTPrintf("Clipboard Mode: %s\n", psz);
1598 }
1599
1600 if (console)
1601 {
1602 ComPtr<IDisplay> display;
1603 CHECK_ERROR_RET(console, COMGETTER(Display)(display.asOutParam()), rc);
1604 ULONG xRes, yRes, bpp;
1605 CHECK_ERROR_RET(display, COMGETTER(Width)(&xRes), rc);
1606 CHECK_ERROR_RET(display, COMGETTER(Height)(&yRes), rc);
1607 CHECK_ERROR_RET(display, COMGETTER(BitsPerPixel)(&bpp), rc);
1608 if (details == VMINFO_MACHINEREADABLE)
1609 RTPrintf("VideoMode=\"%d,%d,%d\"\n", xRes, yRes, bpp);
1610 else
1611 RTPrintf("Video mode: %dx%dx%d\n", xRes, yRes, bpp);
1612 }
1613
1614 /*
1615 * VRDP
1616 */
1617 ComPtr<IVRDPServer> vrdpServer;
1618 rc = machine->COMGETTER(VRDPServer)(vrdpServer.asOutParam());
1619 if (SUCCEEDED(rc) && vrdpServer)
1620 {
1621 BOOL fEnabled = false;
1622 vrdpServer->COMGETTER(Enabled)(&fEnabled);
1623 if (fEnabled)
1624 {
1625 ULONG port;
1626 vrdpServer->COMGETTER(Port)(&port);
1627 Bstr address;
1628 vrdpServer->COMGETTER(NetAddress)(address.asOutParam());
1629 BOOL fMultiCon;
1630 vrdpServer->COMGETTER(AllowMultiConnection)(&fMultiCon);
1631 VRDPAuthType_T vrdpAuthType;
1632 const char *strAuthType;
1633 vrdpServer->COMGETTER(AuthType)(&vrdpAuthType);
1634 switch (vrdpAuthType)
1635 {
1636 case VRDPAuthType_Null:
1637 strAuthType = "null";
1638 break;
1639 case VRDPAuthType_External:
1640 strAuthType = "external";
1641 break;
1642 case VRDPAuthType_Guest:
1643 strAuthType = "guest";
1644 break;
1645 default:
1646 strAuthType = "unknown";
1647 break;
1648 }
1649 if (details == VMINFO_MACHINEREADABLE)
1650 {
1651 RTPrintf("vrdp=\"on\"\n");
1652 RTPrintf("vrdpport=%d\n", port);
1653 RTPrintf("vrdpaddress=\"%lS\"\n", address.raw());
1654 RTPrintf("vrdpauthtype=\"%s\"\n", strAuthType);
1655 RTPrintf("vrdpmulticon=\"%s\"\n", fMultiCon ? "on" : "off");
1656 }
1657 else
1658 {
1659 if (address.isEmpty())
1660 address = "0.0.0.0";
1661 RTPrintf("VRDP: enabled (Address %lS, Port %d, MultiConn: %s, Authentication type: %s)\n", address.raw(), port, fMultiCon ? "on" : "off", strAuthType);
1662 }
1663 }
1664 else
1665 {
1666 if (details == VMINFO_MACHINEREADABLE)
1667 RTPrintf("vrdp=\"off\"\n");
1668 else
1669 RTPrintf("VRDP: disabled\n");
1670 }
1671 }
1672
1673 /*
1674 * USB.
1675 */
1676 ComPtr<IUSBController> USBCtl;
1677 rc = machine->COMGETTER(USBController)(USBCtl.asOutParam());
1678 if (SUCCEEDED(rc))
1679 {
1680 BOOL fEnabled;
1681 rc = USBCtl->COMGETTER(Enabled)(&fEnabled);
1682 if (FAILED(rc))
1683 fEnabled = false;
1684 if (details == VMINFO_MACHINEREADABLE)
1685 RTPrintf("usb=\"%s\"\n", fEnabled ? "on" : "off");
1686 else
1687 RTPrintf("USB: %s\n", fEnabled ? "enabled" : "disabled");
1688
1689 if (details != VMINFO_MACHINEREADABLE)
1690 RTPrintf("\nUSB Device Filters:\n\n");
1691
1692 ComPtr<IUSBDeviceFilterCollection> Coll;
1693 CHECK_ERROR_RET (USBCtl, COMGETTER(DeviceFilters)(Coll.asOutParam()), rc);
1694
1695 ComPtr<IUSBDeviceFilterEnumerator> Enum;
1696 CHECK_ERROR_RET (Coll, Enumerate(Enum.asOutParam()), rc);
1697
1698 ULONG index = 0;
1699 BOOL fMore = FALSE;
1700 rc = Enum->HasMore (&fMore);
1701 ASSERT_RET (SUCCEEDED (rc), rc);
1702
1703 if (!fMore)
1704 {
1705 if (details != VMINFO_MACHINEREADABLE)
1706 RTPrintf("<none>\n\n");
1707 }
1708 else
1709 while (fMore)
1710 {
1711 ComPtr<IUSBDeviceFilter> DevPtr;
1712 rc = Enum->GetNext(DevPtr.asOutParam());
1713 ASSERT_RET (SUCCEEDED (rc), rc);
1714
1715 /* Query info. */
1716
1717 if (details != VMINFO_MACHINEREADABLE)
1718 RTPrintf("Index: %lu\n", index);
1719
1720 BOOL bActive = FALSE;
1721 CHECK_ERROR_RET (DevPtr, COMGETTER (Active) (&bActive), rc);
1722 if (details == VMINFO_MACHINEREADABLE)
1723 RTPrintf("USBFilterActive%d=\"%s\"\n", index + 1, bActive ? "on" : "off");
1724 else
1725 RTPrintf("Active: %s\n", bActive ? "yes" : "no");
1726
1727 Bstr bstr;
1728 CHECK_ERROR_RET (DevPtr, COMGETTER (Name) (bstr.asOutParam()), rc);
1729 if (details == VMINFO_MACHINEREADABLE)
1730 RTPrintf("USBFilterName%d=\"%lS\"\n", index + 1, bstr.raw());
1731 else
1732 RTPrintf("Name: %lS\n", bstr.raw());
1733 CHECK_ERROR_RET (DevPtr, COMGETTER (VendorId) (bstr.asOutParam()), rc);
1734 if (details == VMINFO_MACHINEREADABLE)
1735 RTPrintf("USBFilterVendorId%d=\"%lS\"\n", index + 1, bstr.raw());
1736 else
1737 RTPrintf("VendorId: %lS\n", bstr.raw());
1738 CHECK_ERROR_RET (DevPtr, COMGETTER (ProductId) (bstr.asOutParam()), rc);
1739 if (details == VMINFO_MACHINEREADABLE)
1740 RTPrintf("USBFilterProductId%d=\"%lS\"\n", index + 1, bstr.raw());
1741 else
1742 RTPrintf("ProductId: %lS\n", bstr.raw());
1743 CHECK_ERROR_RET (DevPtr, COMGETTER (Revision) (bstr.asOutParam()), rc);
1744 if (details == VMINFO_MACHINEREADABLE)
1745 RTPrintf("USBFilterRevision%d=\"%lS\"\n", index + 1, bstr.raw());
1746 else
1747 RTPrintf("Revision: %lS\n", bstr.raw());
1748 CHECK_ERROR_RET (DevPtr, COMGETTER (Manufacturer) (bstr.asOutParam()), rc);
1749 if (details == VMINFO_MACHINEREADABLE)
1750 RTPrintf("USBFilterManufacturer%d=\"%lS\"\n", index + 1, bstr.raw());
1751 else
1752 RTPrintf("Manufacturer: %lS\n", bstr.raw());
1753 CHECK_ERROR_RET (DevPtr, COMGETTER (Product) (bstr.asOutParam()), rc);
1754 if (details == VMINFO_MACHINEREADABLE)
1755 RTPrintf("USBFilterProduct%d=\"%lS\"\n", index + 1, bstr.raw());
1756 else
1757 RTPrintf("Product: %lS\n", bstr.raw());
1758 CHECK_ERROR_RET (DevPtr, COMGETTER (Remote) (bstr.asOutParam()), rc);
1759 if (details == VMINFO_MACHINEREADABLE)
1760 RTPrintf("USBFilterRemote%d=\"%lS\"\n", index + 1, bstr.raw());
1761 else
1762 RTPrintf("Remote: %lS\n", bstr.raw());
1763 CHECK_ERROR_RET (DevPtr, COMGETTER (SerialNumber) (bstr.asOutParam()), rc);
1764 if (details == VMINFO_MACHINEREADABLE)
1765 RTPrintf("USBFilterSerialNumber%d=\"%lS\"\n", index + 1, bstr.raw());
1766 else
1767 RTPrintf("Serial Number: %lS\n", bstr.raw());
1768 if (details != VMINFO_MACHINEREADABLE)
1769 {
1770 ULONG fMaskedIfs;
1771 CHECK_ERROR_RET (DevPtr, COMGETTER (MaskedInterfaces) (&fMaskedIfs), rc);
1772 if (fMaskedIfs)
1773 RTPrintf("Masked Interfaces: 0x%08x\n", fMaskedIfs);
1774 RTPrintf("\n");
1775 }
1776
1777 rc = Enum->HasMore (&fMore);
1778 ASSERT_RET (SUCCEEDED (rc), rc);
1779
1780 index ++;
1781 }
1782
1783 if (console)
1784 {
1785 index = 0;
1786 /* scope */
1787 {
1788 if (details != VMINFO_MACHINEREADABLE)
1789 RTPrintf("Available remote USB devices:\n\n");
1790
1791 ComPtr<IHostUSBDeviceCollection> coll;
1792 CHECK_ERROR_RET (console, COMGETTER(RemoteUSBDevices) (coll.asOutParam()), rc);
1793
1794 ComPtr <IHostUSBDeviceEnumerator> en;
1795 CHECK_ERROR_RET (coll, Enumerate (en.asOutParam()), rc);
1796
1797 BOOL more = FALSE;
1798 rc = en->HasMore (&more);
1799 ASSERT_RET (SUCCEEDED (rc), rc);
1800
1801 if (!more)
1802 {
1803 if (details != VMINFO_MACHINEREADABLE)
1804 RTPrintf("<none>\n\n");
1805 }
1806 else
1807 while (more)
1808 {
1809 ComPtr <IHostUSBDevice> dev;
1810 rc = en->GetNext (dev.asOutParam());
1811 ASSERT_RET (SUCCEEDED (rc), rc);
1812
1813 /* Query info. */
1814 Guid id;
1815 CHECK_ERROR_RET (dev, COMGETTER(Id)(id.asOutParam()), rc);
1816 USHORT usVendorId;
1817 CHECK_ERROR_RET (dev, COMGETTER(VendorId)(&usVendorId), rc);
1818 USHORT usProductId;
1819 CHECK_ERROR_RET (dev, COMGETTER(ProductId)(&usProductId), rc);
1820 USHORT bcdRevision;
1821 CHECK_ERROR_RET (dev, COMGETTER(Revision)(&bcdRevision), rc);
1822
1823 if (details == VMINFO_MACHINEREADABLE)
1824 RTPrintf("USBRemoteUUID%d=\"%S\"\n"
1825 "USBRemoteVendorId%d=\"%#06x\"\n"
1826 "USBRemoteProductId%d=\"%#06x\"\n"
1827 "USBRemoteRevision%d=\"%#04x%02x\"\n",
1828 index + 1, id.toString().raw(),
1829 index + 1, usVendorId,
1830 index + 1, usProductId,
1831 index + 1, bcdRevision >> 8, bcdRevision & 0xff);
1832 else
1833 RTPrintf("UUID: %S\n"
1834 "VendorId: 0x%04x (%04X)\n"
1835 "ProductId: 0x%04x (%04X)\n"
1836 "Revision: %u.%u (%02u%02u)\n",
1837 id.toString().raw(),
1838 usVendorId, usVendorId, usProductId, usProductId,
1839 bcdRevision >> 8, bcdRevision & 0xff,
1840 bcdRevision >> 8, bcdRevision & 0xff);
1841
1842 /* optional stuff. */
1843 Bstr bstr;
1844 CHECK_ERROR_RET (dev, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
1845 if (!bstr.isEmpty())
1846 {
1847 if (details == VMINFO_MACHINEREADABLE)
1848 RTPrintf("USBRemoteManufacturer%d=\"%lS\"\n", index + 1, bstr.raw());
1849 else
1850 RTPrintf("Manufacturer: %lS\n", bstr.raw());
1851 }
1852 CHECK_ERROR_RET (dev, COMGETTER(Product)(bstr.asOutParam()), rc);
1853 if (!bstr.isEmpty())
1854 {
1855 if (details == VMINFO_MACHINEREADABLE)
1856 RTPrintf("USBRemoteProduct%d=\"%lS\"\n", index + 1, bstr.raw());
1857 else
1858 RTPrintf("Product: %lS\n", bstr.raw());
1859 }
1860 CHECK_ERROR_RET (dev, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
1861 if (!bstr.isEmpty())
1862 {
1863 if (details == VMINFO_MACHINEREADABLE)
1864 RTPrintf("USBRemoteSerialNumber%d=\"%lS\"\n", index + 1, bstr.raw());
1865 else
1866 RTPrintf("SerialNumber: %lS\n", bstr.raw());
1867 }
1868 CHECK_ERROR_RET (dev, COMGETTER(Address)(bstr.asOutParam()), rc);
1869 if (!bstr.isEmpty())
1870 {
1871 if (details == VMINFO_MACHINEREADABLE)
1872 RTPrintf("USBRemoteAddress%d=\"%lS\"\n", index + 1, bstr.raw());
1873 else
1874 RTPrintf("Address: %lS\n", bstr.raw());
1875 }
1876
1877 if (details != VMINFO_MACHINEREADABLE)
1878 RTPrintf("\n");
1879
1880 rc = en->HasMore (&more);
1881 ASSERT_RET (SUCCEEDED (rc), rc);
1882
1883 index ++;
1884 }
1885 }
1886
1887 index = 0;
1888 /* scope */
1889 {
1890 if (details != VMINFO_MACHINEREADABLE)
1891 RTPrintf ("Currently Attached USB Devices:\n\n");
1892
1893 ComPtr <IUSBDeviceCollection> coll;
1894 CHECK_ERROR_RET (console, COMGETTER(USBDevices) (coll.asOutParam()), rc);
1895
1896 ComPtr <IUSBDeviceEnumerator> en;
1897 CHECK_ERROR_RET (coll, Enumerate (en.asOutParam()), rc);
1898
1899 BOOL more = FALSE;
1900 rc = en->HasMore (&more);
1901 ASSERT_RET (SUCCEEDED (rc), rc);
1902
1903 if (!more)
1904 {
1905 if (details != VMINFO_MACHINEREADABLE)
1906 RTPrintf("<none>\n\n");
1907 }
1908 else
1909 while (more)
1910 {
1911 ComPtr <IUSBDevice> dev;
1912 rc = en->GetNext (dev.asOutParam());
1913 ASSERT_RET (SUCCEEDED (rc), rc);
1914
1915 /* Query info. */
1916 Guid id;
1917 CHECK_ERROR_RET (dev, COMGETTER(Id)(id.asOutParam()), rc);
1918 USHORT usVendorId;
1919 CHECK_ERROR_RET (dev, COMGETTER(VendorId)(&usVendorId), rc);
1920 USHORT usProductId;
1921 CHECK_ERROR_RET (dev, COMGETTER(ProductId)(&usProductId), rc);
1922 USHORT bcdRevision;
1923 CHECK_ERROR_RET (dev, COMGETTER(Revision)(&bcdRevision), rc);
1924
1925 if (details == VMINFO_MACHINEREADABLE)
1926 RTPrintf("USBAttachedUUID%d=\"%S\"\n"
1927 "USBAttachedVendorId%d=\"%#06x\"\n"
1928 "USBAttachedProductId%d=\"%#06x\"\n"
1929 "USBAttachedRevision%d=\"%#04x%02x\"\n",
1930 index + 1, id.toString().raw(),
1931 index + 1, usVendorId,
1932 index + 1, usProductId,
1933 index + 1, bcdRevision >> 8, bcdRevision & 0xff);
1934 else
1935 RTPrintf("UUID: %S\n"
1936 "VendorId: 0x%04x (%04X)\n"
1937 "ProductId: 0x%04x (%04X)\n"
1938 "Revision: %u.%u (%02u%02u)\n",
1939 id.toString().raw(),
1940 usVendorId, usVendorId, usProductId, usProductId,
1941 bcdRevision >> 8, bcdRevision & 0xff,
1942 bcdRevision >> 8, bcdRevision & 0xff);
1943
1944 /* optional stuff. */
1945 Bstr bstr;
1946 CHECK_ERROR_RET (dev, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
1947 if (!bstr.isEmpty())
1948 {
1949 if (details == VMINFO_MACHINEREADABLE)
1950 RTPrintf("USBAttachedManufacturer%d=\"%lS\"\n", index + 1, bstr.raw());
1951 else
1952 RTPrintf("Manufacturer: %lS\n", bstr.raw());
1953 }
1954 CHECK_ERROR_RET (dev, COMGETTER(Product)(bstr.asOutParam()), rc);
1955 if (!bstr.isEmpty())
1956 {
1957 if (details == VMINFO_MACHINEREADABLE)
1958 RTPrintf("USBAttachedProduct%d=\"%lS\"\n", index + 1, bstr.raw());
1959 else
1960 RTPrintf("Product: %lS\n", bstr.raw());
1961 }
1962 CHECK_ERROR_RET (dev, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
1963 if (!bstr.isEmpty())
1964 {
1965 if (details == VMINFO_MACHINEREADABLE)
1966 RTPrintf("USBAttachedSerialNumber%d=\"%lS\"\n", index + 1, bstr.raw());
1967 else
1968 RTPrintf("SerialNumber: %lS\n", bstr.raw());
1969 }
1970 CHECK_ERROR_RET (dev, COMGETTER(Address)(bstr.asOutParam()), rc);
1971 if (!bstr.isEmpty())
1972 {
1973 if (details == VMINFO_MACHINEREADABLE)
1974 RTPrintf("USBAttachedAddress%d=\"%lS\"\n", index + 1, bstr.raw());
1975 else
1976 RTPrintf("Address: %lS\n", bstr.raw());
1977 }
1978
1979 if (details != VMINFO_MACHINEREADABLE)
1980 RTPrintf("\n");
1981
1982 rc = en->HasMore (&more);
1983 ASSERT_RET (SUCCEEDED (rc), rc);
1984
1985 index ++;
1986 }
1987 }
1988 }
1989 } /* USB */
1990
1991 /*
1992 * Shared folders
1993 */
1994 if (details != VMINFO_MACHINEREADABLE)
1995 RTPrintf("Shared folders: ");
1996 uint32_t numSharedFolders = 0;
1997#if 0 // not yet implemented
1998 /* globally shared folders first */
1999 {
2000 ComPtr<ISharedFolderCollection> sfColl;
2001 ComPtr<ISharedFolderEnumerator> sfEnum;
2002 CHECK_ERROR_RET(virtualBox, COMGETTER(SharedFolders)(sfColl.asOutParam()), rc);
2003 CHECK_ERROR_RET(sfColl, Enumerate(sfEnum.asOutParam()), rc);
2004 BOOL fMore;
2005 sfEnum->HasMore(&fMore);
2006 while (fMore)
2007 {
2008 ComPtr<ISharedFolder> sf;
2009 CHECK_ERROR_RET(sfEnum, GetNext(sf.asOutParam()), rc);
2010 Bstr name, hostPath;
2011 sf->COMGETTER(Name)(name.asOutParam());
2012 sf->COMGETTER(HostPath)(hostPath.asOutParam());
2013 RTPrintf("Name: '%lS', Host path: '%lS' (global mapping)\n", name.raw(), hostPath.raw());
2014 ++numSharedFolders;
2015 CHECK_ERROR_RET(sfEnum, HasMore(&fMore), rc);
2016 }
2017 }
2018#endif
2019 /* now VM mappings */
2020 {
2021 ComPtr<ISharedFolderCollection> sfColl;
2022 ComPtr<ISharedFolderEnumerator> sfEnum;
2023 CHECK_ERROR_RET(machine, COMGETTER(SharedFolders)(sfColl.asOutParam()), rc);
2024 CHECK_ERROR_RET(sfColl, Enumerate(sfEnum.asOutParam()), rc);
2025 ULONG index = 0;
2026 BOOL fMore;
2027 sfEnum->HasMore(&fMore);
2028 while (fMore)
2029 {
2030 ComPtr<ISharedFolder> sf;
2031 CHECK_ERROR_RET(sfEnum, GetNext(sf.asOutParam()), rc);
2032 Bstr name, hostPath;
2033 BOOL writable;
2034 sf->COMGETTER(Name)(name.asOutParam());
2035 sf->COMGETTER(HostPath)(hostPath.asOutParam());
2036 sf->COMGETTER(Writable)(&writable);
2037 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
2038 RTPrintf("\n\n");
2039 if (details == VMINFO_MACHINEREADABLE)
2040 {
2041 RTPrintf("SharedFolderNameMachineMapping%d=\"%lS\"\n", index + 1,
2042 name.raw());
2043 RTPrintf("SharedFolderPathMachineMapping%d=\"%lS\"\n", index + 1,
2044 hostPath.raw());
2045 }
2046 else
2047 RTPrintf("Name: '%lS', Host path: '%lS' (machine mapping), %s\n",
2048 name.raw(), hostPath.raw(), writable ? "writable" : "readonly");
2049 ++numSharedFolders;
2050 CHECK_ERROR_RET(sfEnum, HasMore(&fMore), rc);
2051 }
2052 }
2053 /* transient mappings */
2054 if (console)
2055 {
2056 ComPtr<ISharedFolderCollection> sfColl;
2057 ComPtr<ISharedFolderEnumerator> sfEnum;
2058 CHECK_ERROR_RET(console, COMGETTER(SharedFolders)(sfColl.asOutParam()), rc);
2059 CHECK_ERROR_RET(sfColl, Enumerate(sfEnum.asOutParam()), rc);
2060 ULONG index = 0;
2061 BOOL fMore;
2062 sfEnum->HasMore(&fMore);
2063 while (fMore)
2064 {
2065 ComPtr<ISharedFolder> sf;
2066 CHECK_ERROR_RET(sfEnum, GetNext(sf.asOutParam()), rc);
2067 Bstr name, hostPath;
2068 sf->COMGETTER(Name)(name.asOutParam());
2069 sf->COMGETTER(HostPath)(hostPath.asOutParam());
2070 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
2071 RTPrintf("\n\n");
2072 if (details == VMINFO_MACHINEREADABLE)
2073 {
2074 RTPrintf("SharedFolderNameTransientMapping%d=\"%lS\"\n", index + 1,
2075 name.raw());
2076 RTPrintf("SharedFolderPathTransientMapping%d=\"%lS\"\n", index + 1,
2077 hostPath.raw());
2078 }
2079 else
2080 RTPrintf("Name: '%lS', Host path: '%lS' (transient mapping)\n", name.raw(), hostPath.raw());
2081 ++numSharedFolders;
2082 CHECK_ERROR_RET(sfEnum, HasMore(&fMore), rc);
2083 }
2084 }
2085 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
2086 RTPrintf("<none>\n");
2087 if (details != VMINFO_MACHINEREADABLE)
2088 RTPrintf("\n");
2089
2090 if (console)
2091 {
2092 /*
2093 * Live VRDP info.
2094 */
2095 ComPtr<IRemoteDisplayInfo> remoteDisplayInfo;
2096 CHECK_ERROR_RET(console, COMGETTER(RemoteDisplayInfo)(remoteDisplayInfo.asOutParam()), rc);
2097 BOOL Active;
2098 ULONG NumberOfClients;
2099 LONG64 BeginTime;
2100 LONG64 EndTime;
2101 ULONG64 BytesSent;
2102 ULONG64 BytesSentTotal;
2103 ULONG64 BytesReceived;
2104 ULONG64 BytesReceivedTotal;
2105 Bstr User;
2106 Bstr Domain;
2107 Bstr ClientName;
2108 Bstr ClientIP;
2109 ULONG ClientVersion;
2110 ULONG EncryptionStyle;
2111
2112 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(Active) (&Active), rc);
2113 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(NumberOfClients) (&NumberOfClients), rc);
2114 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(BeginTime) (&BeginTime), rc);
2115 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(EndTime) (&EndTime), rc);
2116 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(BytesSent) (&BytesSent), rc);
2117 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(BytesSentTotal) (&BytesSentTotal), rc);
2118 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(BytesReceived) (&BytesReceived), rc);
2119 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(BytesReceivedTotal) (&BytesReceivedTotal), rc);
2120 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(User) (User.asOutParam ()), rc);
2121 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(Domain) (Domain.asOutParam ()), rc);
2122 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(ClientName) (ClientName.asOutParam ()), rc);
2123 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(ClientIP) (ClientIP.asOutParam ()), rc);
2124 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(ClientVersion) (&ClientVersion), rc);
2125 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(EncryptionStyle) (&EncryptionStyle), rc);
2126
2127 if (details == VMINFO_MACHINEREADABLE)
2128 RTPrintf("VRDPActiveConnection=\"%s\"\n", Active ? "on": "off");
2129 else
2130 RTPrintf("VRDP Connection: %s\n", Active? "active": "not active");
2131
2132 if (details == VMINFO_MACHINEREADABLE)
2133 RTPrintf("VRDPClients=%d\n", NumberOfClients);
2134 else
2135 RTPrintf("Clients so far: %d\n", NumberOfClients);
2136
2137 if (NumberOfClients > 0)
2138 {
2139 char timestr[128];
2140
2141 if (Active)
2142 {
2143 makeTimeStr (timestr, sizeof (timestr), BeginTime);
2144 if (details == VMINFO_MACHINEREADABLE)
2145 RTPrintf("VRDPStartTime=\"%s\"\n", timestr);
2146 else
2147 RTPrintf("Start time: %s\n", timestr);
2148 }
2149 else
2150 {
2151 makeTimeStr (timestr, sizeof (timestr), BeginTime);
2152 if (details == VMINFO_MACHINEREADABLE)
2153 RTPrintf("VRDPLastStartTime=\"%s\"\n", timestr);
2154 else
2155 RTPrintf("Last started: %s\n", timestr);
2156 makeTimeStr (timestr, sizeof (timestr), EndTime);
2157 if (details == VMINFO_MACHINEREADABLE)
2158 RTPrintf("VRDPLastEndTime=\"%s\"\n", timestr);
2159 else
2160 RTPrintf("Last ended: %s\n", timestr);
2161 }
2162
2163 if (details == VMINFO_MACHINEREADABLE)
2164 {
2165 RTPrintf("VRDPBytesSent=%llu\n", BytesSent);
2166 RTPrintf("VRDPThroughputSend=%llu\n", (BytesSent * 1000) / (EndTime - BeginTime) );
2167 RTPrintf("VRDPBytesSentTotal=%llu\n", BytesSentTotal);
2168
2169 RTPrintf("VRDPBytesReceived=%llu\n", BytesReceived);
2170 RTPrintf("VRDPThroughputReceive=%llu\n", (BytesReceived * 1000) / (EndTime - BeginTime) );
2171 RTPrintf("VRDPBytesReceivedTotal=%llu\n", BytesReceivedTotal);
2172 }
2173 else
2174 {
2175 RTPrintf("Sent: %llu Bytes\n", BytesSent);
2176 RTPrintf("Average speed: %llu B/s\n", (BytesSent * 1000) / (EndTime - BeginTime) );
2177 RTPrintf("Sent total: %llu Bytes\n", BytesSentTotal);
2178
2179 RTPrintf("Received: %llu Bytes\n", BytesReceived);
2180 RTPrintf("Speed: %llu B/s\n", (BytesReceived * 1000) / (EndTime - BeginTime) );
2181 RTPrintf("Received total: %llu Bytes\n", BytesReceivedTotal);
2182 }
2183
2184 if (Active)
2185 {
2186 if (details == VMINFO_MACHINEREADABLE)
2187 {
2188 RTPrintf("VRDPUserName=\"%lS\"\n", User.raw());
2189 RTPrintf("VRDPDomain=\"%lS\"\n", Domain.raw());
2190 RTPrintf("VRDPClientName=\"%lS\"\n", ClientName.raw());
2191 RTPrintf("VRDPClientIP=\"%lS\"\n", ClientIP.raw());
2192 RTPrintf("VRDPClientVersion=%d\n", ClientVersion);
2193 RTPrintf("VRDPEncryption=\"%s\"\n", EncryptionStyle == 0? "RDP4": "RDP5 (X.509)");
2194 }
2195 else
2196 {
2197 RTPrintf("User name: %lS\n", User.raw());
2198 RTPrintf("Domain: %lS\n", Domain.raw());
2199 RTPrintf("Client name: %lS\n", ClientName.raw());
2200 RTPrintf("Client IP: %lS\n", ClientIP.raw());
2201 RTPrintf("Client version: %d\n", ClientVersion);
2202 RTPrintf("Encryption: %s\n", EncryptionStyle == 0? "RDP4": "RDP5 (X.509)");
2203 }
2204 }
2205 }
2206
2207 if (details != VMINFO_MACHINEREADABLE)
2208 RTPrintf("\n");
2209 }
2210
2211 if ( details == VMINFO_STANDARD
2212 || details == VMINFO_FULL
2213 || details == VMINFO_MACHINEREADABLE)
2214 {
2215 Bstr description;
2216 machine->COMGETTER(Description)(description.asOutParam());
2217 if (!description.isEmpty())
2218 {
2219 if (details == VMINFO_MACHINEREADABLE)
2220 RTPrintf("description=\"%lS\"\n", description.raw());
2221 else
2222 RTPrintf("Description:\n%lS\n", description.raw());
2223 }
2224 }
2225
2226 ULONG guestVal;
2227 if (details != VMINFO_MACHINEREADABLE)
2228 RTPrintf("Guest:\n\n");
2229
2230#ifdef VBOX_WITH_MEM_BALLOONING
2231 rc = machine->COMGETTER(MemoryBalloonSize)(&guestVal);
2232 if (SUCCEEDED(rc))
2233 {
2234 if (details == VMINFO_MACHINEREADABLE)
2235 RTPrintf("GuestMemoryBalloon=%d\n", guestVal);
2236 else
2237 RTPrintf("Configured memory balloon size: %d MB\n", guestVal);
2238 }
2239#endif
2240 rc = machine->COMGETTER(StatisticsUpdateInterval)(&guestVal);
2241 if (SUCCEEDED(rc))
2242 {
2243 if (details == VMINFO_MACHINEREADABLE)
2244 RTPrintf("GuestStatisticsUpdateInterval=%d\n", guestVal);
2245 else
2246 {
2247 if (guestVal == 0)
2248 RTPrintf("Statistics update: disabled\n");
2249 else
2250 RTPrintf("Statistics update interval: %d seconds\n", guestVal);
2251 }
2252 }
2253 if (details != VMINFO_MACHINEREADABLE)
2254 RTPrintf("\n");
2255
2256 if ( console
2257 && ( details == VMINFO_STATISTICS
2258 || details == VMINFO_FULL
2259 || details == VMINFO_MACHINEREADABLE))
2260 {
2261 ComPtr <IGuest> guest;
2262
2263 rc = console->COMGETTER(Guest)(guest.asOutParam());
2264 if (SUCCEEDED(rc))
2265 {
2266 ULONG statVal;
2267
2268 rc = guest->GetStatistic(0, GuestStatisticType_SampleNumber, &statVal);
2269 if (details == VMINFO_MACHINEREADABLE)
2270 RTPrintf("StatGuestSample=%d\n", statVal);
2271 else
2272 RTPrintf("Guest statistics for sample %d:\n\n", statVal);
2273
2274 rc = guest->GetStatistic(0, GuestStatisticType_CPULoad_Idle, &statVal);
2275 if (SUCCEEDED(rc))
2276 {
2277 if (details == VMINFO_MACHINEREADABLE)
2278 RTPrintf("StatGuestLoadIdleCPU%d=%d\n", 0, statVal);
2279 else
2280 RTPrintf("CPU%d: CPU Load Idle %-3d%%\n", 0, statVal);
2281 }
2282
2283 rc = guest->GetStatistic(0, GuestStatisticType_CPULoad_Kernel, &statVal);
2284 if (SUCCEEDED(rc))
2285 {
2286 if (details == VMINFO_MACHINEREADABLE)
2287 RTPrintf("StatGuestLoadKernelCPU%d=%d\n", 0, statVal);
2288 else
2289 RTPrintf("CPU%d: CPU Load Kernel %-3d%%\n", 0, statVal);
2290 }
2291
2292 rc = guest->GetStatistic(0, GuestStatisticType_CPULoad_User, &statVal);
2293 if (SUCCEEDED(rc))
2294 {
2295 if (details == VMINFO_MACHINEREADABLE)
2296 RTPrintf("StatGuestLoadUserCPU%d=%d\n", 0, statVal);
2297 else
2298 RTPrintf("CPU%d: CPU Load User %-3d%%\n", 0, statVal);
2299 }
2300
2301 rc = guest->GetStatistic(0, GuestStatisticType_Threads, &statVal);
2302 if (SUCCEEDED(rc))
2303 {
2304 if (details == VMINFO_MACHINEREADABLE)
2305 RTPrintf("StatGuestThreadsCPU%d=%d\n", 0, statVal);
2306 else
2307 RTPrintf("CPU%d: Threads %d\n", 0, statVal);
2308 }
2309
2310 rc = guest->GetStatistic(0, GuestStatisticType_Processes, &statVal);
2311 if (SUCCEEDED(rc))
2312 {
2313 if (details == VMINFO_MACHINEREADABLE)
2314 RTPrintf("StatGuestProcessesCPU%d=%d\n", 0, statVal);
2315 else
2316 RTPrintf("CPU%d: Processes %d\n", 0, statVal);
2317 }
2318
2319 rc = guest->GetStatistic(0, GuestStatisticType_Handles, &statVal);
2320 if (SUCCEEDED(rc))
2321 {
2322 if (details == VMINFO_MACHINEREADABLE)
2323 RTPrintf("StatGuestHandlesCPU%d=%d\n", 0, statVal);
2324 else
2325 RTPrintf("CPU%d: Handles %d\n", 0, statVal);
2326 }
2327
2328 rc = guest->GetStatistic(0, GuestStatisticType_MemoryLoad, &statVal);
2329 if (SUCCEEDED(rc))
2330 {
2331 if (details == VMINFO_MACHINEREADABLE)
2332 RTPrintf("StatGuestMemoryLoadCPU%d=%d\n", 0, statVal);
2333 else
2334 RTPrintf("CPU%d: Memory Load %d%%\n", 0, statVal);
2335 }
2336
2337 rc = guest->GetStatistic(0, GuestStatisticType_PhysMemTotal, &statVal);
2338 if (SUCCEEDED(rc))
2339 {
2340 if (details == VMINFO_MACHINEREADABLE)
2341 RTPrintf("StatGuestMemoryTotalPhysCPU%d=%d\n", 0, statVal);
2342 else
2343 RTPrintf("CPU%d: Total physical memory %-4d MB\n", 0, statVal);
2344 }
2345
2346 rc = guest->GetStatistic(0, GuestStatisticType_PhysMemAvailable, &statVal);
2347 if (SUCCEEDED(rc))
2348 {
2349 if (details == VMINFO_MACHINEREADABLE)
2350 RTPrintf("StatGuestMemoryFreePhysCPU%d=%d\n", 0, statVal);
2351 else
2352 RTPrintf("CPU%d: Free physical memory %-4d MB\n", 0, statVal);
2353 }
2354
2355#ifdef VBOX_WITH_MEM_BALLOONING
2356 rc = guest->GetStatistic(0, GuestStatisticType_PhysMemBalloon, &statVal);
2357 if (SUCCEEDED(rc))
2358 {
2359 if (details == VMINFO_MACHINEREADABLE)
2360 RTPrintf("StatGuestMemoryBalloonCPU%d=%d\n", 0, statVal);
2361 else
2362 RTPrintf("CPU%d: Memory balloon size %-4d MB\n", 0, statVal);
2363 }
2364#endif
2365 rc = guest->GetStatistic(0, GuestStatisticType_MemCommitTotal, &statVal);
2366 if (SUCCEEDED(rc))
2367 {
2368 if (details == VMINFO_MACHINEREADABLE)
2369 RTPrintf("StatGuestMemoryCommittedCPU%d=%d\n", 0, statVal);
2370 else
2371 RTPrintf("CPU%d: Committed memory %-4d MB\n", 0, statVal);
2372 }
2373
2374 rc = guest->GetStatistic(0, GuestStatisticType_MemKernelTotal, &statVal);
2375 if (SUCCEEDED(rc))
2376 {
2377 if (details == VMINFO_MACHINEREADABLE)
2378 RTPrintf("StatGuestMemoryTotalKernelCPU%d=%d\n", 0, statVal);
2379 else
2380 RTPrintf("CPU%d: Total kernel memory %-4d MB\n", 0, statVal);
2381 }
2382
2383 rc = guest->GetStatistic(0, GuestStatisticType_MemKernelPaged, &statVal);
2384 if (SUCCEEDED(rc))
2385 {
2386 if (details == VMINFO_MACHINEREADABLE)
2387 RTPrintf("StatGuestMemoryPagedKernelCPU%d=%d\n", 0, statVal);
2388 else
2389 RTPrintf("CPU%d: Paged kernel memory %-4d MB\n", 0, statVal);
2390 }
2391
2392 rc = guest->GetStatistic(0, GuestStatisticType_MemKernelNonpaged, &statVal);
2393 if (SUCCEEDED(rc))
2394 {
2395 if (details == VMINFO_MACHINEREADABLE)
2396 RTPrintf("StatGuestMemoryNonpagedKernelCPU%d=%d\n", 0, statVal);
2397 else
2398 RTPrintf("CPU%d: Nonpaged kernel memory %-4d MB\n", 0, statVal);
2399 }
2400
2401 rc = guest->GetStatistic(0, GuestStatisticType_MemSystemCache, &statVal);
2402 if (SUCCEEDED(rc))
2403 {
2404 if (details == VMINFO_MACHINEREADABLE)
2405 RTPrintf("StatGuestSystemCacheSizeCPU%d=%d\n", 0, statVal);
2406 else
2407 RTPrintf("CPU%d: System cache size %-4d MB\n", 0, statVal);
2408 }
2409
2410 rc = guest->GetStatistic(0, GuestStatisticType_PageFileSize, &statVal);
2411 if (SUCCEEDED(rc))
2412 {
2413 if (details == VMINFO_MACHINEREADABLE)
2414 RTPrintf("StatGuestPageFileSizeCPU%d=%d\n", 0, statVal);
2415 else
2416 RTPrintf("CPU%d: Page file size %-4d MB\n", 0, statVal);
2417 }
2418
2419 RTPrintf("\n");
2420 }
2421 else
2422 {
2423 if (details != VMINFO_MACHINEREADABLE)
2424 {
2425 RTPrintf("[!] FAILED calling console->getGuest at line %d!\n", __LINE__);
2426 PRINT_RC_MESSAGE(rc);
2427 }
2428 }
2429 }
2430
2431 /*
2432 * snapshots
2433 */
2434 ComPtr<ISnapshot> snapshot;
2435 rc = machine->GetSnapshot(Guid(), snapshot.asOutParam());
2436 if (SUCCEEDED(rc) && snapshot)
2437 {
2438 if (details != VMINFO_MACHINEREADABLE)
2439 RTPrintf("Snapshots:\n\n");
2440 showSnapshots(snapshot, details);
2441 }
2442
2443 if (details != VMINFO_MACHINEREADABLE)
2444 RTPrintf("\n");
2445 return S_OK;
2446}
2447
2448static int handleShowVMInfo(int argc, char *argv[],
2449 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
2450{
2451 HRESULT rc;
2452
2453 /* at least one option: the UUID or name of the VM */
2454 if (argc < 1)
2455 return errorSyntax(USAGE_SHOWVMINFO, "Incorrect number of parameters");
2456
2457 /* try to find the given machine */
2458 ComPtr <IMachine> machine;
2459 Guid uuid (argv[0]);
2460 if (!uuid.isEmpty())
2461 {
2462 CHECK_ERROR (virtualBox, GetMachine (uuid, machine.asOutParam()));
2463 }
2464 else
2465 {
2466 CHECK_ERROR (virtualBox, FindMachine (Bstr(argv[0]), machine.asOutParam()));
2467 if (SUCCEEDED (rc))
2468 machine->COMGETTER(Id) (uuid.asOutParam());
2469 }
2470 if (FAILED (rc))
2471 return 1;
2472
2473 /* 2nd option can be -details, -statistics or -argdump */
2474 VMINFO_DETAILS details = VMINFO_NONE;
2475 bool fDetails = false;
2476 bool fStatistics = false;
2477 bool fMachinereadable = false;
2478 for (int i=1;i<argc;i++)
2479 {
2480 if (!strcmp(argv[i], "-details"))
2481 fDetails = true;
2482 else
2483 if (!strcmp(argv[i], "-statistics"))
2484 fStatistics = true;
2485 if (!strcmp(argv[1], "-machinereadable"))
2486 fMachinereadable = true;
2487 }
2488 if (fMachinereadable)
2489 details = VMINFO_MACHINEREADABLE;
2490 else
2491 if (fDetails && fStatistics)
2492 details = VMINFO_FULL;
2493 else
2494 if (fDetails)
2495 details = VMINFO_STANDARD;
2496 else
2497 if (fStatistics)
2498 details = VMINFO_STATISTICS;
2499
2500 ComPtr <IConsole> console;
2501
2502 /* open an existing session for the VM */
2503 rc = virtualBox->OpenExistingSession (session, uuid);
2504 if (SUCCEEDED(rc))
2505 /* get the session machine */
2506 rc = session->COMGETTER(Machine)(machine.asOutParam());
2507 if (SUCCEEDED(rc))
2508 /* get the session console */
2509 rc = session->COMGETTER(Console)(console.asOutParam());
2510
2511 rc = showVMInfo (virtualBox, machine, console, details);
2512
2513 if (console)
2514 session->Close();
2515
2516 return SUCCEEDED (rc) ? 0 : 1;
2517}
2518
2519
2520static int handleList(int argc, char *argv[],
2521 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
2522{
2523 HRESULT rc = S_OK;
2524
2525 /* exactly one option: the object */
2526 if (argc != 1)
2527 return errorSyntax(USAGE_LIST, "Incorrect number of parameters");
2528
2529 /* which object? */
2530 if (strcmp(argv[0], "vms") == 0)
2531 {
2532 /*
2533 * Get the list of all registered VMs
2534 */
2535 ComPtr<IMachineCollection> collection;
2536 rc = virtualBox->COMGETTER(Machines)(collection.asOutParam());
2537 ComPtr<IMachineEnumerator> enumerator;
2538 if (SUCCEEDED(rc))
2539 rc = collection->Enumerate(enumerator.asOutParam());
2540 if (SUCCEEDED(rc))
2541 {
2542 /*
2543 * Iterate through the collection
2544 */
2545 BOOL hasMore = FALSE;
2546 while (enumerator->HasMore(&hasMore), hasMore)
2547 {
2548 ComPtr<IMachine> machine;
2549 rc = enumerator->GetNext(machine.asOutParam());
2550 if ((SUCCEEDED(rc)) && machine)
2551 {
2552 rc = showVMInfo(virtualBox, machine);
2553 }
2554 }
2555 }
2556 }
2557 else
2558 if (strcmp(argv[0], "runningvms") == 0)
2559 {
2560 /*
2561 * Get the list of all _running_ VMs
2562 */
2563 ComPtr<IMachineCollection> collection;
2564 rc = virtualBox->COMGETTER(Machines)(collection.asOutParam());
2565 ComPtr<IMachineEnumerator> enumerator;
2566 if (SUCCEEDED(rc))
2567 rc = collection->Enumerate(enumerator.asOutParam());
2568 if (SUCCEEDED(rc))
2569 {
2570 /*
2571 * Iterate through the collection
2572 */
2573 BOOL hasMore = FALSE;
2574 while (enumerator->HasMore(&hasMore), hasMore)
2575 {
2576 ComPtr<IMachine> machine;
2577 rc = enumerator->GetNext(machine.asOutParam());
2578 if ((SUCCEEDED(rc)) && machine)
2579 {
2580 MachineState_T machineState;
2581 rc = machine->COMGETTER(State)(&machineState);
2582 if (SUCCEEDED(rc))
2583 {
2584 switch (machineState)
2585 {
2586 case MachineState_Running:
2587 case MachineState_Paused:
2588 {
2589 Guid uuid;
2590 rc = machine->COMGETTER(Id) (uuid.asOutParam());
2591 if (SUCCEEDED(rc))
2592 RTPrintf ("%s\n", uuid.toString().raw());
2593 break;
2594 }
2595 }
2596 }
2597 }
2598 }
2599 }
2600 }
2601 else
2602 if (strcmp(argv[0], "ostypes") == 0)
2603 {
2604 ComPtr<IGuestOSTypeCollection> coll;
2605 ComPtr<IGuestOSTypeEnumerator> enumerator;
2606 CHECK_ERROR(virtualBox, COMGETTER(GuestOSTypes)(coll.asOutParam()));
2607 if (SUCCEEDED(rc) && coll)
2608 {
2609 CHECK_ERROR(coll, Enumerate(enumerator.asOutParam()));
2610 BOOL hasMore;
2611 while (SUCCEEDED(enumerator->HasMore(&hasMore)) && hasMore)
2612 {
2613 ComPtr<IGuestOSType> guestOS;
2614 CHECK_RC_BREAK(enumerator->GetNext(guestOS.asOutParam()));
2615 Bstr guestId;
2616 guestOS->COMGETTER(Id)(guestId.asOutParam());
2617 RTPrintf("ID: %lS\n", guestId.raw());
2618 Bstr guestDescription;
2619 guestOS->COMGETTER(Description)(guestDescription.asOutParam());
2620 RTPrintf("Description: %lS\n\n", guestDescription.raw());
2621 }
2622 }
2623 }
2624 else
2625 if (strcmp(argv[0], "hostdvds") == 0)
2626 {
2627 ComPtr<IHost> host;
2628 CHECK_ERROR(virtualBox, COMGETTER(Host)(host.asOutParam()));
2629 ComPtr<IHostDVDDriveCollection> coll;
2630 ComPtr<IHostDVDDriveEnumerator> enumerator;
2631 CHECK_ERROR(host, COMGETTER(DVDDrives)(coll.asOutParam()));
2632 if (SUCCEEDED(rc) && coll)
2633 {
2634 CHECK_ERROR(coll, Enumerate(enumerator.asOutParam()));
2635 BOOL hasMore;
2636 while (SUCCEEDED(enumerator->HasMore(&hasMore)) && hasMore)
2637 {
2638 ComPtr<IHostDVDDrive> dvdDrive;
2639 CHECK_RC_BREAK(enumerator->GetNext(dvdDrive.asOutParam()));
2640 Bstr name;
2641 dvdDrive->COMGETTER(Name)(name.asOutParam());
2642 RTPrintf("Name: %lS\n\n", name.raw());
2643 }
2644 }
2645 }
2646 else
2647 if (strcmp(argv[0], "hostfloppies") == 0)
2648 {
2649 ComPtr<IHost> host;
2650 CHECK_ERROR(virtualBox, COMGETTER(Host)(host.asOutParam()));
2651 ComPtr<IHostFloppyDriveCollection> coll;
2652 ComPtr<IHostFloppyDriveEnumerator> enumerator;
2653 CHECK_ERROR(host, COMGETTER(FloppyDrives)(coll.asOutParam()));
2654 if (SUCCEEDED(rc) && coll)
2655 {
2656 CHECK_ERROR(coll, Enumerate(enumerator.asOutParam()));
2657 BOOL hasMore;
2658 while (SUCCEEDED(enumerator->HasMore(&hasMore)) && hasMore)
2659 {
2660 ComPtr<IHostFloppyDrive> floppyDrive;
2661 CHECK_RC_BREAK(enumerator->GetNext(floppyDrive.asOutParam()));
2662 Bstr name;
2663 floppyDrive->COMGETTER(Name)(name.asOutParam());
2664 RTPrintf("Name: %lS\n\n", name.raw());
2665 }
2666 }
2667 }
2668#ifdef RT_OS_WINDOWS
2669 else
2670 if (strcmp(argv[0], "hostifs") == 0)
2671 {
2672 ComPtr<IHost> host;
2673 CHECK_ERROR(virtualBox, COMGETTER(Host)(host.asOutParam()));
2674 ComPtr<IHostNetworkInterfaceCollection> coll;
2675 ComPtr<IHostNetworkInterfaceEnumerator> enumerator;
2676 CHECK_ERROR(host, COMGETTER(NetworkInterfaces)(coll.asOutParam()));
2677 if (SUCCEEDED(rc) && coll)
2678 {
2679 CHECK_ERROR(coll, Enumerate(enumerator.asOutParam()));
2680 BOOL hasMore;
2681 while (SUCCEEDED(enumerator->HasMore(&hasMore)) && hasMore)
2682 {
2683 ComPtr<IHostNetworkInterface> networkInterface;
2684 CHECK_RC_BREAK(enumerator->GetNext(networkInterface.asOutParam()));
2685 Bstr interfaceName;
2686 networkInterface->COMGETTER(Name)(interfaceName.asOutParam());
2687 RTPrintf("Name: %lS\n", interfaceName.raw());
2688 Guid interfaceGuid;
2689 networkInterface->COMGETTER(Id)(interfaceGuid.asOutParam());
2690 RTPrintf("GUID: %lS\n\n", Bstr(interfaceGuid.toString()));
2691 }
2692 }
2693 }
2694#endif /* RT_OS_WINDOWS */
2695 else
2696 if (strcmp(argv[0], "hdds") == 0)
2697 {
2698 ComPtr<IHardDiskCollection> hddColl;
2699 CHECK_ERROR(virtualBox, COMGETTER(HardDisks)(hddColl.asOutParam()));
2700 ComPtr<IHardDiskEnumerator> enumerator;
2701 CHECK_ERROR(hddColl, Enumerate(enumerator.asOutParam()));
2702 BOOL hasMore;
2703 while (SUCCEEDED(enumerator->HasMore(&hasMore)) && hasMore)
2704 {
2705 ComPtr<IHardDisk> hdd;
2706 CHECK_RC_BREAK(enumerator->GetNext(hdd.asOutParam()));
2707 Guid uuid;
2708 hdd->COMGETTER(Id)(uuid.asOutParam());
2709 RTPrintf("UUID: %s\n", uuid.toString().raw());
2710 HardDiskStorageType_T storageType;
2711 hdd->COMGETTER(StorageType)(&storageType);
2712 const char *storageTypeString = "unknown";
2713 switch (storageType)
2714 {
2715 case HardDiskStorageType_VirtualDiskImage:
2716 storageTypeString = "Virtual Disk Image";
2717 break;
2718 case HardDiskStorageType_ISCSIHardDisk:
2719 storageTypeString = "iSCSI hard disk";
2720 break;
2721 }
2722 RTPrintf("Storage type: %s\n", storageTypeString);
2723 Bstr filepath;
2724 /// @todo (dmik) we temporarily use the location property to
2725 // determine the image file name. This is subject to change
2726 // when iSCSI disks are here (we should either query a
2727 // storage-specific interface from IHardDisk, or "standardize"
2728 // the location property)
2729 hdd->COMGETTER(Location)(filepath.asOutParam());
2730 RTPrintf("Path: %lS\n", filepath.raw());
2731 BOOL fAccessible;
2732 hdd->COMGETTER(AllAccessible)(&fAccessible);
2733 RTPrintf("Accessible: %s\n", fAccessible ? "yes" : "no");
2734 Guid machineUUID;
2735 hdd->COMGETTER(MachineId)(machineUUID.asOutParam());
2736 if (!machineUUID.isEmpty())
2737 {
2738 ComPtr<IMachine> machine;
2739 CHECK_ERROR(virtualBox, GetMachine(machineUUID, machine.asOutParam()));
2740 ASSERT(machine);
2741 Bstr name;
2742 machine->COMGETTER(Name)(name.asOutParam());
2743 machine->COMGETTER(Id)(uuid.asOutParam());
2744 RTPrintf("Usage: %lS (UUID: %s)\n", name.raw(), uuid.toString().raw());
2745 }
2746 RTPrintf("\n");
2747 }
2748 }
2749 else
2750 if (strcmp(argv[0], "dvds") == 0)
2751 {
2752 ComPtr<IDVDImageCollection> dvdColl;
2753 CHECK_ERROR(virtualBox, COMGETTER(DVDImages)(dvdColl.asOutParam()));
2754 ComPtr<IDVDImageEnumerator> enumerator;
2755 CHECK_ERROR(dvdColl, Enumerate(enumerator.asOutParam()));
2756 BOOL hasMore;
2757 while (SUCCEEDED(enumerator->HasMore(&hasMore)) && hasMore)
2758 {
2759 ComPtr<IDVDImage> dvdImage;
2760 CHECK_RC_BREAK(enumerator->GetNext(dvdImage.asOutParam()));
2761 Guid uuid;
2762 dvdImage->COMGETTER(Id)(uuid.asOutParam());
2763 RTPrintf("UUID: %s\n", uuid.toString().raw());
2764 Bstr filePath;
2765 dvdImage->COMGETTER(FilePath)(filePath.asOutParam());
2766 RTPrintf("Path: %lS\n", filePath.raw());
2767 BOOL fAccessible;
2768 dvdImage->COMGETTER(Accessible)(&fAccessible);
2769 RTPrintf("Accessible: %s\n", fAccessible ? "yes" : "no");
2770 Bstr machineUUIDs;
2771 CHECK_ERROR(virtualBox, GetDVDImageUsage(uuid, ResourceUsage_All, machineUUIDs.asOutParam()));
2772 /** @todo usage */
2773 RTPrintf("\n");
2774 }
2775 }
2776 else
2777 if (strcmp(argv[0], "floppies") == 0)
2778 {
2779 ComPtr<IFloppyImageCollection> floppyColl;
2780 CHECK_ERROR(virtualBox, COMGETTER(FloppyImages)(floppyColl.asOutParam()));
2781 ComPtr<IFloppyImageEnumerator> enumerator;
2782 CHECK_ERROR(floppyColl, Enumerate(enumerator.asOutParam()));
2783 BOOL hasMore;
2784 while (SUCCEEDED(enumerator->HasMore(&hasMore)) && hasMore)
2785 {
2786 ComPtr<IFloppyImage> floppyImage;
2787 CHECK_RC_BREAK(enumerator->GetNext(floppyImage.asOutParam()));
2788 Guid uuid;
2789 floppyImage->COMGETTER(Id)(uuid.asOutParam());
2790 RTPrintf("UUID: %s\n", uuid.toString().raw());
2791 Bstr filePath;
2792 floppyImage->COMGETTER(FilePath)(filePath.asOutParam());
2793 RTPrintf("Path: %lS\n", filePath.raw());
2794 BOOL fAccessible;
2795 floppyImage->COMGETTER(Accessible)(&fAccessible);
2796 RTPrintf("Accessible: %s\n", fAccessible ? "yes" : "no");
2797 Bstr machineUUIDs;
2798 CHECK_ERROR(virtualBox, GetFloppyImageUsage(uuid, ResourceUsage_All, machineUUIDs.asOutParam()));
2799 /** @todo usage */
2800 RTPrintf("\n");
2801 }
2802 }
2803 else
2804 if (strcmp(argv[0], "usbhost") == 0)
2805 {
2806 ComPtr<IHost> Host;
2807 CHECK_ERROR_RET (virtualBox, COMGETTER(Host)(Host.asOutParam()), 1);
2808
2809 ComPtr<IHostUSBDeviceCollection> CollPtr;
2810 CHECK_ERROR_RET (Host, COMGETTER(USBDevices)(CollPtr.asOutParam()), 1);
2811
2812 ComPtr<IHostUSBDeviceEnumerator> EnumPtr;
2813 CHECK_ERROR_RET (CollPtr, Enumerate(EnumPtr.asOutParam()), 1);
2814
2815 RTPrintf("Host USB Devices:\n\n");
2816
2817 BOOL fMore = FALSE;
2818 rc = EnumPtr->HasMore (&fMore);
2819 ASSERT_RET (SUCCEEDED (rc), 1);
2820
2821 if (!fMore)
2822 {
2823 RTPrintf("<none>\n\n");
2824 }
2825 else
2826 while (fMore)
2827 {
2828 ComPtr <IHostUSBDevice> dev;
2829 rc = EnumPtr->GetNext (dev.asOutParam());
2830 ASSERT_RET (SUCCEEDED (rc), 1);
2831
2832 /* Query info. */
2833 Guid id;
2834 CHECK_ERROR_RET (dev, COMGETTER(Id)(id.asOutParam()), 1);
2835 USHORT usVendorId;
2836 CHECK_ERROR_RET (dev, COMGETTER(VendorId)(&usVendorId), 1);
2837 USHORT usProductId;
2838 CHECK_ERROR_RET (dev, COMGETTER(ProductId)(&usProductId), 1);
2839 USHORT bcdRevision;
2840 CHECK_ERROR_RET (dev, COMGETTER(Revision)(&bcdRevision), 1);
2841
2842 RTPrintf("UUID: %S\n"
2843 "VendorId: 0x%04x (%04X)\n"
2844 "ProductId: 0x%04x (%04X)\n"
2845 "Revision: %u.%u (%02u%02u)\n",
2846 id.toString().raw(),
2847 usVendorId, usVendorId, usProductId, usProductId,
2848 bcdRevision >> 8, bcdRevision & 0xff,
2849 bcdRevision >> 8, bcdRevision & 0xff);
2850
2851 /* optional stuff. */
2852 Bstr bstr;
2853 CHECK_ERROR_RET (dev, COMGETTER(Manufacturer)(bstr.asOutParam()), 1);
2854 if (!bstr.isEmpty())
2855 RTPrintf("Manufacturer: %lS\n", bstr.raw());
2856 CHECK_ERROR_RET (dev, COMGETTER(Product)(bstr.asOutParam()), 1);
2857 if (!bstr.isEmpty())
2858 RTPrintf("Product: %lS\n", bstr.raw());
2859 CHECK_ERROR_RET (dev, COMGETTER(SerialNumber)(bstr.asOutParam()), 1);
2860 if (!bstr.isEmpty())
2861 RTPrintf("SerialNumber: %lS\n", bstr.raw());
2862 CHECK_ERROR_RET (dev, COMGETTER(Address)(bstr.asOutParam()), 1);
2863 if (!bstr.isEmpty())
2864 RTPrintf("Address: %lS\n", bstr.raw());
2865
2866 /* current state */
2867 USBDeviceState_T state;
2868 CHECK_ERROR_RET (dev, COMGETTER(State)(&state), 1);
2869 const char *pszState = "?";
2870 switch (state)
2871 {
2872 case USBDeviceState_NotSupported:
2873 pszState = "Not supported"; break;
2874 case USBDeviceState_Unavailable:
2875 pszState = "Unavailable"; break;
2876 case USBDeviceState_Busy:
2877 pszState = "Busy"; break;
2878 case USBDeviceState_Available:
2879 pszState = "Available"; break;
2880 case USBDeviceState_Held:
2881 pszState = "Held"; break;
2882 case USBDeviceState_Captured:
2883 pszState = "Captured"; break;
2884 default:
2885 ASSERT (false);
2886 break;
2887 }
2888 RTPrintf("Current State: %s\n\n", pszState);
2889
2890 rc = EnumPtr->HasMore (&fMore);
2891 ASSERT_RET (SUCCEEDED (rc), rc);
2892 }
2893 }
2894 else
2895 if (strcmp(argv[0], "usbfilters") == 0)
2896 {
2897 RTPrintf("Global USB Device Filters:\n\n");
2898
2899 ComPtr <IHost> host;
2900 CHECK_ERROR_RET (virtualBox, COMGETTER(Host) (host.asOutParam()), 1);
2901
2902 ComPtr<IHostUSBDeviceFilterCollection> coll;
2903 CHECK_ERROR_RET (host, COMGETTER (USBDeviceFilters)(coll.asOutParam()), 1);
2904
2905 ComPtr<IHostUSBDeviceFilterEnumerator> en;
2906 CHECK_ERROR_RET (coll, Enumerate(en.asOutParam()), 1);
2907
2908 ULONG index = 0;
2909 BOOL more = FALSE;
2910 rc = en->HasMore (&more);
2911 ASSERT_RET (SUCCEEDED (rc), 1);
2912
2913 if (!more)
2914 {
2915 RTPrintf("<none>\n\n");
2916 }
2917 else
2918 while (more)
2919 {
2920 ComPtr<IHostUSBDeviceFilter> flt;
2921 rc = en->GetNext (flt.asOutParam());
2922 ASSERT_RET (SUCCEEDED (rc), 1);
2923
2924 /* Query info. */
2925
2926 RTPrintf("Index: %lu\n", index);
2927
2928 BOOL active = FALSE;
2929 CHECK_ERROR_RET (flt, COMGETTER (Active) (&active), 1);
2930 RTPrintf("Active: %s\n", active ? "yes" : "no");
2931
2932 USBDeviceFilterAction_T action;
2933 CHECK_ERROR_RET (flt, COMGETTER (Action) (&action), 1);
2934 const char *pszAction = "<invalid>";
2935 switch (action)
2936 {
2937 case USBDeviceFilterAction_Ignore:
2938 pszAction = "Ignore";
2939 break;
2940 case USBDeviceFilterAction_Hold:
2941 pszAction = "Hold";
2942 break;
2943 default:
2944 break;
2945 }
2946 RTPrintf("Action: %s\n", pszAction);
2947
2948 Bstr bstr;
2949 CHECK_ERROR_RET (flt, COMGETTER (Name) (bstr.asOutParam()), 1);
2950 RTPrintf("Name: %lS\n", bstr.raw());
2951 CHECK_ERROR_RET (flt, COMGETTER (VendorId) (bstr.asOutParam()), 1);
2952 RTPrintf("VendorId: %lS\n", bstr.raw());
2953 CHECK_ERROR_RET (flt, COMGETTER (ProductId) (bstr.asOutParam()), 1);
2954 RTPrintf("ProductId: %lS\n", bstr.raw());
2955 CHECK_ERROR_RET (flt, COMGETTER (Revision) (bstr.asOutParam()), 1);
2956 RTPrintf("Revision: %lS\n", bstr.raw());
2957 CHECK_ERROR_RET (flt, COMGETTER (Manufacturer) (bstr.asOutParam()), 1);
2958 RTPrintf("Manufacturer: %lS\n", bstr.raw());
2959 CHECK_ERROR_RET (flt, COMGETTER (Product) (bstr.asOutParam()), 1);
2960 RTPrintf("Product: %lS\n", bstr.raw());
2961 CHECK_ERROR_RET (flt, COMGETTER (SerialNumber) (bstr.asOutParam()), 1);
2962 RTPrintf("Serial Number: %lS\n\n", bstr.raw());
2963
2964 rc = en->HasMore (&more);
2965 ASSERT_RET (SUCCEEDED (rc), 1);
2966
2967 index ++;
2968 }
2969 }
2970 else if (strcmp(argv[0], "systemproperties") == 0)
2971 {
2972 ComPtr<ISystemProperties> systemProperties;
2973 virtualBox->COMGETTER(SystemProperties)(systemProperties.asOutParam());
2974
2975 Bstr str;
2976 ULONG ulValue;
2977 ULONG64 ul64Value;
2978 BOOL flag;
2979
2980 systemProperties->COMGETTER(MinGuestRAM)(&ulValue);
2981 RTPrintf("Minimum guest RAM size: %u Megabytes\n", ulValue);
2982 systemProperties->COMGETTER(MaxGuestRAM)(&ulValue);
2983 RTPrintf("Maximum guest RAM size: %u Megabytes\n", ulValue);
2984 systemProperties->COMGETTER(MaxGuestVRAM)(&ulValue);
2985 RTPrintf("Maximum video RAM size: %u Megabytes\n", ulValue);
2986 systemProperties->COMGETTER(MaxVDISize)(&ul64Value);
2987 RTPrintf("Maximum VDI size: %lu Megabytes\n", ul64Value);
2988 systemProperties->COMGETTER(DefaultVDIFolder)(str.asOutParam());
2989 RTPrintf("Default VDI filder: %lS\n", str.raw());
2990 systemProperties->COMGETTER(DefaultMachineFolder)(str.asOutParam());
2991 RTPrintf("Default machine folder: %lS\n", str.raw());
2992 systemProperties->COMGETTER(RemoteDisplayAuthLibrary)(str.asOutParam());
2993 RTPrintf("VRDP authentication library: %lS\n", str.raw());
2994 systemProperties->COMGETTER(WebServiceAuthLibrary)(str.asOutParam());
2995 RTPrintf("Webservice auth. library: %lS\n", str.raw());
2996 systemProperties->COMGETTER(HWVirtExEnabled)(&flag);
2997 RTPrintf("Hardware virt. extensions: %s\n", flag ? "yes" : "no");
2998 systemProperties->COMGETTER(LogHistoryCount)(&ulValue);
2999 RTPrintf("Log history count: %u\n", ulValue);
3000
3001 }
3002 else
3003 return errorSyntax(USAGE_LIST, "Invalid parameter '%s'", Utf8Str(argv[0]).raw());
3004
3005 return SUCCEEDED(rc) ? 0 : 1;
3006}
3007
3008static int handleRegisterVM(int argc, char *argv[],
3009 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
3010{
3011 HRESULT rc;
3012
3013 if (argc != 1)
3014 return errorSyntax(USAGE_REGISTERVM, "Incorrect number of parameters");
3015
3016 ComPtr<IMachine> machine;
3017 CHECK_ERROR(virtualBox, OpenMachine(Bstr(argv[0]), machine.asOutParam()));
3018 if (SUCCEEDED(rc))
3019 {
3020 ASSERT(machine);
3021 CHECK_ERROR(virtualBox, RegisterMachine(machine));
3022 }
3023 return SUCCEEDED(rc) ? 0 : 1;
3024}
3025
3026static int handleUnregisterVM(int argc, char *argv[],
3027 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
3028{
3029 HRESULT rc;
3030
3031 if ((argc != 1) && (argc != 2))
3032 return errorSyntax(USAGE_UNREGISTERVM, "Incorrect number of parameters");
3033
3034 ComPtr<IMachine> machine;
3035 /* assume it's a UUID */
3036 rc = virtualBox->GetMachine(Guid(argv[0]), machine.asOutParam());
3037 if (FAILED(rc) || !machine)
3038 {
3039 /* must be a name */
3040 CHECK_ERROR(virtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam()));
3041 }
3042 if (machine)
3043 {
3044 Guid uuid;
3045 machine->COMGETTER(Id)(uuid.asOutParam());
3046 machine = NULL;
3047 CHECK_ERROR(virtualBox, UnregisterMachine(uuid, machine.asOutParam()));
3048 if (SUCCEEDED(rc) && machine)
3049 {
3050 /* are we supposed to delete the config file? */
3051 if ((argc == 2) && (strcmp(argv[1], "-delete") == 0))
3052 {
3053 CHECK_ERROR(machine, DeleteSettings());
3054 }
3055 }
3056 }
3057 return SUCCEEDED(rc) ? 0 : 1;
3058}
3059
3060static int handleCreateVDI(int argc, char *argv[],
3061 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
3062{
3063 HRESULT rc;
3064 Bstr filename;
3065 uint64_t sizeMB = 0;
3066 bool fStatic = false;
3067 Bstr comment;
3068 bool fRegister = false;
3069 const char *type = "normal";
3070
3071 /* let's have a closer look at the arguments */
3072 for (int i = 0; i < argc; i++)
3073 {
3074 if (strcmp(argv[i], "-filename") == 0)
3075 {
3076 if (argc <= i + 1)
3077 return errorArgument("Missing argument to '%s'", argv[i]);
3078 i++;
3079 filename = argv[i];
3080 }
3081 else if (strcmp(argv[i], "-size") == 0)
3082 {
3083 if (argc <= i + 1)
3084 return errorArgument("Missing argument to '%s'", argv[i]);
3085 i++;
3086 sizeMB = RTStrToUInt64(argv[i]);
3087 }
3088 else if (strcmp(argv[i], "-static") == 0)
3089 {
3090 fStatic = true;
3091 }
3092 else if (strcmp(argv[i], "-comment") == 0)
3093 {
3094 if (argc <= i + 1)
3095 return errorArgument("Missing argument to '%s'", argv[i]);
3096 i++;
3097 comment = argv[i];
3098 }
3099 else if (strcmp(argv[i], "-register") == 0)
3100 {
3101 fRegister = true;
3102 }
3103 else if (strcmp(argv[i], "-type") == 0)
3104 {
3105 if (argc <= i + 1)
3106 return errorArgument("Missing argument to '%s'", argv[i]);
3107 i++;
3108 type = argv[i];
3109 }
3110 else
3111 return errorSyntax(USAGE_CREATEVDI, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());
3112 }
3113 /* check the outcome */
3114 if (!filename || (sizeMB == 0))
3115 return errorSyntax(USAGE_CREATEVDI, "Parameters -filename and -size are required");
3116
3117 if (strcmp(type, "normal") && strcmp(type, "writethrough"))
3118 return errorArgument("Invalid VDI type '%s' specified", Utf8Str(type).raw());
3119
3120 ComPtr<IHardDisk> hardDisk;
3121 CHECK_ERROR(virtualBox, CreateHardDisk(HardDiskStorageType_VirtualDiskImage, hardDisk.asOutParam()));
3122 if (SUCCEEDED(rc) && hardDisk)
3123 {
3124 CHECK_ERROR(hardDisk,COMSETTER(Description)(comment));
3125 ComPtr<IVirtualDiskImage> vdi = hardDisk;
3126 CHECK_ERROR(vdi, COMSETTER(FilePath)(filename));
3127 ComPtr<IProgress> progress;
3128 if (fStatic)
3129 {
3130 CHECK_ERROR(vdi, CreateFixedImage(sizeMB, progress.asOutParam()));
3131 }
3132 else
3133 {
3134 CHECK_ERROR(vdi, CreateDynamicImage(sizeMB, progress.asOutParam()));
3135 }
3136 if (SUCCEEDED(rc) && progress)
3137 {
3138 if (fStatic)
3139 showProgress(progress);
3140 else
3141 CHECK_ERROR(progress, WaitForCompletion(-1));
3142 if (SUCCEEDED(rc))
3143 {
3144 progress->COMGETTER(ResultCode)(&rc);
3145 if (FAILED(rc))
3146 {
3147 com::ProgressErrorInfo info(progress);
3148 if (info.isBasicAvailable())
3149 RTPrintf("Error: failed to create disk image. Error message: %lS\n", info.getText().raw());
3150 else
3151 RTPrintf("Error: failed to create disk image. No error message available!\n");
3152 }
3153 else
3154 {
3155 Guid uuid;
3156 CHECK_ERROR(hardDisk, COMGETTER(Id)(uuid.asOutParam()));
3157
3158 if (strcmp(type, "normal") == 0)
3159 {
3160 /* nothing required, default */
3161 }
3162 else if (strcmp(type, "writethrough") == 0)
3163 {
3164 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Writethrough));
3165 }
3166
3167 RTPrintf("Disk image created. UUID: %s\n", uuid.toString().raw());
3168 }
3169 }
3170 }
3171 if (SUCCEEDED(rc) && fRegister)
3172 {
3173 CHECK_ERROR(virtualBox, RegisterHardDisk(hardDisk));
3174 }
3175 }
3176 return SUCCEEDED(rc) ? 0 : 1;
3177}
3178
3179static DECLCALLBACK(int) vdiProgressCallback(PVM pVM, unsigned uPercent, void *pvUser)
3180{
3181 unsigned *pPercent = (unsigned *)pvUser;
3182
3183 if (*pPercent != uPercent)
3184 {
3185 *pPercent = uPercent;
3186 RTPrintf(".");
3187 if ((uPercent % 10) == 0 && uPercent)
3188 RTPrintf("%d%%", uPercent);
3189 RTStrmFlush(g_pStdOut);
3190 }
3191
3192 return VINF_SUCCESS;
3193}
3194
3195
3196static int handleModifyVDI(int argc, char *argv[],
3197 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
3198{
3199 HRESULT rc;
3200
3201 /* The uuid/filename and a command */
3202 if (argc < 2)
3203 return errorSyntax(USAGE_MODIFYVDI, "Incorrect number of parameters");
3204
3205 ComPtr<IHardDisk> hardDisk;
3206 ComPtr<IVirtualDiskImage> vdi;
3207 Bstr filepath;
3208
3209 /* first guess is that it's a UUID */
3210 Guid uuid(argv[0]);
3211 rc = virtualBox->GetHardDisk(uuid, hardDisk.asOutParam());
3212 /* no? then it must be a filename */
3213 if (!hardDisk)
3214 {
3215 filepath = argv[0];
3216 CHECK_ERROR(virtualBox, FindVirtualDiskImage(filepath, vdi.asOutParam()));
3217 hardDisk = vdi;
3218 }
3219 else
3220 {
3221 vdi = hardDisk;
3222 }
3223
3224 /* let's find out which command */
3225// doesn't currently work if (strcmp(argv[1], "settype") == 0)
3226 if (0)
3227 {
3228 /* hard disk must be registered */
3229 if (SUCCEEDED(rc) && hardDisk && vdi)
3230 {
3231 char *type = NULL;
3232
3233 if (argc <= 2)
3234 return errorArgument("Missing argument to for settype");
3235
3236 type = argv[2];
3237
3238 HardDiskType_T hddType;
3239 CHECK_ERROR(hardDisk, COMGETTER(Type)(&hddType));
3240
3241 if (strcmp(type, "normal") == 0)
3242 {
3243 if (hddType != HardDiskType_Normal)
3244 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Normal));
3245 }
3246 else if (strcmp(type, "writethrough") == 0)
3247 {
3248 if (hddType != HardDiskType_Writethrough)
3249 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Writethrough));
3250
3251 }
3252 else if (strcmp(type, "immutable") == 0)
3253 {
3254 if (hddType != HardDiskType_Immutable)
3255 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Immutable));
3256 }
3257 else
3258 {
3259 return errorArgument("Invalid VDI type '%s' specified", Utf8Str(type).raw());
3260 }
3261 }
3262 else
3263 return errorArgument("Hard disk image not registered");
3264 }
3265 else if (strcmp(argv[1], "compact") == 0)
3266 {
3267 ComPtr<IVirtualDiskImage> vdi;
3268
3269 /* the hard disk image might not be registered */
3270 if (!hardDisk)
3271 {
3272 virtualBox->OpenVirtualDiskImage(Bstr(argv[0]), vdi.asOutParam());
3273 if (!vdi)
3274 return errorArgument("Hard disk image not found");
3275 }
3276 else
3277 vdi = hardDisk;
3278
3279 if (!vdi)
3280 return errorArgument("Invalid hard disk type. The command only works on VDI files\n");
3281
3282 Bstr fileName;
3283 vdi->COMGETTER(FilePath)(fileName.asOutParam());
3284
3285 /* close the file */
3286 hardDisk = NULL;
3287 vdi = NULL;
3288
3289 unsigned uProcent;
3290
3291 RTPrintf("Shrinking '%lS': 0%%", fileName.raw());
3292 int vrc = VDIShrinkImage(Utf8Str(fileName).raw(), vdiProgressCallback, &uProcent);
3293 if (VBOX_FAILURE(vrc))
3294 {
3295 RTPrintf("Error while shrinking hard disk image: %Vrc\n", vrc);
3296 rc = E_FAIL;
3297 }
3298 }
3299 else
3300 return errorSyntax(USAGE_MODIFYVDI, "Invalid parameter '%s'", Utf8Str(argv[1]).raw());
3301
3302 return SUCCEEDED(rc) ? 0 : 1;
3303}
3304
3305static int handleCloneVDI(int argc, char *argv[],
3306 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
3307{
3308 HRESULT rc;
3309
3310 /* source VDI and target path */
3311 if (argc != 2)
3312 return errorSyntax(USAGE_CLONEVDI, "Incorrect number of parameters");
3313
3314 /* first guess is that it's a UUID */
3315 Guid uuid(argv[0]);
3316 ComPtr<IHardDisk> hardDisk;
3317 rc = virtualBox->GetHardDisk(uuid, hardDisk.asOutParam());
3318 if (!hardDisk)
3319 {
3320 /* not successful? Then it must be a filename */
3321 ComPtr<IVirtualDiskImage> vdi;
3322 CHECK_ERROR(virtualBox, OpenVirtualDiskImage(Bstr(argv[0]), vdi.asOutParam()));
3323 hardDisk = vdi;
3324 }
3325 if (hardDisk)
3326 {
3327 ComPtr<IVirtualDiskImage> vdiOut;
3328 ComPtr<IProgress> progress;
3329 CHECK_ERROR(hardDisk, CloneToImage(Bstr(argv[1]), vdiOut.asOutParam(), progress.asOutParam()));
3330 if (SUCCEEDED(rc))
3331 {
3332 showProgress(progress);
3333 progress->COMGETTER(ResultCode)(&rc);
3334 if (FAILED(rc))
3335 {
3336 com::ProgressErrorInfo info(progress);
3337 if (info.isBasicAvailable())
3338 {
3339 RTPrintf("Error: failed to clone disk image. Error message: %lS\n", info.getText().raw());
3340 }
3341 else
3342 {
3343 RTPrintf("Error: failed to clone disk image. No error message available!\n");
3344 }
3345 }
3346 }
3347 }
3348 return SUCCEEDED(rc) ? 0 : 1;
3349}
3350
3351static int handleConvertDDImage(int argc, char *argv[])
3352{
3353 int arg = 0;
3354 VDIIMAGETYPE enmImgType = VDI_IMAGE_TYPE_NORMAL;
3355 if (argc >= 1 && !strcmp(argv[arg], "-static"))
3356 {
3357 arg++;
3358 enmImgType = VDI_IMAGE_TYPE_FIXED;
3359 }
3360
3361#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS)
3362 const bool fReadFromStdIn = (argc >= arg + 1) && !strcmp(argv[arg], "stdin");
3363#else
3364 const bool fReadFromStdIn = false;
3365#endif
3366
3367 if ((!fReadFromStdIn && argc != arg + 2) || (fReadFromStdIn && argc != arg + 3))
3368 return errorSyntax(USAGE_CONVERTDD, "Incorrect number of parameters");
3369
3370 RTPrintf("Converting VDI: from DD image file=\"%s\" to file=\"%s\"...\n",
3371 argv[arg], argv[arg + 1]);
3372
3373 /* open raw image file. */
3374 RTFILE File;
3375 int rc = VINF_SUCCESS;
3376 if (fReadFromStdIn)
3377 File = 0;
3378 else
3379 rc = RTFileOpen(&File, argv[arg], RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE);
3380 if (VBOX_FAILURE(rc))
3381 {
3382 RTPrintf("File=\"%s\" open error: %Rrf\n", argv[arg], rc);
3383 return rc;
3384 }
3385
3386 uint64_t cbFile;
3387 /* get image size. */
3388 if (fReadFromStdIn)
3389 cbFile = RTStrToUInt64(argv[arg + 2]);
3390 else
3391 rc = RTFileGetSize(File, &cbFile);
3392 if (VBOX_SUCCESS(rc))
3393 {
3394 RTPrintf("Creating %s image with size %RU64 bytes (%RU64MB)...\n", (enmImgType == VDI_IMAGE_TYPE_FIXED) ? "fixed" : "dynamic", cbFile, (cbFile + _1M - 1) / _1M);
3395 char pszComment[256];
3396 RTStrPrintf(pszComment, sizeof(pszComment), "Converted image from %s", argv[arg]);
3397 rc = VDICreateBaseImage(argv[arg + 1],
3398 enmImgType,
3399 cbFile,
3400 pszComment, NULL, NULL);
3401 if (VBOX_SUCCESS(rc))
3402 {
3403 PVDIDISK pVdi = VDIDiskCreate();
3404 rc = VDIDiskOpenImage(pVdi, argv[arg + 1], VDI_OPEN_FLAGS_NORMAL);
3405 if (VBOX_SUCCESS(rc))
3406 {
3407 /* alloc work buffer. */
3408 size_t cbBuffer = VDIDiskGetBufferSize(pVdi);
3409 void *pvBuf = RTMemAlloc(cbBuffer);
3410 if (pvBuf)
3411 {
3412 uint64_t offFile = 0;
3413 while (offFile < cbFile)
3414 {
3415 size_t cbRead = 0;
3416 size_t cbToRead = cbFile - offFile >= (uint64_t) cbBuffer ?
3417 cbBuffer : (size_t) (cbFile - offFile);
3418 rc = RTFileRead(File, pvBuf, cbToRead, &cbRead);
3419 if (VBOX_FAILURE(rc) || !cbRead)
3420 break;
3421 rc = VDIDiskWrite(pVdi, offFile, pvBuf, cbRead);
3422 if (VBOX_FAILURE(rc))
3423 break;
3424 offFile += cbRead;
3425 }
3426
3427 RTMemFree(pvBuf);
3428 }
3429 else
3430 rc = VERR_NO_MEMORY;
3431
3432 VDIDiskCloseImage(pVdi);
3433 }
3434
3435 if (VBOX_FAILURE(rc))
3436 {
3437 /* delete image on error */
3438 RTPrintf("Failed (%Vrc)!\n", rc);
3439 VDIDeleteImage(argv[arg + 1]);
3440 }
3441 }
3442 else
3443 RTPrintf("Failed to create output file (%Vrc)!\n", rc);
3444 }
3445 RTFileClose(File);
3446
3447 return rc;
3448}
3449
3450static int handleAddiSCSIDisk(int argc, char *argv[],
3451 ComPtr <IVirtualBox> aVirtualBox, ComPtr<ISession> aSession)
3452{
3453 HRESULT rc;
3454 Bstr server;
3455 Bstr target;
3456 uint16_t port = UINT16_MAX;
3457 uint64_t lun = UINT64_MAX;
3458 Bstr username;
3459 Bstr password;
3460 Bstr comment;
3461
3462 /* at least server and target */
3463 if (argc < 4)
3464 return errorSyntax(USAGE_ADDISCSIDISK, "Not enough parameters");
3465
3466 /* let's have a closer look at the arguments */
3467 for (int i = 0; i < argc; i++)
3468 {
3469 if (strcmp(argv[i], "-server") == 0)
3470 {
3471 if (argc <= i + 1)
3472 return errorArgument("Missing argument to '%s'", argv[i]);
3473 i++;
3474 server = argv[i];
3475 }
3476 else if (strcmp(argv[i], "-target") == 0)
3477 {
3478 if (argc <= i + 1)
3479 return errorArgument("Missing argument to '%s'", argv[i]);
3480 i++;
3481 target = argv[i];
3482 }
3483 else if (strcmp(argv[i], "-port") == 0)
3484 {
3485 if (argc <= i + 1)
3486 return errorArgument("Missing argument to '%s'", argv[i]);
3487 i++;
3488 port = atoi(argv[i]);
3489 }
3490 else if (strcmp(argv[i], "-lun") == 0)
3491 {
3492 /** @todo move the LUN encoding algorithm into IISCSIHardDisk, add decoding */
3493 if (argc <= i + 1)
3494 return errorArgument("Missing argument to '%s'", argv[i]);
3495 i++;
3496 char *pszNext;
3497 int rc = RTStrToUInt64Ex(argv[i], &pszNext, 0, &lun);
3498 if (VBOX_FAILURE(rc) || *pszNext != '\0' || lun >= 16384)
3499 return errorArgument("Invalid LUN number '%s'", argv[i]);
3500 if (lun <= 255)
3501 {
3502 /* Assume bus identifier = 0. */
3503 lun = (lun << 48); /* uses peripheral device addressing method */
3504 }
3505 else
3506 {
3507 /* Check above already limited the LUN to 14 bits. */
3508 lun = (lun << 48) | RT_BIT_64(62); /* uses flat space addressing method */
3509 }
3510 }
3511 else if (strcmp(argv[i], "-encodedlun") == 0)
3512 {
3513 if (argc <= i + 1)
3514 return errorArgument("Missing argument to '%s'", argv[i]);
3515 i++;
3516 char *pszNext;
3517 int rc = RTStrToUInt64Ex(argv[i], &pszNext, 0, &lun);
3518 if (VBOX_FAILURE(rc) || *pszNext != '\0')
3519 return errorArgument("Invalid encoded LUN number '%s'", argv[i]);
3520 }
3521 else if (strcmp(argv[i], "-username") == 0)
3522 {
3523 if (argc <= i + 1)
3524 return errorArgument("Missing argument to '%s'", argv[i]);
3525 i++;
3526 username = argv[i];
3527 }
3528 else if (strcmp(argv[i], "-password") == 0)
3529 {
3530 if (argc <= i + 1)
3531 return errorArgument("Missing argument to '%s'", argv[i]);
3532 i++;
3533 password = argv[i];
3534 }
3535 else if (strcmp(argv[i], "-comment") == 0)
3536 {
3537 if (argc <= i + 1)
3538 return errorArgument("Missing argument to '%s'", argv[i]);
3539 i++;
3540 comment = argv[i];
3541 }
3542 else
3543 return errorSyntax(USAGE_ADDISCSIDISK, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());
3544 }
3545
3546 /* check for required options */
3547 if (!server || !target)
3548 return errorSyntax(USAGE_ADDISCSIDISK, "Parameters -server and -target are required");
3549
3550 ComPtr<IHardDisk> hardDisk;
3551 CHECK_ERROR(aVirtualBox, CreateHardDisk(HardDiskStorageType_ISCSIHardDisk, hardDisk.asOutParam()));
3552 if (SUCCEEDED(rc) && hardDisk)
3553 {
3554 CHECK_ERROR(hardDisk, COMSETTER(Description)(comment));
3555 ComPtr<IISCSIHardDisk> iSCSIDisk = hardDisk;
3556 CHECK_ERROR(iSCSIDisk, COMSETTER(Server)(server));
3557 if (port != UINT16_MAX)
3558 CHECK_ERROR(iSCSIDisk, COMSETTER(Port)(port));
3559 CHECK_ERROR(iSCSIDisk, COMSETTER(Target)(target));
3560 if (lun != UINT64_MAX)
3561 CHECK_ERROR(iSCSIDisk, COMSETTER(Lun)(lun));
3562 CHECK_ERROR(iSCSIDisk, COMSETTER(UserName)(username));
3563 CHECK_ERROR(iSCSIDisk, COMSETTER(Password)(password));
3564
3565 if (SUCCEEDED(rc))
3566 {
3567 CHECK_ERROR(aVirtualBox, RegisterHardDisk(hardDisk));
3568 }
3569
3570 if (SUCCEEDED(rc))
3571 {
3572 Guid guid;
3573 CHECK_ERROR(hardDisk, COMGETTER(Id)(guid.asOutParam()));
3574 RTPrintf("iSCSI disk created. UUID: %s\n", guid.toString().raw());
3575 }
3576 }
3577
3578 return SUCCEEDED(rc) ? 0 : 1;
3579}
3580
3581static int handleCreateVM(int argc, char *argv[],
3582 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
3583{
3584 HRESULT rc;
3585 Bstr baseFolder;
3586 Bstr settingsFile;
3587 Bstr name;
3588 RTUUID id;
3589 bool fRegister = false;
3590
3591 RTUuidClear(&id);
3592 for (int i = 0; i < argc; i++)
3593 {
3594 if (strcmp(argv[i], "-basefolder") == 0)
3595 {
3596 if (argc <= i + 1)
3597 return errorArgument("Missing argument to '%s'", argv[i]);
3598 i++;
3599 baseFolder = argv[i];
3600 }
3601 else if (strcmp(argv[i], "-settingsfile") == 0)
3602 {
3603 if (argc <= i + 1)
3604 return errorArgument("Missing argument to '%s'", argv[i]);
3605 i++;
3606 settingsFile = argv[i];
3607 }
3608 else if (strcmp(argv[i], "-name") == 0)
3609 {
3610 if (argc <= i + 1)
3611 return errorArgument("Missing argument to '%s'", argv[i]);
3612 i++;
3613 name = argv[i];
3614 }
3615 else if (strcmp(argv[i], "-uuid") == 0)
3616 {
3617 if (argc <= i + 1)
3618 return errorArgument("Missing argument to '%s'", argv[i]);
3619 i++;
3620 if (VBOX_FAILURE(RTUuidFromStr(&id, argv[i])))
3621 return errorArgument("Invalid UUID format %s\n", argv[i]);
3622 }
3623 else if (strcmp(argv[i], "-register") == 0)
3624 {
3625 fRegister = true;
3626 }
3627 else
3628 return errorSyntax(USAGE_CREATEVM, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());
3629 }
3630 if (!name)
3631 return errorSyntax(USAGE_CREATEVM, "Parameter -name is required");
3632
3633 if (!!baseFolder && !!settingsFile)
3634 return errorSyntax(USAGE_CREATEVM, "Either -basefolder or -settingsfile must be specified");
3635
3636 do
3637 {
3638 ComPtr<IMachine> machine;
3639
3640 if (!settingsFile)
3641 CHECK_ERROR_BREAK(virtualBox,
3642 CreateMachine(baseFolder, name, Guid(id), machine.asOutParam()));
3643 else
3644 CHECK_ERROR_BREAK(virtualBox,
3645 CreateLegacyMachine(settingsFile, name, Guid(id), machine.asOutParam()));
3646
3647 CHECK_ERROR_BREAK(machine, SaveSettings());
3648 if (fRegister)
3649 {
3650 CHECK_ERROR_BREAK(virtualBox, RegisterMachine(machine));
3651 }
3652 Guid uuid;
3653 CHECK_ERROR_BREAK(machine, COMGETTER(Id)(uuid.asOutParam()));
3654 CHECK_ERROR_BREAK(machine, COMGETTER(SettingsFilePath)(settingsFile.asOutParam()));
3655 RTPrintf("Virtual machine '%ls' is created%s.\n"
3656 "UUID: %s\n"
3657 "Settings file: '%ls'\n",
3658 name.raw(), fRegister ? " and registered" : "",
3659 uuid.toString().raw(), settingsFile.raw());
3660 }
3661 while (0);
3662
3663 return SUCCEEDED(rc) ? 0 : 1;
3664}
3665
3666/**
3667 * Parses a number.
3668 *
3669 * @returns Valid number on success.
3670 * @returns 0 if invalid number. All necesary bitching has been done.
3671 * @param psz Pointer to the nic number.
3672 */
3673static unsigned parseNum(const char *psz, unsigned cMaxNum, const char *name)
3674{
3675 uint32_t u32;
3676 char *pszNext;
3677 int rc = RTStrToUInt32Ex(psz, &pszNext, 10, &u32);
3678 if ( VBOX_SUCCESS(rc)
3679 && *pszNext == '\0'
3680 && u32 >= 1
3681 && u32 <= cMaxNum)
3682 return (unsigned)u32;
3683 errorArgument("Invalid %s number '%s'", name, psz);
3684 return 0;
3685}
3686
3687static int handleModifyVM(int argc, char *argv[],
3688 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
3689{
3690 HRESULT rc;
3691 Bstr name;
3692 Bstr ostype;
3693 ULONG memorySize = 0;
3694 ULONG vramSize = 0;
3695 char *acpi = NULL;
3696 char *hwvirtex = NULL;
3697 char *pae = NULL;
3698 char *ioapic = NULL;
3699 int monitorcount = -1;
3700 char *bioslogofadein = NULL;
3701 char *bioslogofadeout = NULL;
3702 uint32_t bioslogodisplaytime = ~0;
3703 char *bioslogoimagepath = NULL;
3704 char *biosbootmenumode = NULL;
3705 char *biossystemtimeoffset = NULL;
3706 char *biospxedebug = NULL;
3707 DeviceType_T bootDevice[4];
3708 int bootDeviceChanged[4] = { false };
3709 char *hdds[34] = {0};
3710 char *dvd = NULL;
3711 char *dvdpassthrough = NULL;
3712 char *floppy = NULL;
3713 char *audio = NULL;
3714 char *audiocontroller = NULL;
3715 char *clipboard = NULL;
3716#ifdef VBOX_VRDP
3717 char *vrdp = NULL;
3718 uint16_t vrdpport = UINT16_MAX;
3719 char *vrdpaddress = NULL;
3720 char *vrdpauthtype = NULL;
3721 char *vrdpmulticon = NULL;
3722#endif
3723 int fUsbEnabled = -1;
3724 int fUsbEhciEnabled = -1;
3725 char *snapshotFolder = NULL;
3726 ULONG guestMemBalloonSize = (ULONG)-1;
3727 ULONG guestStatInterval = (ULONG)-1;
3728 int fSataEnabled = -1;
3729 int sataPortCount = -1;
3730 int sataBootDevices[4] = {-1,-1,-1,-1};
3731
3732 /* VM ID + at least one parameter. Parameter arguments are checked
3733 * individually. */
3734 if (argc < 2)
3735 return errorSyntax(USAGE_MODIFYVM, "Not enough parameters");
3736
3737 /* Get the number of network adapters */
3738 ULONG NetworkAdapterCount = 0;
3739 {
3740 ComPtr <ISystemProperties> info;
3741 CHECK_ERROR_RET (virtualBox, COMGETTER(SystemProperties) (info.asOutParam()), 1);
3742 CHECK_ERROR_RET (info, COMGETTER(NetworkAdapterCount) (&NetworkAdapterCount), 1);
3743 }
3744 ULONG SerialPortCount = 0;
3745 {
3746 ComPtr <ISystemProperties> info;
3747 CHECK_ERROR_RET (virtualBox, COMGETTER(SystemProperties) (info.asOutParam()), 1);
3748 CHECK_ERROR_RET (info, COMGETTER(SerialPortCount) (&SerialPortCount), 1);
3749 }
3750
3751 std::vector <char *> nics (NetworkAdapterCount, 0);
3752 std::vector <char *> nictype (NetworkAdapterCount, 0);
3753 std::vector <char *> cableconnected (NetworkAdapterCount, 0);
3754 std::vector <char *> nictrace (NetworkAdapterCount, 0);
3755 std::vector <char *> nictracefile (NetworkAdapterCount, 0);
3756 std::vector <char *> nicspeed (NetworkAdapterCount, 0);
3757 std::vector <char *> hostifdev (NetworkAdapterCount, 0);
3758 std::vector <const char *> intnet (NetworkAdapterCount, 0);
3759 std::vector <const char *> natnet (NetworkAdapterCount, 0);
3760#ifdef RT_OS_LINUX
3761 std::vector <char *> tapsetup (NetworkAdapterCount, 0);
3762 std::vector <char *> tapterm (NetworkAdapterCount, 0);
3763#endif
3764 std::vector <char *> macs (NetworkAdapterCount, 0);
3765 std::vector <char *> uarts_mode (SerialPortCount, 0);
3766 std::vector <ULONG> uarts_base (SerialPortCount, 0);
3767 std::vector <ULONG> uarts_irq (SerialPortCount, 0);
3768 std::vector <char *> uarts_path (SerialPortCount, 0);
3769
3770 for (int i = 1; i < argc; i++)
3771 {
3772 if (strcmp(argv[i], "-name") == 0)
3773 {
3774 if (argc <= i + 1)
3775 return errorArgument("Missing argument to '%s'", argv[i]);
3776 i++;
3777 name = argv[i];
3778 }
3779 else if (strcmp(argv[i], "-ostype") == 0)
3780 {
3781 if (argc <= i + 1)
3782 return errorArgument("Missing argument to '%s'", argv[i]);
3783 i++;
3784 ostype = argv[i];
3785 }
3786 else if (strcmp(argv[i], "-memory") == 0)
3787 {
3788 if (argc <= i + 1)
3789 return errorArgument("Missing argument to '%s'", argv[i]);
3790 i++;
3791 memorySize = atoi(argv[i]);
3792 }
3793 else if (strcmp(argv[i], "-vram") == 0)
3794 {
3795 if (argc <= i + 1)
3796 return errorArgument("Missing argument to '%s'", argv[i]);
3797 i++;
3798 vramSize = atoi(argv[i]);
3799 }
3800 else if (strcmp(argv[i], "-acpi") == 0)
3801 {
3802 if (argc <= i + 1)
3803 return errorArgument("Missing argument to '%s'", argv[i]);
3804 i++;
3805 acpi = argv[i];
3806 }
3807 else if (strcmp(argv[i], "-ioapic") == 0)
3808 {
3809 if (argc <= i + 1)
3810 return errorArgument("Missing argument to '%s'", argv[i]);
3811 i++;
3812 ioapic = argv[i];
3813 }
3814 else if (strcmp(argv[i], "-hwvirtex") == 0)
3815 {
3816 if (argc <= i + 1)
3817 return errorArgument("Missing argument to '%s'", argv[i]);
3818 i++;
3819 hwvirtex = argv[i];
3820 }
3821 else if (strcmp(argv[i], "-pae") == 0)
3822 {
3823 if (argc <= i + 1)
3824 return errorArgument("Missing argument to '%s'", argv[i]);
3825 i++;
3826 pae = argv[i];
3827 }
3828 else if (strcmp(argv[i], "-monitorcount") == 0)
3829 {
3830 if (argc <= i + 1)
3831 return errorArgument("Missing argument to '%s'", argv[i]);
3832 i++;
3833 monitorcount = atoi(argv[i]);
3834 }
3835 else if (strcmp(argv[i], "-bioslogofadein") == 0)
3836 {
3837 if (argc <= i + 1)
3838 return errorArgument("Missing argument to '%s'", argv[i]);
3839 i++;
3840 bioslogofadein = argv[i];
3841 }
3842 else if (strcmp(argv[i], "-bioslogofadeout") == 0)
3843 {
3844 if (argc <= i + 1)
3845 return errorArgument("Missing argument to '%s'", argv[i]);
3846 i++;
3847 bioslogofadeout = argv[i];
3848 }
3849 else if (strcmp(argv[i], "-bioslogodisplaytime") == 0)
3850 {
3851 if (argc <= i + 1)
3852 return errorArgument("Missing argument to '%s'", argv[i]);
3853 i++;
3854 bioslogodisplaytime = atoi(argv[i]);
3855 }
3856 else if (strcmp(argv[i], "-bioslogoimagepath") == 0)
3857 {
3858 if (argc <= i + 1)
3859 return errorArgument("Missing argument to '%s'", argv[i]);
3860 i++;
3861 bioslogoimagepath = argv[i];
3862 }
3863 else if (strcmp(argv[i], "-biosbootmenu") == 0)
3864 {
3865 if (argc <= i + 1)
3866 return errorArgument("Missing argument to '%s'", argv[i]);
3867 i++;
3868 biosbootmenumode = argv[i];
3869 }
3870 else if (strcmp(argv[i], "-biossystemtimeoffset") == 0)
3871 {
3872 if (argc <= i + 1)
3873 return errorArgument("Missing argument to '%s'", argv[i]);
3874 i++;
3875 biossystemtimeoffset = argv[i];
3876 }
3877 else if (strcmp(argv[i], "-biospxedebug") == 0)
3878 {
3879 if (argc <= i + 1)
3880 return errorArgument("Missing argument to '%s'", argv[i]);
3881 i++;
3882 biospxedebug = argv[i];
3883 }
3884 else if (strncmp(argv[i], "-boot", 5) == 0)
3885 {
3886 ULONG n = 0;
3887 if (!argv[i][5])
3888 return errorSyntax(USAGE_MODIFYVM, "Missing boot slot number in '%s'", argv[i]);
3889 if ((n = strtoul(&argv[i][5], NULL, 10)) < 1)
3890 return errorSyntax(USAGE_MODIFYVM, "Invalid boot slot number in '%s'", argv[i]);
3891 if (argc <= i + 1)
3892 return errorArgument("Missing argument to '%s'", argv[i]);
3893 i++;
3894 if (strcmp(argv[i], "none") == 0)
3895 {
3896 bootDevice[n - 1] = DeviceType_Null;
3897 }
3898 else if (strcmp(argv[i], "floppy") == 0)
3899 {
3900 bootDevice[n - 1] = DeviceType_Floppy;
3901 }
3902 else if (strcmp(argv[i], "dvd") == 0)
3903 {
3904 bootDevice[n - 1] = DeviceType_DVD;
3905 }
3906 else if (strcmp(argv[i], "disk") == 0)
3907 {
3908 bootDevice[n - 1] = DeviceType_HardDisk;
3909 }
3910 else if (strcmp(argv[i], "net") == 0)
3911 {
3912 bootDevice[n - 1] = DeviceType_Network;
3913 }
3914 else
3915 return errorArgument("Invalid boot device '%s'", argv[i]);
3916
3917 bootDeviceChanged[n - 1] = true;
3918 }
3919 else if (strcmp(argv[i], "-hda") == 0)
3920 {
3921 if (argc <= i + 1)
3922 return errorArgument("Missing argument to '%s'", argv[i]);
3923 i++;
3924 hdds[0] = argv[i];
3925 }
3926 else if (strcmp(argv[i], "-hdb") == 0)
3927 {
3928 if (argc <= i + 1)
3929 return errorArgument("Missing argument to '%s'", argv[i]);
3930 i++;
3931 hdds[1] = argv[i];
3932 }
3933 else if (strcmp(argv[i], "-hdd") == 0)
3934 {
3935 if (argc <= i + 1)
3936 return errorArgument("Missing argument to '%s'", argv[i]);
3937 i++;
3938 hdds[2] = argv[i];
3939 }
3940 else if (strcmp(argv[i], "-dvd") == 0)
3941 {
3942 if (argc <= i + 1)
3943 return errorArgument("Missing argument to '%s'", argv[i]);
3944 i++;
3945 dvd = argv[i];
3946 }
3947 else if (strcmp(argv[i], "-dvdpassthrough") == 0)
3948 {
3949 if (argc <= i + 1)
3950 return errorArgument("Missing argument to '%s'", argv[i]);
3951 i++;
3952 dvdpassthrough = argv[i];
3953 }
3954 else if (strcmp(argv[i], "-floppy") == 0)
3955 {
3956 if (argc <= i + 1)
3957 return errorArgument("Missing argument to '%s'", argv[i]);
3958 i++;
3959 floppy = argv[i];
3960 }
3961 else if (strcmp(argv[i], "-audio") == 0)
3962 {
3963 if (argc <= i + 1)
3964 return errorArgument("Missing argument to '%s'", argv[i]);
3965 i++;
3966 audio = argv[i];
3967 }
3968 else if (strcmp(argv[i], "-audiocontroller") == 0)
3969 {
3970 if (argc <= i + 1)
3971 return errorArgument("Missing argument to '%s'", argv[i]);
3972 i++;
3973 audiocontroller = argv[i];
3974 }
3975 else if (strcmp(argv[i], "-clipboard") == 0)
3976 {
3977 if (argc <= i + 1)
3978 return errorArgument("Missing argument to '%s'", argv[i]);
3979 i++;
3980 clipboard = argv[i];
3981 }
3982 else if (strncmp(argv[i], "-cableconnected", 15) == 0)
3983 {
3984 unsigned n = parseNum(&argv[i][15], NetworkAdapterCount, "NIC");
3985 if (!n)
3986 return 1;
3987
3988 if (argc <= i + 1)
3989 return errorArgument("Missing argument to '%s'", argv[i]);
3990
3991 cableconnected[n - 1] = argv[i + 1];
3992 i++;
3993 }
3994 /* watch for the right order of these -nic* comparisons! */
3995 else if (strncmp(argv[i], "-nictracefile", 13) == 0)
3996 {
3997 unsigned n = parseNum(&argv[i][13], NetworkAdapterCount, "NIC");
3998 if (!n)
3999 return 1;
4000 if (argc <= i + 1)
4001 {
4002 return errorArgument("Missing argument to '%s'", argv[i]);
4003 }
4004 nictracefile[n - 1] = argv[i + 1];
4005 i++;
4006 }
4007 else if (strncmp(argv[i], "-nictrace", 9) == 0)
4008 {
4009 unsigned n = parseNum(&argv[i][9], NetworkAdapterCount, "NIC");
4010 if (!n)
4011 return 1;
4012 if (argc <= i + 1)
4013 return errorArgument("Missing argument to '%s'", argv[i]);
4014 nictrace[n - 1] = argv[i + 1];
4015 i++;
4016 }
4017 else if (strncmp(argv[i], "-nictype", 8) == 0)
4018 {
4019 unsigned n = parseNum(&argv[i][8], NetworkAdapterCount, "NIC");
4020 if (!n)
4021 return 1;
4022 if (argc <= i + 1)
4023 return errorArgument("Missing argument to '%s'", argv[i]);
4024 nictype[n - 1] = argv[i + 1];
4025 i++;
4026 }
4027 else if (strncmp(argv[i], "-nicspeed", 9) == 0)
4028 {
4029 unsigned n = parseNum(&argv[i][9], NetworkAdapterCount, "NIC");
4030 if (!n)
4031 return 1;
4032 if (argc <= i + 1)
4033 return errorArgument("Missing argument to '%s'", argv[i]);
4034 nicspeed[n - 1] = argv[i + 1];
4035 i++;
4036 }
4037 else if (strncmp(argv[i], "-nic", 4) == 0)
4038 {
4039 unsigned n = parseNum(&argv[i][4], NetworkAdapterCount, "NIC");
4040 if (!n)
4041 return 1;
4042 if (argc <= i + 1)
4043 return errorArgument("Missing argument to '%s'", argv[i]);
4044 nics[n - 1] = argv[i + 1];
4045 i++;
4046 }
4047 else if (strncmp(argv[i], "-hostifdev", 10) == 0)
4048 {
4049 unsigned n = parseNum(&argv[i][10], NetworkAdapterCount, "NIC");
4050 if (!n)
4051 return 1;
4052 if (argc <= i + 1)
4053 return errorArgument("Missing argument to '%s'", argv[i]);
4054 hostifdev[n - 1] = argv[i + 1];
4055 i++;
4056 }
4057 else if (strncmp(argv[i], "-intnet", 7) == 0)
4058 {
4059 unsigned n = parseNum(&argv[i][7], NetworkAdapterCount, "NIC");
4060 if (!n)
4061 return 1;
4062 if (argc <= i + 1)
4063 return errorArgument("Missing argument to '%s'", argv[i]);
4064 intnet[n - 1] = argv[i + 1];
4065 i++;
4066 }
4067 else if (strncmp(argv[i], "-natnet", 7) == 0)
4068 {
4069 unsigned n = parseNum(&argv[i][7], NetworkAdapterCount, "NIC");
4070 if (!n)
4071 return 1;
4072 if (argc <= i + 1)
4073 return errorArgument("Missing argument to '%s'", argv[i]);
4074
4075 if (!strcmp(argv[i + 1], "default"))
4076 natnet[n - 1] = "";
4077 else
4078 {
4079 RTIPV4ADDR Network;
4080 RTIPV4ADDR Netmask;
4081 int rc = RTCidrStrToIPv4(argv[i + 1], &Network, &Netmask);
4082 if (RT_FAILURE(rc))
4083 return errorArgument("Invalid IPv4 network '%s' specified -- CIDR notation expected.\n", argv[i + 1]);
4084 if (Netmask & 0x1f)
4085 return errorArgument("Prefix length of the NAT network must be less than 28.\n");
4086 natnet[n - 1] = argv[i + 1];
4087 }
4088 i++;
4089 }
4090#ifdef RT_OS_LINUX
4091 else if (strncmp(argv[i], "-tapsetup", 9) == 0)
4092 {
4093 unsigned n = parseNum(&argv[i][9], NetworkAdapterCount, "NIC");
4094 if (!n)
4095 return 1;
4096 if (argc <= i + 1)
4097 return errorArgument("Missing argument to '%s'", argv[i]);
4098 tapsetup[n - 1] = argv[i + 1];
4099 i++;
4100 }
4101 else if (strncmp(argv[i], "-tapterminate", 13) == 0)
4102 {
4103 unsigned n = parseNum(&argv[i][13], NetworkAdapterCount, "NIC");
4104 if (!n)
4105 return 1;
4106 if (argc <= i + 1)
4107 return errorArgument("Missing argument to '%s'", argv[i]);
4108 tapterm[n - 1] = argv[i + 1];
4109 i++;
4110 }
4111#endif /* RT_OS_LINUX */
4112 else if (strncmp(argv[i], "-macaddress", 11) == 0)
4113 {
4114 unsigned n = parseNum(&argv[i][11], NetworkAdapterCount, "NIC");
4115 if (!n)
4116 return 1;
4117 if (argc <= i + 1)
4118 return errorArgument("Missing argument to '%s'", argv[i]);
4119 macs[n - 1] = argv[i + 1];
4120 i++;
4121 }
4122#ifdef VBOX_VRDP
4123 else if (strcmp(argv[i], "-vrdp") == 0)
4124 {
4125 if (argc <= i + 1)
4126 return errorArgument("Missing argument to '%s'", argv[i]);
4127 i++;
4128 vrdp = argv[i];
4129 }
4130 else if (strcmp(argv[i], "-vrdpport") == 0)
4131 {
4132 if (argc <= i + 1)
4133 return errorArgument("Missing argument to '%s'", argv[i]);
4134 i++;
4135 if (strcmp(argv[i], "default") == 0)
4136 vrdpport = 0;
4137 else
4138 vrdpport = atoi(argv[i]);
4139 }
4140 else if (strcmp(argv[i], "-vrdpaddress") == 0)
4141 {
4142 if (argc <= i + 1)
4143 return errorArgument("Missing argument to '%s'", argv[i]);
4144 i++;
4145 vrdpaddress = argv[i];
4146 }
4147 else if (strcmp(argv[i], "-vrdpauthtype") == 0)
4148 {
4149 if (argc <= i + 1)
4150 return errorArgument("Missing argument to '%s'", argv[i]);
4151 i++;
4152 vrdpauthtype = argv[i];
4153 }
4154 else if (strcmp(argv[i], "-vrdpmulticon") == 0)
4155 {
4156 if (argc <= i + 1)
4157 return errorArgument("Missing argument to '%s'", argv[i]);
4158 i++;
4159 vrdpmulticon = argv[i];
4160 }
4161#endif /* VBOX_VRDP */
4162 else if (strcmp(argv[i], "-usb") == 0)
4163 {
4164 if (argc <= i + 1)
4165 return errorArgument("Missing argument to '%s'", argv[i]);
4166 i++;
4167 if (strcmp(argv[i], "on") == 0 || strcmp(argv[i], "enable") == 0)
4168 fUsbEnabled = 1;
4169 else if (strcmp(argv[i], "off") == 0 || strcmp(argv[i], "disable") == 0)
4170 fUsbEnabled = 0;
4171 else
4172 return errorArgument("Invalid -usb argument '%s'", argv[i]);
4173 }
4174 else if (strcmp(argv[i], "-usbehci") == 0)
4175 {
4176 if (argc <= i + 1)
4177 return errorArgument("Missing argument to '%s'", argv[i]);
4178 i++;
4179 if (strcmp(argv[i], "on") == 0 || strcmp(argv[i], "enable") == 0)
4180 fUsbEhciEnabled = 1;
4181 else if (strcmp(argv[i], "off") == 0 || strcmp(argv[i], "disable") == 0)
4182 fUsbEhciEnabled = 0;
4183 else
4184 return errorArgument("Invalid -usbehci argument '%s'", argv[i]);
4185 }
4186 else if (strcmp(argv[i], "-snapshotfolder") == 0)
4187 {
4188 if (argc <= i + 1)
4189 return errorArgument("Missing argument to '%s'", argv[i]);
4190 i++;
4191 snapshotFolder = argv[i];
4192 }
4193 else if (strncmp(argv[i], "-uartmode", 9) == 0)
4194 {
4195 unsigned n = parseNum(&argv[i][9], SerialPortCount, "UART");
4196 if (!n)
4197 return 1;
4198 i++;
4199 if (strcmp(argv[i], "disconnected") == 0)
4200 {
4201 uarts_mode[n - 1] = argv[i];
4202 }
4203 else
4204 {
4205 if (strcmp(argv[i], "server") == 0 || strcmp(argv[i], "client") == 0)
4206 {
4207 uarts_mode[n - 1] = argv[i];
4208 i++;
4209#ifdef RT_OS_WINDOWS
4210 if (strncmp(argv[i], "\\\\.\\pipe\\", 9))
4211 return errorArgument("Uart pipe must start with \\\\.\\pipe\\");
4212#endif
4213 }
4214 else
4215 {
4216 uarts_mode[n - 1] = (char*)"device";
4217 }
4218 if (argc <= i)
4219 return errorArgument("Missing argument to -uartmode");
4220 uarts_path[n - 1] = argv[i];
4221 }
4222 }
4223 else if (strncmp(argv[i], "-uart", 5) == 0)
4224 {
4225 unsigned n = parseNum(&argv[i][5], SerialPortCount, "UART");
4226 if (!n)
4227 return 1;
4228 if (argc <= i + 1)
4229 return errorArgument("Missing argument to '%s'", argv[i]);
4230 i++;
4231 if (strcmp(argv[i], "off") == 0 || strcmp(argv[i], "disable") == 0)
4232 {
4233 uarts_base[n - 1] = (ULONG)-1;
4234 }
4235 else
4236 {
4237 if (argc <= i + 1)
4238 return errorArgument("Missing argument to '%s'", argv[i-1]);
4239 uint32_t uVal;
4240 int vrc;
4241 vrc = RTStrToUInt32Ex(argv[i], NULL, 0, &uVal);
4242 if (vrc != VINF_SUCCESS || uVal == 0)
4243 return errorArgument("Error parsing UART I/O base '%s'", argv[i]);
4244 uarts_base[n - 1] = uVal;
4245 i++;
4246 vrc = RTStrToUInt32Ex(argv[i], NULL, 0, &uVal);
4247 if (vrc != VINF_SUCCESS)
4248 return errorArgument("Error parsing UART IRQ '%s'", argv[i]);
4249 uarts_irq[n - 1] = uVal;
4250 }
4251 }
4252#ifdef VBOX_WITH_MEM_BALLOONING
4253 else if (strncmp(argv[i], "-guestmemoryballoon", 19) == 0)
4254 {
4255 if (argc <= i + 1)
4256 return errorArgument("Missing argument to '%s'", argv[i]);
4257 i++;
4258 uint32_t uVal;
4259 int vrc;
4260 vrc = RTStrToUInt32Ex(argv[i], NULL, 0, &uVal);
4261 if (vrc != VINF_SUCCESS)
4262 return errorArgument("Error parsing guest memory balloon size '%s'", argv[i]);
4263 guestMemBalloonSize = uVal;
4264 }
4265#endif
4266 else if (strncmp(argv[i], "-gueststatisticsinterval", 24) == 0)
4267 {
4268 if (argc <= i + 1)
4269 return errorArgument("Missing argument to '%s'", argv[i]);
4270 i++;
4271 uint32_t uVal;
4272 int vrc;
4273 vrc = RTStrToUInt32Ex(argv[i], NULL, 0, &uVal);
4274 if (vrc != VINF_SUCCESS)
4275 return errorArgument("Error parsing guest statistics interval '%s'", argv[i]);
4276 guestStatInterval = uVal;
4277 }
4278 else if (strcmp(argv[i], "-sata") == 0)
4279 {
4280 if (argc <= i + 1)
4281 return errorArgument("Missing argument to '%s'", argv[i]);
4282 i++;
4283 if (strcmp(argv[i], "on") == 0 || strcmp(argv[i], "enable") == 0)
4284 fSataEnabled = 1;
4285 else if (strcmp(argv[i], "off") == 0 || strcmp(argv[i], "disable") == 0)
4286 fSataEnabled = 0;
4287 else
4288 return errorArgument("Invalid -usb argument '%s'", argv[i]);
4289 }
4290 else if (strcmp(argv[i], "-sataportcount") == 0)
4291 {
4292 unsigned n;
4293
4294 if (argc <= i + 1)
4295 return errorArgument("Missing arguments to '%s'", argv[i]);
4296 i++;
4297
4298 n = parseNum(argv[i], 30, "SATA");
4299 if (!n)
4300 return 1;
4301 sataPortCount = n;
4302 }
4303 else if (strncmp(argv[i], "-sataport", 9) == 0)
4304 {
4305 unsigned n = parseNum(&argv[i][9], 30, "SATA");
4306 if (!n)
4307 return 1;
4308 if (argc <= i + 1)
4309 return errorArgument("Missing argument to '%s'", argv[i]);
4310 i++;
4311 hdds[n-1+4] = argv[i];
4312 }
4313 else if (strncmp(argv[i], "-sataideemulation", 17) == 0)
4314 {
4315 unsigned bootDevicePos = 0;
4316 unsigned n;
4317
4318 bootDevicePos = parseNum(&argv[i][17], 4, "SATA");
4319 if (!bootDevicePos)
4320 return 1;
4321 bootDevicePos--;
4322
4323 if (argc <= i + 1)
4324 return errorArgument("Missing arguments to '%s'", argv[i]);
4325 i++;
4326
4327 n = parseNum(argv[i], 30, "SATA");
4328 if (!n)
4329 return 1;
4330
4331 sataBootDevices[bootDevicePos] = n-1;
4332 }
4333 else
4334 return errorSyntax(USAGE_MODIFYVM, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());
4335 }
4336
4337 /* try to find the given machine */
4338 ComPtr <IMachine> machine;
4339 Guid uuid (argv[0]);
4340 if (!uuid.isEmpty())
4341 {
4342 CHECK_ERROR (virtualBox, GetMachine (uuid, machine.asOutParam()));
4343 }
4344 else
4345 {
4346 CHECK_ERROR (virtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam()));
4347 if (SUCCEEDED (rc))
4348 machine->COMGETTER(Id)(uuid.asOutParam());
4349 }
4350 if (FAILED (rc))
4351 return 1;
4352
4353 /* open a session for the VM */
4354 CHECK_ERROR_RET (virtualBox, OpenSession(session, uuid), 1);
4355
4356 do
4357 {
4358 /* get the mutable session machine */
4359 session->COMGETTER(Machine)(machine.asOutParam());
4360
4361 ComPtr <IBIOSSettings> biosSettings;
4362 machine->COMGETTER(BIOSSettings)(biosSettings.asOutParam());
4363
4364 if (name)
4365 CHECK_ERROR(machine, COMSETTER(Name)(name));
4366 if (ostype)
4367 {
4368 ComPtr<IGuestOSType> guestOSType;
4369 CHECK_ERROR(virtualBox, GetGuestOSType(ostype, guestOSType.asOutParam()));
4370 if (SUCCEEDED(rc) && guestOSType)
4371 {
4372 CHECK_ERROR(machine, COMSETTER(OSTypeId)(ostype));
4373 }
4374 else
4375 {
4376 errorArgument("Invalid guest OS type '%s'", Utf8Str(ostype).raw());
4377 rc = E_FAIL;
4378 break;
4379 }
4380 }
4381 if (memorySize > 0)
4382 CHECK_ERROR(machine, COMSETTER(MemorySize)(memorySize));
4383 if (vramSize > 0)
4384 CHECK_ERROR(machine, COMSETTER(VRAMSize)(vramSize));
4385 if (acpi)
4386 {
4387 if (strcmp(acpi, "on") == 0)
4388 {
4389 CHECK_ERROR(biosSettings, COMSETTER(ACPIEnabled)(true));
4390 }
4391 else if (strcmp(acpi, "off") == 0)
4392 {
4393 CHECK_ERROR(biosSettings, COMSETTER(ACPIEnabled)(false));
4394 }
4395 else
4396 {
4397 errorArgument("Invalid -acpi argument '%s'", acpi);
4398 rc = E_FAIL;
4399 break;
4400 }
4401 }
4402 if (ioapic)
4403 {
4404 if (strcmp(ioapic, "on") == 0)
4405 {
4406 CHECK_ERROR(biosSettings, COMSETTER(IOAPICEnabled)(true));
4407 }
4408 else if (strcmp(ioapic, "off") == 0)
4409 {
4410 CHECK_ERROR(biosSettings, COMSETTER(IOAPICEnabled)(false));
4411 }
4412 else
4413 {
4414 errorArgument("Invalid -ioapic argument '%s'", ioapic);
4415 rc = E_FAIL;
4416 break;
4417 }
4418 }
4419 if (hwvirtex)
4420 {
4421 if (strcmp(hwvirtex, "on") == 0)
4422 {
4423 CHECK_ERROR(machine, COMSETTER(HWVirtExEnabled)(TSBool_True));
4424 }
4425 else if (strcmp(hwvirtex, "off") == 0)
4426 {
4427 CHECK_ERROR(machine, COMSETTER(HWVirtExEnabled)(TSBool_False));
4428 }
4429 else if (strcmp(hwvirtex, "default") == 0)
4430 {
4431 CHECK_ERROR(machine, COMSETTER(HWVirtExEnabled)(TSBool_Default));
4432 }
4433 else
4434 {
4435 errorArgument("Invalid -hwvirtex argument '%s'", hwvirtex);
4436 rc = E_FAIL;
4437 break;
4438 }
4439 }
4440 if (pae)
4441 {
4442 if (strcmp(pae, "on") == 0)
4443 {
4444 CHECK_ERROR(machine, COMSETTER(PAEEnabled)(true));
4445 }
4446 else if (strcmp(pae, "off") == 0)
4447 {
4448 CHECK_ERROR(machine, COMSETTER(PAEEnabled)(false));
4449 }
4450 else
4451 {
4452 errorArgument("Invalid -pae argument '%s'", ioapic);
4453 rc = E_FAIL;
4454 break;
4455 }
4456 }
4457 if (monitorcount != -1)
4458 {
4459 CHECK_ERROR(machine, COMSETTER(MonitorCount)(monitorcount));
4460 }
4461 if (bioslogofadein)
4462 {
4463 if (strcmp(bioslogofadein, "on") == 0)
4464 {
4465 CHECK_ERROR(biosSettings, COMSETTER(LogoFadeIn)(true));
4466 }
4467 else if (strcmp(bioslogofadein, "off") == 0)
4468 {
4469 CHECK_ERROR(biosSettings, COMSETTER(LogoFadeIn)(false));
4470 }
4471 else
4472 {
4473 errorArgument("Invalid -bioslogofadein argument '%s'", bioslogofadein);
4474 rc = E_FAIL;
4475 break;
4476 }
4477 }
4478 if (bioslogofadeout)
4479 {
4480 if (strcmp(bioslogofadeout, "on") == 0)
4481 {
4482 CHECK_ERROR(biosSettings, COMSETTER(LogoFadeOut)(true));
4483 }
4484 else if (strcmp(bioslogofadeout, "off") == 0)
4485 {
4486 CHECK_ERROR(biosSettings, COMSETTER(LogoFadeOut)(false));
4487 }
4488 else
4489 {
4490 errorArgument("Invalid -bioslogofadeout argument '%s'", bioslogofadeout);
4491 rc = E_FAIL;
4492 break;
4493 }
4494 }
4495 if (bioslogodisplaytime != ~0U)
4496 {
4497 CHECK_ERROR(biosSettings, COMSETTER(LogoDisplayTime)(bioslogodisplaytime));
4498 }
4499 if (bioslogoimagepath)
4500 {
4501 CHECK_ERROR(biosSettings, COMSETTER(LogoImagePath)(Bstr(bioslogoimagepath)));
4502 }
4503 if (biosbootmenumode)
4504 {
4505 if (strcmp(biosbootmenumode, "disabled") == 0)
4506 CHECK_ERROR(biosSettings, COMSETTER(BootMenuMode)(BIOSBootMenuMode_Disabled));
4507 else if (strcmp(biosbootmenumode, "menuonly") == 0)
4508 CHECK_ERROR(biosSettings, COMSETTER(BootMenuMode)(BIOSBootMenuMode_MenuOnly));
4509 else if (strcmp(biosbootmenumode, "messageandmenu") == 0)
4510 CHECK_ERROR(biosSettings, COMSETTER(BootMenuMode)(BIOSBootMenuMode_MessageAndMenu));
4511 else
4512 {
4513 errorArgument("Invalid -biosbootmenu argument '%s'", biosbootmenumode);
4514 rc = E_FAIL;
4515 break;
4516 }
4517
4518 }
4519 if (biossystemtimeoffset)
4520 {
4521 LONG64 timeOffset = RTStrToInt64(biossystemtimeoffset);
4522 CHECK_ERROR(biosSettings, COMSETTER(TimeOffset)(timeOffset));
4523 }
4524 if (biospxedebug)
4525 {
4526 if (strcmp(biospxedebug, "on") == 0)
4527 {
4528 CHECK_ERROR(biosSettings, COMSETTER(PXEDebugEnabled)(true));
4529 }
4530 else if (strcmp(biospxedebug, "off") == 0)
4531 {
4532 CHECK_ERROR(biosSettings, COMSETTER(PXEDebugEnabled)(false));
4533 }
4534 else
4535 {
4536 errorArgument("Invalid -biospxedebug argument '%s'", biospxedebug);
4537 rc = E_FAIL;
4538 break;
4539 }
4540 }
4541 for (int curBootDev = 0; curBootDev < 4; curBootDev++)
4542 {
4543 if (bootDeviceChanged[curBootDev])
4544 CHECK_ERROR(machine, SetBootOrder (curBootDev + 1, bootDevice[curBootDev]));
4545 }
4546 if (hdds[0])
4547 {
4548 if (strcmp(hdds[0], "none") == 0)
4549 {
4550 machine->DetachHardDisk(StorageBus_IDE, 0, 0);
4551 }
4552 else
4553 {
4554 /* first guess is that it's a UUID */
4555 Guid uuid(hdds[0]);
4556 ComPtr<IHardDisk> hardDisk;
4557 rc = virtualBox->GetHardDisk(uuid, hardDisk.asOutParam());
4558 /* not successful? Then it must be a filename */
4559 if (!hardDisk)
4560 {
4561 CHECK_ERROR(virtualBox, OpenHardDisk(Bstr(hdds[0]), hardDisk.asOutParam()));
4562 if (SUCCEEDED(rc) && hardDisk)
4563 {
4564 /* first check if it's already registered */
4565 Guid hddUUID;
4566 hardDisk->COMGETTER(Id)(hddUUID.asOutParam());
4567 ComPtr<IHardDisk> registeredHDD;
4568 rc = virtualBox->GetHardDisk(hddUUID, registeredHDD.asOutParam());
4569 if (SUCCEEDED(rc) && registeredHDD)
4570 hardDisk = registeredHDD;
4571 else
4572 {
4573 /* it has to be registered */
4574 CHECK_ERROR(virtualBox, RegisterHardDisk(hardDisk));
4575 if (FAILED(rc))
4576 break;
4577 }
4578 }
4579 }
4580 if (hardDisk)
4581 {
4582 hardDisk->COMGETTER(Id)(uuid.asOutParam());
4583 CHECK_ERROR(machine, AttachHardDisk(uuid, StorageBus_IDE, 0, 0));
4584 }
4585 else
4586 rc = E_FAIL;
4587 if (FAILED(rc))
4588 break;
4589 }
4590 }
4591 if (hdds[1])
4592 {
4593 if (strcmp(hdds[1], "none") == 0)
4594 {
4595 machine->DetachHardDisk(StorageBus_IDE, 0, 1);
4596 }
4597 else
4598 {
4599 /* first guess is that it's a UUID */
4600 Guid uuid(hdds[1]);
4601 ComPtr<IHardDisk> hardDisk;
4602 rc = virtualBox->GetHardDisk(uuid, hardDisk.asOutParam());
4603 /* not successful? Then it must be a filename */
4604 if (!hardDisk)
4605 {
4606 CHECK_ERROR(virtualBox, OpenHardDisk(Bstr(hdds[1]), hardDisk.asOutParam()));
4607 if (SUCCEEDED(rc) && hardDisk)
4608 {
4609 /* first check if it's already registered */
4610 Guid hddUUID;
4611 hardDisk->COMGETTER(Id)(hddUUID.asOutParam());
4612 ComPtr<IHardDisk> registeredHDD;
4613 rc = virtualBox->GetHardDisk(hddUUID, registeredHDD.asOutParam());
4614 if (SUCCEEDED(rc) && registeredHDD)
4615 hardDisk = registeredHDD;
4616 else
4617 {
4618 /* it has to be registered */
4619 CHECK_ERROR(virtualBox, RegisterHardDisk(hardDisk));
4620 if (FAILED(rc))
4621 break;
4622 }
4623 }
4624 }
4625 if (hardDisk)
4626 {
4627 hardDisk->COMGETTER(Id)(uuid.asOutParam());
4628 CHECK_ERROR(machine, AttachHardDisk(uuid, StorageBus_IDE, 0, 1));
4629 }
4630 else
4631 rc = E_FAIL;
4632 if (FAILED(rc))
4633 break;
4634 }
4635 }
4636 if (hdds[2])
4637 {
4638 if (strcmp(hdds[2], "none") == 0)
4639 {
4640 machine->DetachHardDisk(StorageBus_IDE, 1, 1);
4641 }
4642 else
4643 {
4644 /* first guess is that it's a UUID */
4645 Guid uuid(hdds[2]);
4646 ComPtr<IHardDisk> hardDisk;
4647 rc = virtualBox->GetHardDisk(uuid, hardDisk.asOutParam());
4648 /* not successful? Then it must be a filename */
4649 if (!hardDisk)
4650 {
4651 CHECK_ERROR(virtualBox, OpenHardDisk(Bstr(hdds[2]), hardDisk.asOutParam()));
4652 if (SUCCEEDED(rc) && hardDisk)
4653 {
4654 /* first check if it's already registered */
4655 Guid hddUUID;
4656 hardDisk->COMGETTER(Id)(hddUUID.asOutParam());
4657 ComPtr<IHardDisk> registeredHDD;
4658 rc = virtualBox->GetHardDisk(hddUUID, registeredHDD.asOutParam());
4659 if (SUCCEEDED(rc) && registeredHDD)
4660 hardDisk = registeredHDD;
4661 else
4662 {
4663 /* it has to be registered */
4664 CHECK_ERROR(virtualBox, RegisterHardDisk(hardDisk));
4665 if (FAILED(rc))
4666 break;
4667 }
4668 }
4669 }
4670 if (hardDisk)
4671 {
4672 hardDisk->COMGETTER(Id)(uuid.asOutParam());
4673 CHECK_ERROR(machine, AttachHardDisk(uuid, StorageBus_IDE, 1, 1));
4674 }
4675 else
4676 rc = E_FAIL;
4677 if (FAILED(rc))
4678 break;
4679 }
4680 }
4681 if (dvd)
4682 {
4683 ComPtr<IDVDDrive> dvdDrive;
4684 machine->COMGETTER(DVDDrive)(dvdDrive.asOutParam());
4685 ASSERT(dvdDrive);
4686
4687 /* unmount? */
4688 if (strcmp(dvd, "none") == 0)
4689 {
4690 CHECK_ERROR(dvdDrive, Unmount());
4691 }
4692 /* host drive? */
4693 else if (strncmp(dvd, "host:", 5) == 0)
4694 {
4695 ComPtr<IHost> host;
4696 CHECK_ERROR(virtualBox, COMGETTER(Host)(host.asOutParam()));
4697 ComPtr<IHostDVDDriveCollection> hostDVDs;
4698 CHECK_ERROR(host, COMGETTER(DVDDrives)(hostDVDs.asOutParam()));
4699 ComPtr<IHostDVDDrive> hostDVDDrive;
4700 rc = hostDVDs->FindByName(Bstr(dvd + 5), hostDVDDrive.asOutParam());
4701 if (!hostDVDDrive)
4702 {
4703 /* 2nd try: try with the real name, important on Linux+libhal */
4704 char szPathReal[RTPATH_MAX];
4705 if (VBOX_FAILURE(RTPathReal(dvd + 5, szPathReal, sizeof(szPathReal))))
4706 {
4707 errorArgument("Invalid host DVD drive name");
4708 rc = E_FAIL;
4709 break;
4710 }
4711 rc = hostDVDs->FindByName(Bstr(szPathReal), hostDVDDrive.asOutParam());
4712 if (!hostDVDDrive)
4713 {
4714 errorArgument("Invalid host DVD drive name");
4715 rc = E_FAIL;
4716 break;
4717 }
4718 }
4719 CHECK_ERROR(dvdDrive, CaptureHostDrive(hostDVDDrive));
4720 }
4721 else
4722 {
4723 /* first assume it's a UUID */
4724 Guid uuid(dvd);
4725 ComPtr<IDVDImage> dvdImage;
4726 rc = virtualBox->GetDVDImage(uuid, dvdImage.asOutParam());
4727 if (FAILED(rc) || !dvdImage)
4728 {
4729 /* must be a filename, check if it's in the collection */
4730 ComPtr<IDVDImageCollection> dvdImages;
4731 virtualBox->COMGETTER(DVDImages)(dvdImages.asOutParam());
4732 rc = dvdImages->FindByPath(Bstr(dvd), dvdImage.asOutParam());
4733 /* not registered, do that on the fly */
4734 if (!dvdImage)
4735 {
4736 Guid emptyUUID;
4737 CHECK_ERROR(virtualBox, OpenDVDImage(Bstr(dvd), emptyUUID, dvdImage.asOutParam()));
4738 if (SUCCEEDED(rc) && dvdImage)
4739 {
4740 /* time to register the image */
4741 CHECK_ERROR(virtualBox, RegisterDVDImage(dvdImage));
4742 }
4743 }
4744 }
4745 if (!dvdImage)
4746 {
4747 rc = E_FAIL;
4748 break;
4749 }
4750
4751 dvdImage->COMGETTER(Id)(uuid.asOutParam());
4752 CHECK_ERROR(dvdDrive, MountImage(uuid));
4753 }
4754 }
4755 if (dvdpassthrough)
4756 {
4757 ComPtr<IDVDDrive> dvdDrive;
4758 machine->COMGETTER(DVDDrive)(dvdDrive.asOutParam());
4759 ASSERT(dvdDrive);
4760
4761 CHECK_ERROR(dvdDrive, COMSETTER(Passthrough)(strcmp(dvdpassthrough, "on") == 0));
4762 }
4763 if (floppy)
4764 {
4765 ComPtr<IFloppyDrive> floppyDrive;
4766 machine->COMGETTER(FloppyDrive)(floppyDrive.asOutParam());
4767 ASSERT(floppyDrive);
4768
4769 /* disable? */
4770 if (strcmp(floppy, "disabled") == 0)
4771 {
4772 /* disable the controller */
4773 CHECK_ERROR(floppyDrive, COMSETTER(Enabled)(false));
4774 }
4775 else
4776 {
4777 /* enable the controller */
4778 CHECK_ERROR(floppyDrive, COMSETTER(Enabled)(true));
4779
4780 /* unmount? */
4781 if (strcmp(floppy, "empty") == 0)
4782 {
4783 CHECK_ERROR(floppyDrive, Unmount());
4784 }
4785 /* host drive? */
4786 else if (strncmp(floppy, "host:", 5) == 0)
4787 {
4788 ComPtr<IHost> host;
4789 CHECK_ERROR(virtualBox, COMGETTER(Host)(host.asOutParam()));
4790 ComPtr<IHostFloppyDriveCollection> hostFloppies;
4791 CHECK_ERROR(host, COMGETTER(FloppyDrives)(hostFloppies.asOutParam()));
4792 ComPtr<IHostFloppyDrive> hostFloppyDrive;
4793 rc = hostFloppies->FindByName(Bstr(floppy + 5), hostFloppyDrive.asOutParam());
4794 if (!hostFloppyDrive)
4795 {
4796 errorArgument("Invalid host floppy drive name");
4797 rc = E_FAIL;
4798 break;
4799 }
4800 CHECK_ERROR(floppyDrive, CaptureHostDrive(hostFloppyDrive));
4801 }
4802 else
4803 {
4804 /* first assume it's a UUID */
4805 Guid uuid(floppy);
4806 ComPtr<IFloppyImage> floppyImage;
4807 rc = virtualBox->GetFloppyImage(uuid, floppyImage.asOutParam());
4808 if (FAILED(rc) || !floppyImage)
4809 {
4810 /* must be a filename */
4811 Guid emptyUUID;
4812 CHECK_ERROR(virtualBox, OpenFloppyImage(Bstr(floppy), emptyUUID, floppyImage.asOutParam()));
4813 if (SUCCEEDED(rc) && floppyImage)
4814 {
4815 /** @todo first iterate through the collection and try to find the image */
4816 /* time to register the image */
4817 CHECK_ERROR(virtualBox, RegisterFloppyImage(floppyImage));
4818 }
4819 }
4820 if (!floppyImage)
4821 {
4822 rc = E_FAIL;
4823 break;
4824 }
4825
4826 floppyImage->COMGETTER(Id)(uuid.asOutParam());
4827 CHECK_ERROR(floppyDrive, MountImage(uuid));
4828 }
4829 }
4830 }
4831 if (audio || audiocontroller)
4832 {
4833 ComPtr<IAudioAdapter> audioAdapter;
4834 machine->COMGETTER(AudioAdapter)(audioAdapter.asOutParam());
4835 ASSERT(audioAdapter);
4836
4837 if (audio)
4838 {
4839 /* disable? */
4840 if (strcmp(audio, "none") == 0)
4841 {
4842 CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(false));
4843 }
4844 else if (strcmp(audio, "null") == 0)
4845 {
4846 CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_Null));
4847 CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(true));
4848 }
4849#ifdef RT_OS_WINDOWS
4850#ifdef VBOX_WITH_WINMM
4851 else if (strcmp(audio, "winmm") == 0)
4852 {
4853 CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_WinMM));
4854 CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(true));
4855 }
4856#endif
4857 else if (strcmp(audio, "dsound") == 0)
4858 {
4859 CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_DirectSound));
4860 CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(true));
4861 }
4862#endif /* RT_OS_WINDOWS */
4863#ifdef RT_OS_LINUX
4864 else if (strcmp(audio, "oss") == 0)
4865 {
4866 CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_OSS));
4867 CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(true));
4868 }
4869# ifdef VBOX_WITH_ALSA
4870 else if (strcmp(audio, "alsa") == 0)
4871 {
4872 CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_ALSA));
4873 CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(true));
4874 }
4875# endif
4876# ifdef VBOX_WITH_PULSE
4877 else if (strcmp(audio, "pulse") == 0)
4878 {
4879 CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_Pulse));
4880 CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(true));
4881 }
4882# endif
4883#endif /* !RT_OS_LINUX */
4884#ifdef RT_OS_SOLARIS
4885 else if (strcmp(audio, "solaudio") == 0)
4886 {
4887 CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_SolAudio));
4888 CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(true));
4889 }
4890
4891#endif /* !RT_OS_SOLARIS */
4892#ifdef RT_OS_DARWIN
4893 else if (strcmp(audio, "coreaudio") == 0)
4894 {
4895 CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_CoreAudio));
4896 CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(true));
4897 }
4898
4899#endif /* !RT_OS_DARWIN */
4900 else
4901 {
4902 errorArgument("Invalid -audio argument '%s'", audio);
4903 rc = E_FAIL;
4904 break;
4905 }
4906 }
4907 if (audiocontroller)
4908 {
4909 if (strcmp(audiocontroller, "sb16") == 0)
4910 CHECK_ERROR(audioAdapter, COMSETTER(AudioController)(AudioControllerType_SB16));
4911 else if (strcmp(audiocontroller, "ac97") == 0)
4912 CHECK_ERROR(audioAdapter, COMSETTER(AudioController)(AudioControllerType_AC97));
4913 else
4914 {
4915 errorArgument("Invalid -audiocontroller argument '%s'", audiocontroller);
4916 rc = E_FAIL;
4917 break;
4918 }
4919 }
4920 }
4921 /* Shared clipboard state */
4922 if (clipboard)
4923 {
4924/* ComPtr<IClipboardMode> clipboardMode;
4925 machine->COMGETTER(ClipboardMode)(clipboardMode.asOutParam());
4926 ASSERT(clipboardMode);
4927*/
4928 if (strcmp(clipboard, "disabled") == 0)
4929 {
4930 CHECK_ERROR(machine, COMSETTER(ClipboardMode)(ClipboardMode_Disabled));
4931 }
4932 else if (strcmp(clipboard, "hosttoguest") == 0)
4933 {
4934 CHECK_ERROR(machine, COMSETTER(ClipboardMode)(ClipboardMode_HostToGuest));
4935 }
4936 else if (strcmp(clipboard, "guesttohost") == 0)
4937 {
4938 CHECK_ERROR(machine, COMSETTER(ClipboardMode)(ClipboardMode_GuestToHost));
4939 }
4940 else if (strcmp(clipboard, "bidirectional") == 0)
4941 {
4942 CHECK_ERROR(machine, COMSETTER(ClipboardMode)(ClipboardMode_Bidirectional));
4943 }
4944 else
4945 {
4946 errorArgument("Invalid -clipboard argument '%s'", clipboard);
4947 rc = E_FAIL;
4948 break;
4949 }
4950 }
4951 /* iterate through all possible NICs */
4952 for (ULONG n = 0; n < NetworkAdapterCount; n ++)
4953 {
4954 ComPtr<INetworkAdapter> nic;
4955 CHECK_ERROR_RET (machine, GetNetworkAdapter (n, nic.asOutParam()), 1);
4956
4957 ASSERT(nic);
4958
4959 /* something about the NIC? */
4960 if (nics[n])
4961 {
4962 if (strcmp(nics[n], "none") == 0)
4963 {
4964 CHECK_ERROR_RET(nic, COMSETTER(Enabled) (FALSE), 1);
4965 }
4966 else if (strcmp(nics[n], "null") == 0)
4967 {
4968 CHECK_ERROR_RET(nic, COMSETTER(Enabled) (TRUE), 1);
4969 CHECK_ERROR_RET(nic, Detach(), 1);
4970 }
4971 else if (strcmp(nics[n], "nat") == 0)
4972 {
4973 CHECK_ERROR_RET(nic, COMSETTER(Enabled) (TRUE), 1);
4974 CHECK_ERROR_RET(nic, AttachToNAT(), 1);
4975 }
4976 else if (strcmp(nics[n], "hostif") == 0)
4977 {
4978 CHECK_ERROR_RET(nic, COMSETTER(Enabled) (TRUE), 1);
4979 CHECK_ERROR_RET(nic, AttachToHostInterface(), 1);
4980 }
4981 else if (strcmp(nics[n], "intnet") == 0)
4982 {
4983 CHECK_ERROR_RET(nic, COMSETTER(Enabled) (TRUE), 1);
4984 CHECK_ERROR_RET(nic, AttachToInternalNetwork(), 1);
4985 }
4986 else
4987 {
4988 errorArgument("Invalid type '%s' specfied for NIC %lu", nics[n], n + 1);
4989 rc = E_FAIL;
4990 break;
4991 }
4992 }
4993
4994 /* something about the NIC type? */
4995 if (nictype[n])
4996 {
4997 if (strcmp(nictype[n], "Am79C970A") == 0)
4998 {
4999 CHECK_ERROR_RET(nic, COMSETTER(AdapterType)(NetworkAdapterType_Am79C970A), 1);
5000 }
5001 else if (strcmp(nictype[n], "Am79C973") == 0)
5002 {
5003 CHECK_ERROR_RET(nic, COMSETTER(AdapterType)(NetworkAdapterType_Am79C973), 1);
5004 }
5005#ifdef VBOX_WITH_E1000
5006 else if (strcmp(nictype[n], "82540EM") == 0)
5007 {
5008 CHECK_ERROR_RET(nic, COMSETTER(AdapterType)(NetworkAdapterType_I82540EM), 1);
5009 }
5010 else if (strcmp(nictype[n], "82543GC") == 0)
5011 {
5012 CHECK_ERROR_RET(nic, COMSETTER(AdapterType)(NetworkAdapterType_I82543GC), 1);
5013 }
5014#endif
5015 else
5016 {
5017 errorArgument("Invalid NIC type '%s' specified for NIC %lu", nictype[n], n + 1);
5018 rc = E_FAIL;
5019 break;
5020 }
5021 }
5022
5023 /* something about the MAC address? */
5024 if (macs[n])
5025 {
5026 /* generate one? */
5027 if (strcmp(macs[n], "auto") == 0)
5028 {
5029 CHECK_ERROR_RET(nic, COMSETTER(MACAddress)(NULL), 1);
5030 }
5031 else
5032 {
5033 CHECK_ERROR_RET(nic, COMSETTER(MACAddress)(Bstr(macs[n])), 1);
5034 }
5035 }
5036
5037 /* something about the reported link speed? */
5038 if (nicspeed[n])
5039 {
5040 uint32_t u32LineSpeed;
5041
5042 u32LineSpeed = atoi(nicspeed[n]);
5043
5044 if (u32LineSpeed < 1000 || u32LineSpeed > 4000000)
5045 {
5046 errorArgument("Invalid -nicspeed%lu argument '%s'", n + 1, nicspeed[n]);
5047 rc = E_FAIL;
5048 break;
5049 }
5050 CHECK_ERROR_RET(nic, COMSETTER(LineSpeed)(u32LineSpeed), 1);
5051 }
5052
5053 /* the link status flag? */
5054 if (cableconnected[n])
5055 {
5056 if (strcmp(cableconnected[n], "on") == 0)
5057 {
5058 CHECK_ERROR_RET(nic, COMSETTER(CableConnected)(TRUE), 1);
5059 }
5060 else if (strcmp(cableconnected[n], "off") == 0)
5061 {
5062 CHECK_ERROR_RET(nic, COMSETTER(CableConnected)(FALSE), 1);
5063 }
5064 else
5065 {
5066 errorArgument("Invalid -cableconnected%lu argument '%s'", n + 1, cableconnected[n]);
5067 rc = E_FAIL;
5068 break;
5069 }
5070 }
5071
5072 /* the trace flag? */
5073 if (nictrace[n])
5074 {
5075 if (strcmp(nictrace[n], "on") == 0)
5076 {
5077 CHECK_ERROR_RET(nic, COMSETTER(TraceEnabled)(TRUE), 1);
5078 }
5079 else if (strcmp(nictrace[n], "off") == 0)
5080 {
5081 CHECK_ERROR_RET(nic, COMSETTER(TraceEnabled)(FALSE), 1);
5082 }
5083 else
5084 {
5085 errorArgument("Invalid -nictrace%lu argument '%s'", n + 1, nictrace[n]);
5086 rc = E_FAIL;
5087 break;
5088 }
5089 }
5090
5091 /* the tracefile flag? */
5092 if (nictracefile[n])
5093 {
5094 CHECK_ERROR_RET(nic, COMSETTER(TraceFile)(Bstr(nictracefile[n])), 1);
5095 }
5096
5097 /* the host interface device? */
5098 if (hostifdev[n])
5099 {
5100 /* remove it? */
5101 if (strcmp(hostifdev[n], "none") == 0)
5102 {
5103 CHECK_ERROR_RET(nic, COMSETTER(HostInterface)(NULL), 1);
5104 }
5105 else
5106 {
5107 CHECK_ERROR_RET(nic, COMSETTER(HostInterface)(Bstr(hostifdev[n])), 1);
5108 }
5109 }
5110
5111 /* the internal network name? */
5112 if (intnet[n])
5113 {
5114 /* remove it? */
5115 if (strcmp(intnet[n], "none") == 0)
5116 {
5117 CHECK_ERROR_RET(nic, COMSETTER(InternalNetwork)(NULL), 1);
5118 }
5119 else
5120 {
5121 CHECK_ERROR_RET(nic, COMSETTER(InternalNetwork)(Bstr(intnet[n])), 1);
5122 }
5123 }
5124 /* the network of the NAT */
5125 if (natnet[n])
5126 {
5127 CHECK_ERROR_RET(nic, COMSETTER(NATNetwork)(Bstr(natnet[n])), 1);
5128 }
5129#ifdef RT_OS_LINUX
5130 /* the TAP setup application? */
5131 if (tapsetup[n])
5132 {
5133 /* remove it? */
5134 if (strcmp(tapsetup[n], "none") == 0)
5135 {
5136 CHECK_ERROR_RET(nic, COMSETTER(TAPSetupApplication)(NULL), 1);
5137 }
5138 else
5139 {
5140 CHECK_ERROR_RET(nic, COMSETTER(TAPSetupApplication)(Bstr(tapsetup[n])), 1);
5141 }
5142 }
5143
5144 /* the TAP terminate application? */
5145 if (tapterm[n])
5146 {
5147 /* remove it? */
5148 if (strcmp(tapterm[n], "none") == 0)
5149 {
5150 CHECK_ERROR_RET(nic, COMSETTER(TAPTerminateApplication)(NULL), 1);
5151 }
5152 else
5153 {
5154 CHECK_ERROR_RET(nic, COMSETTER(TAPTerminateApplication)(Bstr(tapterm[n])), 1);
5155 }
5156 }
5157#endif /* RT_OS_LINUX */
5158
5159 }
5160 if (FAILED(rc))
5161 break;
5162
5163 /* iterate through all possible serial ports */
5164 for (ULONG n = 0; n < SerialPortCount; n ++)
5165 {
5166 ComPtr<ISerialPort> uart;
5167 CHECK_ERROR_RET (machine, GetSerialPort (n, uart.asOutParam()), 1);
5168
5169 ASSERT(uart);
5170
5171 if (uarts_base[n])
5172 {
5173 if (uarts_base[n] == (ULONG)-1)
5174 {
5175 CHECK_ERROR_RET(uart, COMSETTER(Enabled) (FALSE), 1);
5176 }
5177 else
5178 {
5179 CHECK_ERROR_RET(uart, COMSETTER(IOBase) (uarts_base[n]), 1);
5180 CHECK_ERROR_RET(uart, COMSETTER(IRQ) (uarts_irq[n]), 1);
5181 CHECK_ERROR_RET(uart, COMSETTER(Enabled) (TRUE), 1);
5182 }
5183 }
5184 if (uarts_mode[n])
5185 {
5186 if (strcmp(uarts_mode[n], "disconnected") == 0)
5187 {
5188 CHECK_ERROR_RET(uart, COMSETTER(HostMode) (PortMode_Disconnected), 1);
5189 }
5190 else
5191 {
5192 if (strcmp(uarts_mode[n], "server") == 0)
5193 {
5194 CHECK_ERROR_RET(uart, COMSETTER(HostMode) (PortMode_HostPipe), 1);
5195 CHECK_ERROR_RET(uart, COMSETTER(Server) (TRUE), 1);
5196 }
5197 else if (strcmp(uarts_mode[n], "client") == 0)
5198 {
5199 CHECK_ERROR_RET(uart, COMSETTER(HostMode) (PortMode_HostPipe), 1);
5200 CHECK_ERROR_RET(uart, COMSETTER(Server) (FALSE), 1);
5201 }
5202 else
5203 {
5204 CHECK_ERROR_RET(uart, COMSETTER(HostMode) (PortMode_HostDevice), 1);
5205 }
5206 CHECK_ERROR_RET(uart, COMSETTER(Path) (Bstr(uarts_path[n])), 1);
5207 }
5208 }
5209 }
5210 if (FAILED(rc))
5211 break;
5212
5213#ifdef VBOX_VRDP
5214 if (vrdp || (vrdpport != UINT16_MAX) || vrdpaddress || vrdpauthtype || vrdpmulticon)
5215 {
5216 ComPtr<IVRDPServer> vrdpServer;
5217 machine->COMGETTER(VRDPServer)(vrdpServer.asOutParam());
5218 ASSERT(vrdpServer);
5219 if (vrdpServer)
5220 {
5221 if (vrdp)
5222 {
5223 if (strcmp(vrdp, "on") == 0)
5224 {
5225 CHECK_ERROR(vrdpServer, COMSETTER(Enabled)(true));
5226 }
5227 else if (strcmp(vrdp, "off") == 0)
5228 {
5229 CHECK_ERROR(vrdpServer, COMSETTER(Enabled)(false));
5230 }
5231 else
5232 {
5233 errorArgument("Invalid -vrdp argument '%s'", vrdp);
5234 rc = E_FAIL;
5235 break;
5236 }
5237 }
5238 if (vrdpport != UINT16_MAX)
5239 {
5240 CHECK_ERROR(vrdpServer, COMSETTER(Port)(vrdpport));
5241 }
5242 if (vrdpaddress)
5243 {
5244 CHECK_ERROR(vrdpServer, COMSETTER(NetAddress)(Bstr(vrdpaddress)));
5245 }
5246 if (vrdpauthtype)
5247 {
5248 if (strcmp(vrdpauthtype, "null") == 0)
5249 {
5250 CHECK_ERROR(vrdpServer, COMSETTER(AuthType)(VRDPAuthType_Null));
5251 }
5252 else if (strcmp(vrdpauthtype, "external") == 0)
5253 {
5254 CHECK_ERROR(vrdpServer, COMSETTER(AuthType)(VRDPAuthType_External));
5255 }
5256 else if (strcmp(vrdpauthtype, "guest") == 0)
5257 {
5258 CHECK_ERROR(vrdpServer, COMSETTER(AuthType)(VRDPAuthType_Guest));
5259 }
5260 else
5261 {
5262 errorArgument("Invalid -vrdpauthtype argument '%s'", vrdpauthtype);
5263 rc = E_FAIL;
5264 break;
5265 }
5266 }
5267 if (vrdpmulticon)
5268 {
5269 if (strcmp(vrdpmulticon, "on") == 0)
5270 {
5271 CHECK_ERROR(vrdpServer, COMSETTER(AllowMultiConnection)(true));
5272 }
5273 else if (strcmp(vrdpmulticon, "off") == 0)
5274 {
5275 CHECK_ERROR(vrdpServer, COMSETTER(AllowMultiConnection)(false));
5276 }
5277 else
5278 {
5279 errorArgument("Invalid -vrdpmulticon argument '%s'", vrdpmulticon);
5280 rc = E_FAIL;
5281 break;
5282 }
5283 }
5284 }
5285 }
5286#endif /* VBOX_VRDP */
5287
5288 /*
5289 * USB enable/disable
5290 */
5291 if (fUsbEnabled != -1)
5292 {
5293 ComPtr<IUSBController> UsbCtl;
5294 CHECK_ERROR(machine, COMGETTER(USBController)(UsbCtl.asOutParam()));
5295 if (SUCCEEDED(rc))
5296 {
5297 CHECK_ERROR(UsbCtl, COMSETTER(Enabled)(!!fUsbEnabled));
5298 }
5299 }
5300 /*
5301 * USB EHCI enable/disable
5302 */
5303 if (fUsbEhciEnabled != -1)
5304 {
5305 ComPtr<IUSBController> UsbCtl;
5306 CHECK_ERROR(machine, COMGETTER(USBController)(UsbCtl.asOutParam()));
5307 if (SUCCEEDED(rc))
5308 {
5309 CHECK_ERROR(UsbCtl, COMSETTER(EnabledEhci)(!!fUsbEhciEnabled));
5310 }
5311 }
5312
5313 if (snapshotFolder)
5314 {
5315 if (strcmp(snapshotFolder, "default") == 0)
5316 {
5317 CHECK_ERROR(machine, COMSETTER(SnapshotFolder)(NULL));
5318 }
5319 else
5320 {
5321 CHECK_ERROR(machine, COMSETTER(SnapshotFolder)(Bstr(snapshotFolder)));
5322 }
5323 }
5324
5325 if (guestMemBalloonSize != (ULONG)-1)
5326 CHECK_ERROR(machine, COMSETTER(MemoryBalloonSize)(guestMemBalloonSize));
5327
5328 if (guestStatInterval != (ULONG)-1)
5329 CHECK_ERROR(machine, COMSETTER(StatisticsUpdateInterval)(guestStatInterval));
5330
5331 /*
5332 * SATA controller enable/disable
5333 */
5334 if (fSataEnabled != -1)
5335 {
5336 ComPtr<ISATAController> SataCtl;
5337 CHECK_ERROR(machine, COMGETTER(SATAController)(SataCtl.asOutParam()));
5338 if (SUCCEEDED(rc))
5339 {
5340 CHECK_ERROR(SataCtl, COMSETTER(Enabled)(!!fSataEnabled));
5341 }
5342 }
5343
5344 for (uint32_t i = 4; i < 34; i++)
5345 {
5346 if (hdds[i])
5347 {
5348 if (strcmp(hdds[i], "none") == 0)
5349 {
5350 machine->DetachHardDisk(StorageBus_SATA, i-4, 0);
5351 }
5352 else
5353 {
5354 /* first guess is that it's a UUID */
5355 Guid uuid(hdds[i]);
5356 ComPtr<IHardDisk> hardDisk;
5357 rc = virtualBox->GetHardDisk(uuid, hardDisk.asOutParam());
5358 /* not successful? Then it must be a filename */
5359 if (!hardDisk)
5360 {
5361 CHECK_ERROR(virtualBox, OpenHardDisk(Bstr(hdds[i]), hardDisk.asOutParam()));
5362 if (SUCCEEDED(rc) && hardDisk)
5363 {
5364 /* first check if it's already registered */
5365 Guid hddUUID;
5366 hardDisk->COMGETTER(Id)(hddUUID.asOutParam());
5367 ComPtr<IHardDisk> registeredHDD;
5368 rc = virtualBox->GetHardDisk(hddUUID, registeredHDD.asOutParam());
5369 if (SUCCEEDED(rc) && registeredHDD)
5370 hardDisk = registeredHDD;
5371 else
5372 {
5373 /* it has to be registered */
5374 CHECK_ERROR(virtualBox, RegisterHardDisk(hardDisk));
5375 if (FAILED(rc))
5376 break;
5377 }
5378 }
5379 }
5380 if (hardDisk)
5381 {
5382 hardDisk->COMGETTER(Id)(uuid.asOutParam());
5383 CHECK_ERROR(machine, AttachHardDisk(uuid, StorageBus_SATA, i-4, 0));
5384 }
5385 else
5386 rc = E_FAIL;
5387 if (FAILED(rc))
5388 break;
5389 }
5390 }
5391 }
5392
5393 for (uint32_t i = 0; i < 4; i++)
5394 {
5395 if (sataBootDevices[i] != -1)
5396 {
5397 ComPtr<ISATAController> SataCtl;
5398 CHECK_ERROR(machine, COMGETTER(SATAController)(SataCtl.asOutParam()));
5399 if (SUCCEEDED(rc))
5400 {
5401 CHECK_ERROR(SataCtl, SetIDEEmulationPort(i, sataBootDevices[i]));
5402 }
5403 }
5404 }
5405
5406 if (sataPortCount != -1)
5407 {
5408 ComPtr<ISATAController> SataCtl;
5409 CHECK_ERROR(machine, COMGETTER(SATAController)(SataCtl.asOutParam()));
5410 if (SUCCEEDED(rc))
5411 {
5412 CHECK_ERROR(SataCtl, COMSETTER(PortCount)(sataPortCount));
5413 }
5414 }
5415
5416 /* commit changes */
5417 CHECK_ERROR(machine, SaveSettings());
5418 }
5419 while (0);
5420
5421 /* it's important to always close sessions */
5422 session->Close();
5423
5424 return SUCCEEDED(rc) ? 0 : 1;
5425}
5426
5427static int handleStartVM(int argc, char *argv[],
5428 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
5429{
5430 HRESULT rc;
5431
5432 if (argc < 1)
5433 return errorSyntax(USAGE_STARTVM, "Not enough parameters");
5434
5435 ComPtr<IMachine> machine;
5436 /* assume it's a UUID */
5437 rc = virtualBox->GetMachine(Guid(argv[0]), machine.asOutParam());
5438 if (FAILED(rc) || !machine)
5439 {
5440 /* must be a name */
5441 CHECK_ERROR(virtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam()));
5442 }
5443 if (machine)
5444 {
5445 Guid uuid;
5446 machine->COMGETTER(Id)(uuid.asOutParam());
5447
5448 /* default to GUI session type */
5449 Bstr sessionType = "gui";
5450 /* has a session type been specified? */
5451 if ((argc > 2) && (strcmp(argv[1], "-type") == 0))
5452 {
5453 if (strcmp(argv[2], "gui") == 0)
5454 {
5455 sessionType = "gui";
5456 }
5457 else if (strcmp(argv[2], "vrdp") == 0)
5458 {
5459 sessionType = "vrdp";
5460 }
5461 else if (strcmp(argv[2], "capture") == 0)
5462 {
5463 sessionType = "capture";
5464 }
5465 else
5466 return errorArgument("Invalid session type argument '%s'", argv[2]);
5467 }
5468
5469 Bstr env;
5470#ifdef RT_OS_LINUX
5471 /* make sure the VM process will start on the same display as VBoxManage */
5472 {
5473 const char *display = RTEnvGet ("DISPLAY");
5474 if (display)
5475 env = Utf8StrFmt ("DISPLAY=%s", display);
5476 }
5477#endif
5478 ComPtr<IProgress> progress;
5479 CHECK_ERROR_RET(virtualBox, OpenRemoteSession(session, uuid, sessionType,
5480 env, progress.asOutParam()), rc);
5481 RTPrintf("Waiting for the remote session to open...\n");
5482 CHECK_ERROR_RET(progress, WaitForCompletion (-1), 1);
5483
5484 BOOL completed;
5485 CHECK_ERROR_RET(progress, COMGETTER(Completed)(&completed), rc);
5486 ASSERT(completed);
5487
5488 HRESULT resultCode;
5489 CHECK_ERROR_RET(progress, COMGETTER(ResultCode)(&resultCode), rc);
5490 if (FAILED(resultCode))
5491 {
5492 ComPtr <IVirtualBoxErrorInfo> errorInfo;
5493 CHECK_ERROR_RET(progress, COMGETTER(ErrorInfo)(errorInfo.asOutParam()), 1);
5494 ErrorInfo info (errorInfo);
5495 PRINT_ERROR_INFO(info);
5496 }
5497 else
5498 {
5499 RTPrintf("Remote session has been successfully opened.\n");
5500 }
5501 }
5502
5503 /* it's important to always close sessions */
5504 session->Close();
5505
5506 return SUCCEEDED(rc) ? 0 : 1;
5507}
5508
5509static int handleControlVM(int argc, char *argv[],
5510 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
5511{
5512 HRESULT rc;
5513
5514 if (argc < 2)
5515 return errorSyntax(USAGE_CONTROLVM, "Not enough parameters");
5516
5517 /* try to find the given machine */
5518 ComPtr <IMachine> machine;
5519 Guid uuid (argv[0]);
5520 if (!uuid.isEmpty())
5521 {
5522 CHECK_ERROR (virtualBox, GetMachine (uuid, machine.asOutParam()));
5523 }
5524 else
5525 {
5526 CHECK_ERROR (virtualBox, FindMachine (Bstr(argv[0]), machine.asOutParam()));
5527 if (SUCCEEDED (rc))
5528 machine->COMGETTER(Id) (uuid.asOutParam());
5529 }
5530 if (FAILED (rc))
5531 return 1;
5532
5533 /* open a session for the VM */
5534 CHECK_ERROR_RET (virtualBox, OpenExistingSession (session, uuid), 1);
5535
5536 do
5537 {
5538 /* get the associated console */
5539 ComPtr<IConsole> console;
5540 CHECK_ERROR_BREAK (session, COMGETTER(Console)(console.asOutParam()));
5541 /* ... and session machine */
5542 ComPtr<IMachine> sessionMachine;
5543 CHECK_ERROR_BREAK (session, COMGETTER(Machine)(sessionMachine.asOutParam()));
5544
5545 /* which command? */
5546 if (strcmp(argv[1], "pause") == 0)
5547 {
5548 CHECK_ERROR_BREAK (console, Pause());
5549 }
5550 else if (strcmp(argv[1], "resume") == 0)
5551 {
5552 CHECK_ERROR_BREAK (console, Resume());
5553 }
5554 else if (strcmp(argv[1], "reset") == 0)
5555 {
5556 CHECK_ERROR_BREAK (console, Reset());
5557 }
5558 else if (strcmp(argv[1], "poweroff") == 0)
5559 {
5560 CHECK_ERROR_BREAK (console, PowerDown());
5561 }
5562 else if (strcmp(argv[1], "savestate") == 0)
5563 {
5564 ComPtr<IProgress> progress;
5565 CHECK_ERROR_BREAK (console, SaveState(progress.asOutParam()));
5566
5567 showProgress(progress);
5568
5569 progress->COMGETTER(ResultCode)(&rc);
5570 if (FAILED(rc))
5571 {
5572 com::ProgressErrorInfo info(progress);
5573 if (info.isBasicAvailable())
5574 {
5575 RTPrintf("Error: failed to save machine state. Error message: %lS\n", info.getText().raw());
5576 }
5577 else
5578 {
5579 RTPrintf("Error: failed to save machine state. No error message available!\n");
5580 }
5581 }
5582 }
5583 else if (strcmp(argv[1], "acpipowerbutton") == 0)
5584 {
5585 CHECK_ERROR_BREAK (console, PowerButton());
5586 }
5587 else if (strcmp(argv[1], "acpisleepbutton") == 0)
5588 {
5589 CHECK_ERROR_BREAK (console, SleepButton());
5590 }
5591 else if (strcmp(argv[1], "keyboardputscancode") == 0)
5592 {
5593 ComPtr<IKeyboard> keyboard;
5594 CHECK_ERROR_BREAK(console, COMGETTER(Keyboard)(keyboard.asOutParam()));
5595
5596 if (argc <= 1 + 1)
5597 {
5598 errorArgument("Missing argument to '%s'. Expected IBM PC AT set 2 keyboard scancode(s) as hex byte(s).", argv[1]);
5599 rc = E_FAIL;
5600 break;
5601 }
5602
5603 /* Arbitrary restrict the length of a sequence of scancodes to 1024. */
5604 LONG alScancodes[1024];
5605 int cScancodes = 0;
5606
5607 /* Process the command line. */
5608 int i;
5609 for (i = 1 + 1; i < argc && cScancodes < (int)RT_ELEMENTS(alScancodes); i++, cScancodes++)
5610 {
5611 if ( isxdigit (argv[i][0])
5612 && isxdigit (argv[i][1])
5613 && argv[i][2] == 0)
5614 {
5615 uint8_t u8Scancode;
5616 int rc = RTStrToUInt8Ex(argv[i], NULL, 16, &u8Scancode);
5617 if (RT_FAILURE (rc))
5618 {
5619 RTPrintf("Error: converting '%s' returned %Vrc!\n", argv[i], rc);
5620 rc = E_FAIL;
5621 break;
5622 }
5623
5624 alScancodes[cScancodes] = u8Scancode;
5625 }
5626 else
5627 {
5628 RTPrintf("Error: '%s' is not a hex byte!\n", argv[i]);
5629 rc = E_FAIL;
5630 break;
5631 }
5632 }
5633
5634 if (FAILED(rc))
5635 break;
5636
5637 if ( cScancodes == RT_ELEMENTS(alScancodes)
5638 && i < argc)
5639 {
5640 RTPrintf("Error: too many scancodes, maximum %d allowed!\n", RT_ELEMENTS(alScancodes));
5641 rc = E_FAIL;
5642 break;
5643 }
5644
5645 /* Send scancodes to the VM.
5646 * Note: 'PutScancodes' did not work here. Only the first scancode was transmitted.
5647 */
5648 for (i = 0; i < cScancodes; i++)
5649 {
5650 CHECK_ERROR_BREAK(keyboard, PutScancode(alScancodes[i]));
5651 RTPrintf("Scancode[%d]: 0x%02X\n", i, alScancodes[i]);
5652 }
5653 }
5654 else if (strncmp(argv[1], "setlinkstate", 12) == 0)
5655 {
5656 /* Get the number of network adapters */
5657 ULONG NetworkAdapterCount = 0;
5658 ComPtr <ISystemProperties> info;
5659 CHECK_ERROR_BREAK (virtualBox, COMGETTER(SystemProperties) (info.asOutParam()));
5660 CHECK_ERROR_BREAK (info, COMGETTER(NetworkAdapterCount) (&NetworkAdapterCount));
5661
5662 unsigned n = parseNum(&argv[1][12], NetworkAdapterCount, "NIC");
5663 if (!n)
5664 {
5665 rc = E_FAIL;
5666 break;
5667 }
5668 if (argc <= 1 + 1)
5669 {
5670 errorArgument("Missing argument to '%s'", argv[1]);
5671 rc = E_FAIL;
5672 break;
5673 }
5674 /* get the corresponding network adapter */
5675 ComPtr<INetworkAdapter> adapter;
5676 CHECK_ERROR_BREAK (sessionMachine, GetNetworkAdapter(n - 1, adapter.asOutParam()));
5677 if (adapter)
5678 {
5679 if (strcmp(argv[2], "on") == 0)
5680 {
5681 CHECK_ERROR_BREAK (adapter, COMSETTER(CableConnected)(TRUE));
5682 }
5683 else if (strcmp(argv[2], "off") == 0)
5684 {
5685 CHECK_ERROR_BREAK (adapter, COMSETTER(CableConnected)(FALSE));
5686 }
5687 else
5688 {
5689 errorArgument("Invalid link state '%s'", Utf8Str(argv[2]).raw());
5690 rc = E_FAIL;
5691 break;
5692 }
5693 }
5694 }
5695 else if (strcmp (argv[1], "usbattach") == 0 ||
5696 strcmp (argv[1], "usbdetach") == 0)
5697 {
5698 if (argc < 3)
5699 {
5700 errorSyntax(USAGE_CONTROLVM, "Not enough parameters");
5701 rc = E_FAIL;
5702 break;
5703 }
5704
5705 bool attach = strcmp (argv[1], "usbattach") == 0;
5706
5707 Guid usbId = argv [2];
5708 if (usbId.isEmpty())
5709 {
5710 // assume address
5711 if (attach)
5712 {
5713 ComPtr <IHost> host;
5714 CHECK_ERROR_BREAK (virtualBox, COMGETTER(Host) (host.asOutParam()));
5715 ComPtr <IHostUSBDeviceCollection> coll;
5716 CHECK_ERROR_BREAK (host, COMGETTER(USBDevices) (coll.asOutParam()));
5717 ComPtr <IHostUSBDevice> dev;
5718 CHECK_ERROR_BREAK (coll, FindByAddress (Bstr (argv [2]), dev.asOutParam()));
5719 CHECK_ERROR_BREAK (dev, COMGETTER(Id) (usbId.asOutParam()));
5720 }
5721 else
5722 {
5723 ComPtr <IUSBDeviceCollection> coll;
5724 CHECK_ERROR_BREAK (console, COMGETTER(USBDevices)(coll.asOutParam()));
5725 ComPtr <IUSBDevice> dev;
5726 CHECK_ERROR_BREAK (coll, FindByAddress (Bstr (argv [2]), dev.asOutParam()));
5727 CHECK_ERROR_BREAK (dev, COMGETTER(Id) (usbId.asOutParam()));
5728 }
5729 }
5730
5731 if (attach)
5732 CHECK_ERROR_BREAK (console, AttachUSBDevice (usbId));
5733 else
5734 {
5735 ComPtr <IUSBDevice> dev;
5736 CHECK_ERROR_BREAK (console, DetachUSBDevice (usbId, dev.asOutParam()));
5737 }
5738 }
5739 else if (strcmp(argv[1], "setvideomodehint") == 0)
5740 {
5741 if (argc != 5 && argc != 6)
5742 {
5743 errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");
5744 rc = E_FAIL;
5745 break;
5746 }
5747 uint32_t xres = atoi(argv[2]);
5748 uint32_t yres = atoi(argv[3]);
5749 uint32_t bpp = atoi(argv[4]);
5750 uint32_t displayIdx = 0;
5751 if (argc == 6)
5752 displayIdx = atoi(argv[5]);
5753
5754 ComPtr<IDisplay> display;
5755 CHECK_ERROR_BREAK(console, COMGETTER(Display)(display.asOutParam()));
5756 CHECK_ERROR_BREAK(display, SetVideoModeHint(xres, yres, bpp, displayIdx));
5757 }
5758 else if (strcmp(argv[1], "setcredentials") == 0)
5759 {
5760 bool fAllowLocalLogon = true;
5761 if (argc == 7)
5762 {
5763 if (strcmp(argv[5], "-allowlocallogon") != 0)
5764 {
5765 errorArgument("Invalid parameter '%s'", argv[5]);
5766 rc = E_FAIL;
5767 break;
5768 }
5769 if (strcmp(argv[6], "no") == 0)
5770 fAllowLocalLogon = false;
5771 }
5772 else if (argc != 5)
5773 {
5774 errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");
5775 rc = E_FAIL;
5776 break;
5777 }
5778
5779 ComPtr<IGuest> guest;
5780 CHECK_ERROR_BREAK(console, COMGETTER(Guest)(guest.asOutParam()));
5781 CHECK_ERROR_BREAK(guest, SetCredentials(Bstr(argv[2]), Bstr(argv[3]), Bstr(argv[4]), fAllowLocalLogon));
5782 }
5783 else if (strcmp(argv[1], "dvdattach") == 0)
5784 {
5785 if (argc != 3)
5786 {
5787 errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");
5788 rc = E_FAIL;
5789 break;
5790 }
5791 ComPtr<IDVDDrive> dvdDrive;
5792 sessionMachine->COMGETTER(DVDDrive)(dvdDrive.asOutParam());
5793 ASSERT(dvdDrive);
5794
5795 /* unmount? */
5796 if (strcmp(argv[2], "none") == 0)
5797 {
5798 CHECK_ERROR(dvdDrive, Unmount());
5799 }
5800 /* host drive? */
5801 else if (strncmp(argv[2], "host:", 5) == 0)
5802 {
5803 ComPtr<IHost> host;
5804 CHECK_ERROR(virtualBox, COMGETTER(Host)(host.asOutParam()));
5805 ComPtr<IHostDVDDriveCollection> hostDVDs;
5806 CHECK_ERROR(host, COMGETTER(DVDDrives)(hostDVDs.asOutParam()));
5807 ComPtr<IHostDVDDrive> hostDVDDrive;
5808 rc = hostDVDs->FindByName(Bstr(argv[2] + 5), hostDVDDrive.asOutParam());
5809 if (!hostDVDDrive)
5810 {
5811 errorArgument("Invalid host DVD drive name");
5812 rc = E_FAIL;
5813 break;
5814 }
5815 CHECK_ERROR(dvdDrive, CaptureHostDrive(hostDVDDrive));
5816 }
5817 else
5818 {
5819 /* first assume it's a UUID */
5820 Guid uuid(argv[2]);
5821 ComPtr<IDVDImage> dvdImage;
5822 rc = virtualBox->GetDVDImage(uuid, dvdImage.asOutParam());
5823 if (FAILED(rc) || !dvdImage)
5824 {
5825 /* must be a filename, check if it's in the collection */
5826 ComPtr<IDVDImageCollection> dvdImages;
5827 virtualBox->COMGETTER(DVDImages)(dvdImages.asOutParam());
5828 rc = dvdImages->FindByPath(Bstr(argv[2]), dvdImage.asOutParam());
5829 /* not registered, do that on the fly */
5830 if (!dvdImage)
5831 {
5832 Guid emptyUUID;
5833 CHECK_ERROR(virtualBox, OpenDVDImage(Bstr(argv[2]), emptyUUID, dvdImage.asOutParam()));
5834 if (SUCCEEDED(rc) && dvdImage)
5835 {
5836 /* time to register the image */
5837 CHECK_ERROR(virtualBox, RegisterDVDImage(dvdImage));
5838 }
5839 }
5840 }
5841 if (!dvdImage)
5842 {
5843 rc = E_FAIL;
5844 break;
5845 }
5846 dvdImage->COMGETTER(Id)(uuid.asOutParam());
5847 CHECK_ERROR(dvdDrive, MountImage(uuid));
5848 }
5849 }
5850 else if (strcmp(argv[1], "floppyattach") == 0)
5851 {
5852 if (argc != 3)
5853 {
5854 errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");
5855 rc = E_FAIL;
5856 break;
5857 }
5858
5859 ComPtr<IFloppyDrive> floppyDrive;
5860 sessionMachine->COMGETTER(FloppyDrive)(floppyDrive.asOutParam());
5861 ASSERT(floppyDrive);
5862
5863 /* unmount? */
5864 if (strcmp(argv[2], "none") == 0)
5865 {
5866 CHECK_ERROR(floppyDrive, Unmount());
5867 }
5868 /* host drive? */
5869 else if (strncmp(argv[2], "host:", 5) == 0)
5870 {
5871 ComPtr<IHost> host;
5872 CHECK_ERROR(virtualBox, COMGETTER(Host)(host.asOutParam()));
5873 ComPtr<IHostFloppyDriveCollection> hostFloppies;
5874 CHECK_ERROR(host, COMGETTER(FloppyDrives)(hostFloppies.asOutParam()));
5875 ComPtr<IHostFloppyDrive> hostFloppyDrive;
5876 rc = hostFloppies->FindByName(Bstr(argv[2] + 5), hostFloppyDrive.asOutParam());
5877 if (!hostFloppyDrive)
5878 {
5879 errorArgument("Invalid host floppy drive name");
5880 rc = E_FAIL;
5881 break;
5882 }
5883 CHECK_ERROR(floppyDrive, CaptureHostDrive(hostFloppyDrive));
5884 }
5885 else
5886 {
5887 /* first assume it's a UUID */
5888 Guid uuid(argv[2]);
5889 ComPtr<IFloppyImage> floppyImage;
5890 rc = virtualBox->GetFloppyImage(uuid, floppyImage.asOutParam());
5891 if (FAILED(rc) || !floppyImage)
5892 {
5893 /* must be a filename, check if it's in the collection */
5894 ComPtr<IFloppyImageCollection> floppyImages;
5895 virtualBox->COMGETTER(FloppyImages)(floppyImages.asOutParam());
5896 rc = floppyImages->FindByPath(Bstr(argv[2]), floppyImage.asOutParam());
5897 /* not registered, do that on the fly */
5898 if (!floppyImage)
5899 {
5900 Guid emptyUUID;
5901 CHECK_ERROR(virtualBox, OpenFloppyImage(Bstr(argv[2]), emptyUUID, floppyImage.asOutParam()));
5902 if (SUCCEEDED(rc) && floppyImage)
5903 {
5904 /* time to register the image */
5905 CHECK_ERROR(virtualBox, RegisterFloppyImage(floppyImage));
5906 }
5907 }
5908 }
5909 if (!floppyImage)
5910 {
5911 rc = E_FAIL;
5912 break;
5913 }
5914 floppyImage->COMGETTER(Id)(uuid.asOutParam());
5915 CHECK_ERROR(floppyDrive, MountImage(uuid));
5916 }
5917 }
5918#ifdef VBOX_WITH_MEM_BALLOONING
5919 else if (strncmp(argv[1], "-guestmemoryballoon", 19) == 0)
5920 {
5921 if (argc != 3)
5922 {
5923 errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");
5924 rc = E_FAIL;
5925 break;
5926 }
5927 uint32_t uVal;
5928 int vrc;
5929 vrc = RTStrToUInt32Ex(argv[2], NULL, 0, &uVal);
5930 if (vrc != VINF_SUCCESS)
5931 {
5932 errorArgument("Error parsing guest memory balloon size '%s'", argv[2]);
5933 rc = E_FAIL;
5934 break;
5935 }
5936
5937 /* guest is running; update IGuest */
5938 ComPtr <IGuest> guest;
5939
5940 rc = console->COMGETTER(Guest)(guest.asOutParam());
5941 if (SUCCEEDED(rc))
5942 CHECK_ERROR(guest, COMSETTER(MemoryBalloonSize)(uVal));
5943 }
5944#endif
5945 else if (strncmp(argv[1], "-gueststatisticsinterval", 24) == 0)
5946 {
5947 if (argc != 3)
5948 {
5949 errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");
5950 rc = E_FAIL;
5951 break;
5952 }
5953 uint32_t uVal;
5954 int vrc;
5955 vrc = RTStrToUInt32Ex(argv[2], NULL, 0, &uVal);
5956 if (vrc != VINF_SUCCESS)
5957 {
5958 errorArgument("Error parsing guest statistics interval '%s'", argv[2]);
5959 rc = E_FAIL;
5960 break;
5961 }
5962
5963 /* guest is running; update IGuest */
5964 ComPtr <IGuest> guest;
5965
5966 rc = console->COMGETTER(Guest)(guest.asOutParam());
5967 if (SUCCEEDED(rc))
5968 CHECK_ERROR(guest, COMSETTER(StatisticsUpdateInterval)(uVal));
5969 }
5970 else
5971 {
5972 errorSyntax(USAGE_CONTROLVM, "Invalid parameter '%s'", Utf8Str(argv[1]).raw());
5973 rc = E_FAIL;
5974 }
5975 }
5976 while (0);
5977
5978 session->Close();
5979
5980 return SUCCEEDED (rc) ? 0 : 1;
5981}
5982
5983static int handleDiscardState(int argc, char *argv[],
5984 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
5985{
5986 HRESULT rc;
5987
5988 if (argc != 1)
5989 return errorSyntax(USAGE_DISCARDSTATE, "Incorrect number of parameters");
5990
5991 ComPtr<IMachine> machine;
5992 /* assume it's a UUID */
5993 rc = virtualBox->GetMachine(Guid(argv[0]), machine.asOutParam());
5994 if (FAILED(rc) || !machine)
5995 {
5996 /* must be a name */
5997 CHECK_ERROR(virtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam()));
5998 }
5999 if (machine)
6000 {
6001 do
6002 {
6003 /* we have to open a session for this task */
6004 Guid guid;
6005 machine->COMGETTER(Id)(guid.asOutParam());
6006 CHECK_ERROR_BREAK(virtualBox, OpenSession(session, guid));
6007 do
6008 {
6009 ComPtr<IConsole> console;
6010 CHECK_ERROR_BREAK(session, COMGETTER(Console)(console.asOutParam()));
6011 CHECK_ERROR_BREAK(console, DiscardSavedState());
6012 }
6013 while (0);
6014 CHECK_ERROR_BREAK(session, Close());
6015 }
6016 while (0);
6017 }
6018
6019 return SUCCEEDED(rc) ? 0 : 1;
6020}
6021
6022static int handleAdoptdState(int argc, char *argv[],
6023 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
6024{
6025 HRESULT rc;
6026
6027 if (argc != 2)
6028 return errorSyntax(USAGE_ADOPTSTATE, "Incorrect number of parameters");
6029
6030 ComPtr<IMachine> machine;
6031 /* assume it's a UUID */
6032 rc = virtualBox->GetMachine(Guid(argv[0]), machine.asOutParam());
6033 if (FAILED(rc) || !machine)
6034 {
6035 /* must be a name */
6036 CHECK_ERROR(virtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam()));
6037 }
6038 if (machine)
6039 {
6040 do
6041 {
6042 /* we have to open a session for this task */
6043 Guid guid;
6044 machine->COMGETTER(Id)(guid.asOutParam());
6045 CHECK_ERROR_BREAK(virtualBox, OpenSession(session, guid));
6046 do
6047 {
6048 ComPtr<IConsole> console;
6049 CHECK_ERROR_BREAK(session, COMGETTER(Console)(console.asOutParam()));
6050 CHECK_ERROR_BREAK(console, AdoptSavedState (Bstr (argv[1])));
6051 }
6052 while (0);
6053 CHECK_ERROR_BREAK(session, Close());
6054 }
6055 while (0);
6056 }
6057
6058 return SUCCEEDED(rc) ? 0 : 1;
6059}
6060
6061static int handleSnapshot(int argc, char *argv[],
6062 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
6063{
6064 HRESULT rc;
6065
6066 /* we need at least a VM and a command */
6067 if (argc < 2)
6068 return errorSyntax(USAGE_SNAPSHOT, "Not enough parameters");
6069
6070 /* the first argument must be the VM */
6071 ComPtr<IMachine> machine;
6072 /* assume it's a UUID */
6073 rc = virtualBox->GetMachine(Guid(argv[0]), machine.asOutParam());
6074 if (FAILED(rc) || !machine)
6075 {
6076 /* must be a name */
6077 CHECK_ERROR(virtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam()));
6078 }
6079 if (!machine)
6080 return 1;
6081 Guid guid;
6082 machine->COMGETTER(Id)(guid.asOutParam());
6083
6084 do
6085 {
6086 /* we have to open a session for this task. First try an existing session */
6087 rc = virtualBox->OpenExistingSession(session, guid);
6088 if (FAILED(rc))
6089 CHECK_ERROR_BREAK(virtualBox, OpenSession(session, guid));
6090 ComPtr<IConsole> console;
6091 CHECK_ERROR_BREAK(session, COMGETTER(Console)(console.asOutParam()));
6092
6093 /* switch based on the command */
6094 if (strcmp(argv[1], "take") == 0)
6095 {
6096 /* there must be a name */
6097 if (argc < 3)
6098 {
6099 errorSyntax(USAGE_SNAPSHOT, "Missing snapshot name");
6100 rc = E_FAIL;
6101 break;
6102 }
6103 Bstr name(argv[2]);
6104 if ((argc > 3) && ((argc != 5) || (strcmp(argv[3], "-desc") != 0)))
6105 {
6106 errorSyntax(USAGE_SNAPSHOT, "Incorrect description format");
6107 rc = E_FAIL;
6108 break;
6109 }
6110 Bstr desc;
6111 if (argc == 5)
6112 desc = argv[4];
6113 ComPtr<IProgress> progress;
6114 CHECK_ERROR_BREAK(console, TakeSnapshot(name, desc, progress.asOutParam()));
6115
6116 showProgress(progress);
6117 progress->COMGETTER(ResultCode)(&rc);
6118 if (FAILED(rc))
6119 {
6120 com::ProgressErrorInfo info(progress);
6121 if (info.isBasicAvailable())
6122 RTPrintf("Error: failed to take snapshot. Error message: %lS\n", info.getText().raw());
6123 else
6124 RTPrintf("Error: failed to take snapshot. No error message available!\n");
6125 }
6126 }
6127 else if (strcmp(argv[1], "discard") == 0)
6128 {
6129 /* exactly one parameter: snapshot name */
6130 if (argc != 3)
6131 {
6132 errorSyntax(USAGE_SNAPSHOT, "Expecting snapshot name only");
6133 rc = E_FAIL;
6134 break;
6135 }
6136
6137 ComPtr<ISnapshot> snapshot;
6138
6139 /* assume it's a UUID */
6140 Guid guid(argv[2]);
6141 if (!guid.isEmpty())
6142 {
6143 CHECK_ERROR_BREAK(machine, GetSnapshot(guid, snapshot.asOutParam()));
6144 }
6145 else
6146 {
6147 /* then it must be a name */
6148 CHECK_ERROR_BREAK(machine, FindSnapshot(Bstr(argv[2]), snapshot.asOutParam()));
6149 }
6150
6151 snapshot->COMGETTER(Id)(guid.asOutParam());
6152
6153 ComPtr<IProgress> progress;
6154 CHECK_ERROR_BREAK(console, DiscardSnapshot(guid, progress.asOutParam()));
6155
6156 showProgress(progress);
6157 progress->COMGETTER(ResultCode)(&rc);
6158 if (FAILED(rc))
6159 {
6160 com::ProgressErrorInfo info(progress);
6161 if (info.isBasicAvailable())
6162 RTPrintf("Error: failed to discard snapshot. Error message: %lS\n", info.getText().raw());
6163 else
6164 RTPrintf("Error: failed to discard snapshot. No error message available!\n");
6165 }
6166 }
6167 else if (strcmp(argv[1], "discardcurrent") == 0)
6168 {
6169 if ( (argc != 3)
6170 || ( (strcmp(argv[2], "-state") != 0)
6171 && (strcmp(argv[2], "-all") != 0)))
6172 {
6173 errorSyntax(USAGE_SNAPSHOT, "Invalid parameter '%s'", Utf8Str(argv[2]).raw());
6174 rc = E_FAIL;
6175 break;
6176 }
6177 bool fAll = false;
6178 if (strcmp(argv[2], "-all") == 0)
6179 fAll = true;
6180
6181 ComPtr<IProgress> progress;
6182
6183 if (fAll)
6184 {
6185 CHECK_ERROR_BREAK(console, DiscardCurrentSnapshotAndState(progress.asOutParam()));
6186 }
6187 else
6188 {
6189 CHECK_ERROR_BREAK(console, DiscardCurrentState(progress.asOutParam()));
6190 }
6191
6192 showProgress(progress);
6193 progress->COMGETTER(ResultCode)(&rc);
6194 if (FAILED(rc))
6195 {
6196 com::ProgressErrorInfo info(progress);
6197 if (info.isBasicAvailable())
6198 RTPrintf("Error: failed to discard. Error message: %lS\n", info.getText().raw());
6199 else
6200 RTPrintf("Error: failed to discard. No error message available!\n");
6201 }
6202
6203 }
6204 else if (strcmp(argv[1], "edit") == 0)
6205 {
6206 if (argc < 3)
6207 {
6208 errorSyntax(USAGE_SNAPSHOT, "Missing snapshot name");
6209 rc = E_FAIL;
6210 break;
6211 }
6212
6213 ComPtr<ISnapshot> snapshot;
6214
6215 if (strcmp(argv[2], "-current") == 0)
6216 {
6217 CHECK_ERROR_BREAK(machine, COMGETTER(CurrentSnapshot)(snapshot.asOutParam()));
6218 }
6219 else
6220 {
6221 /* assume it's a UUID */
6222 Guid guid(argv[2]);
6223 if (!guid.isEmpty())
6224 {
6225 CHECK_ERROR_BREAK(machine, GetSnapshot(guid, snapshot.asOutParam()));
6226 }
6227 else
6228 {
6229 /* then it must be a name */
6230 CHECK_ERROR_BREAK(machine, FindSnapshot(Bstr(argv[2]), snapshot.asOutParam()));
6231 }
6232 }
6233
6234 /* parse options */
6235 for (int i = 3; i < argc; i++)
6236 {
6237 if (strcmp(argv[i], "-newname") == 0)
6238 {
6239 if (argc <= i + 1)
6240 {
6241 errorArgument("Missing argument to '%s'", argv[i]);
6242 rc = E_FAIL;
6243 break;
6244 }
6245 i++;
6246 snapshot->COMSETTER(Name)(Bstr(argv[i]));
6247 }
6248 else if (strcmp(argv[i], "-newdesc") == 0)
6249 {
6250 if (argc <= i + 1)
6251 {
6252 errorArgument("Missing argument to '%s'", argv[i]);
6253 rc = E_FAIL;
6254 break;
6255 }
6256 i++;
6257 snapshot->COMSETTER(Description)(Bstr(argv[i]));
6258 }
6259 else
6260 {
6261 errorSyntax(USAGE_SNAPSHOT, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());
6262 rc = E_FAIL;
6263 break;
6264 }
6265 }
6266
6267 }
6268 else if (strcmp(argv[1], "showvminfo") == 0)
6269 {
6270 /* exactly one parameter: snapshot name */
6271 if (argc != 3)
6272 {
6273 errorSyntax(USAGE_SNAPSHOT, "Expecting snapshot name only");
6274 rc = E_FAIL;
6275 break;
6276 }
6277
6278 ComPtr<ISnapshot> snapshot;
6279
6280 /* assume it's a UUID */
6281 Guid guid(argv[2]);
6282 if (!guid.isEmpty())
6283 {
6284 CHECK_ERROR_BREAK(machine, GetSnapshot(guid, snapshot.asOutParam()));
6285 }
6286 else
6287 {
6288 /* then it must be a name */
6289 CHECK_ERROR_BREAK(machine, FindSnapshot(Bstr(argv[2]), snapshot.asOutParam()));
6290 }
6291
6292 /* get the machine of the given snapshot */
6293 ComPtr<IMachine> machine;
6294 snapshot->COMGETTER(Machine)(machine.asOutParam());
6295 showVMInfo(virtualBox, machine, console);
6296 }
6297 else
6298 {
6299 errorSyntax(USAGE_SNAPSHOT, "Invalid parameter '%s'", Utf8Str(argv[1]).raw());
6300 rc = E_FAIL;
6301 }
6302 } while (0);
6303
6304 session->Close();
6305
6306 return SUCCEEDED(rc) ? 0 : 1;
6307}
6308
6309static int handleShowVDIInfo(int argc, char *argv[],
6310 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
6311{
6312 HRESULT rc;
6313
6314 if (argc != 1)
6315 return errorSyntax(USAGE_SHOWVDIINFO, "Incorrect number of parameters");
6316
6317 ComPtr<IHardDisk> hardDisk;
6318 Bstr filepath;
6319
6320 bool registered = true;
6321
6322 /* first guess is that it's a UUID */
6323 Guid uuid(argv[0]);
6324 rc = virtualBox->GetHardDisk(uuid, hardDisk.asOutParam());
6325 /* no? then it must be a filename */
6326 if (FAILED (rc))
6327 {
6328 filepath = argv[0];
6329 rc = virtualBox->FindHardDisk(filepath, hardDisk.asOutParam());
6330 /* no? well, then it's an unregistered image */
6331 if (FAILED (rc))
6332 {
6333 registered = false;
6334 CHECK_ERROR(virtualBox, OpenHardDisk(filepath, hardDisk.asOutParam()));
6335 }
6336 }
6337 if (SUCCEEDED(rc) && hardDisk)
6338 {
6339 /* query a VDI object (will remain null if it's not VDI) */
6340 ComPtr<IVirtualDiskImage> vdi = hardDisk;
6341
6342 hardDisk->COMGETTER(Id)(uuid.asOutParam());
6343 RTPrintf("UUID: %s\n", uuid.toString().raw());
6344
6345 RTPrintf("Registered: %s\n", registered ? "yes" : "no");
6346
6347 /* check for accessibility */
6348 BOOL accessible = FALSE;
6349 CHECK_ERROR_RET (hardDisk, COMGETTER(Accessible)(&accessible), 1);
6350 RTPrintf("Accessible: %s\n", accessible ? "yes" : "no");
6351
6352 if (!accessible)
6353 {
6354 Bstr err;
6355 CHECK_ERROR_RET (hardDisk, COMGETTER(LastAccessError)(err.asOutParam()), 1);
6356 RTPrintf("Access Error: %lS\n", err.raw());
6357 }
6358
6359 Bstr description;
6360 hardDisk->COMGETTER(Description)(description.asOutParam());
6361 if (description)
6362 {
6363 RTPrintf("Description: %lS\n", description.raw());
6364 }
6365
6366 ULONG64 size;
6367 hardDisk->COMGETTER(Size)(&size);
6368 RTPrintf("Size: %llu MBytes\n", size);
6369 ULONG64 actualSize;
6370 hardDisk->COMGETTER(ActualSize)(&actualSize);
6371 RTPrintf("Current size on disk: %llu MBytes\n", actualSize >> 20);
6372
6373 HardDiskType_T type;
6374 hardDisk->COMGETTER(Type)(&type);
6375 const char *typeStr = "unknown";
6376 switch (type)
6377 {
6378 case HardDiskType_Normal:
6379 typeStr = "standard";
6380 break;
6381 case HardDiskType_Immutable:
6382 typeStr = "immutable";
6383 break;
6384 case HardDiskType_Writethrough:
6385 typeStr = "writethrough";
6386 break;
6387 }
6388 RTPrintf("Type: %s\n", typeStr);
6389
6390 HardDiskStorageType_T storageType;
6391 const char *storageTypeStr = "unknown";
6392 hardDisk->COMGETTER(StorageType)(&storageType);
6393 switch (storageType)
6394 {
6395 case HardDiskStorageType_VirtualDiskImage:
6396 storageTypeStr = "Virtual Disk Image (VDI)";
6397 break;
6398 case HardDiskStorageType_VMDKImage:
6399 storageTypeStr = "VMDK Image";
6400 break;
6401 case HardDiskStorageType_ISCSIHardDisk:
6402 storageTypeStr = "iSCSI target";
6403 break;
6404 case HardDiskStorageType_VHDImage:
6405 storageTypeStr = "VHD Image";
6406 break;
6407 }
6408 RTPrintf("Storage type: %s\n", storageTypeStr);
6409
6410 if (registered)
6411 {
6412 hardDisk->COMGETTER(MachineId)(uuid.asOutParam());
6413 RTPrintf("In use by VM: %s\n", uuid ? uuid.toString().raw() : "<none>");
6414 }
6415
6416 if (vdi)
6417 {
6418 /* VDI specific information */
6419 vdi->COMGETTER(FilePath)(filepath.asOutParam());
6420 RTPrintf("Path: %lS\n", filepath.raw());
6421
6422 }
6423 else
6424 {
6425 /* Generic location information */
6426 Bstr loc;
6427 hardDisk->COMGETTER(Location)(loc.asOutParam());
6428 RTPrintf("Location: %lS\n", loc.raw());
6429 }
6430 }
6431 return SUCCEEDED(rc) ? 0 : 1;
6432}
6433
6434static int handleRegisterImage(int argc, char *argv[],
6435 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
6436{
6437 HRESULT rc;
6438
6439 if (argc < 2)
6440 return errorSyntax(USAGE_REGISTERIMAGE, "Not enough parameters");
6441
6442 Bstr filepath(argv[1]);
6443
6444 if (strcmp(argv[0], "disk") == 0)
6445 {
6446 const char *type = NULL;
6447 /* there can be a type parameter */
6448 if ((argc > 2) && (argc != 4))
6449 return errorSyntax(USAGE_REGISTERIMAGE, "Incorrect number of parameters");
6450 if (argc == 4)
6451 {
6452 if (strcmp(argv[2], "-type") != 0)
6453 return errorSyntax(USAGE_REGISTERIMAGE, "Invalid parameter '%s'", Utf8Str(argv[2]).raw());
6454 if ( (strcmp(argv[3], "normal") != 0)
6455 && (strcmp(argv[3], "immutable") != 0)
6456 && (strcmp(argv[3], "writethrough") != 0))
6457 return errorArgument("Invalid VDI type '%s' specified", Utf8Str(argv[3]).raw());
6458 type = argv[3];
6459 }
6460
6461 ComPtr<IHardDisk> hardDisk;
6462 CHECK_ERROR(virtualBox, OpenHardDisk(filepath, hardDisk.asOutParam()));
6463 if (SUCCEEDED(rc) && hardDisk)
6464 {
6465 /* change the type if requested */
6466 if (type)
6467 {
6468 if (strcmp(type, "normal") == 0)
6469 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Normal));
6470 else if (strcmp(type, "immutable") == 0)
6471 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Immutable));
6472 else if (strcmp(type, "writethrough") == 0)
6473 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Writethrough));
6474 }
6475 if (SUCCEEDED(rc))
6476 CHECK_ERROR(virtualBox, RegisterHardDisk(hardDisk));
6477 }
6478 }
6479 else if (strcmp(argv[0], "dvd") == 0)
6480 {
6481 ComPtr<IDVDImage> dvdImage;
6482 CHECK_ERROR(virtualBox, OpenDVDImage(filepath, Guid(), dvdImage.asOutParam()));
6483 if (SUCCEEDED(rc) && dvdImage)
6484 {
6485 CHECK_ERROR(virtualBox, RegisterDVDImage(dvdImage));
6486 }
6487 }
6488 else if (strcmp(argv[0], "floppy") == 0)
6489 {
6490 ComPtr<IFloppyImage> floppyImage;
6491 CHECK_ERROR(virtualBox, OpenFloppyImage(filepath, Guid(), floppyImage.asOutParam()));
6492 if (SUCCEEDED(rc) && floppyImage)
6493 {
6494 CHECK_ERROR(virtualBox, RegisterFloppyImage(floppyImage));
6495 }
6496 }
6497 else
6498 return errorSyntax(USAGE_REGISTERIMAGE, "Invalid parameter '%s'", Utf8Str(argv[1]).raw());
6499
6500 return SUCCEEDED(rc) ? 0 : 1;
6501}
6502
6503static int handleUnregisterImage(int argc, char *argv[],
6504 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
6505{
6506 HRESULT rc;
6507
6508 if (argc != 2)
6509 return errorSyntax(USAGE_UNREGISTERIMAGE, "Incorrect number of parameters");
6510
6511 /* first guess is that it's a UUID */
6512 Guid uuid(argv[1]);
6513
6514 if (strcmp(argv[0], "disk") == 0)
6515 {
6516 ComPtr<IHardDisk> hardDisk;
6517 rc = virtualBox->GetHardDisk(uuid, hardDisk.asOutParam());
6518 /* not a UUID or not registered? Then it must be a filename */
6519 if (!hardDisk)
6520 {
6521 ComPtr<IVirtualDiskImage> vdi;
6522 CHECK_ERROR(virtualBox, FindVirtualDiskImage(Bstr(argv[1]), vdi.asOutParam()));
6523 hardDisk = vdi;
6524 }
6525 if (SUCCEEDED(rc) && hardDisk)
6526 {
6527 hardDisk->COMGETTER(Id)(uuid.asOutParam());
6528 CHECK_ERROR(virtualBox, UnregisterHardDisk(uuid, hardDisk.asOutParam()));
6529 }
6530 }
6531 else
6532 if (strcmp(argv[0], "dvd") == 0)
6533 {
6534 ComPtr<IDVDImage> dvdImage;
6535 rc = virtualBox->GetDVDImage(uuid, dvdImage.asOutParam());
6536 /* not a UUID or not registered? Then it must be a filename */
6537 if (!dvdImage)
6538 {
6539 ComPtr<IDVDImageCollection> dvdColl;
6540 virtualBox->COMGETTER(DVDImages)(dvdColl.asOutParam());
6541 CHECK_ERROR(dvdColl, FindByPath(Bstr(argv[1]), dvdImage.asOutParam()));
6542 }
6543 if (SUCCEEDED(rc) && dvdImage)
6544 {
6545 dvdImage->COMGETTER(Id)(uuid.asOutParam());
6546 CHECK_ERROR(virtualBox, UnregisterDVDImage(uuid, dvdImage.asOutParam()));
6547 }
6548 }
6549 else
6550 if (strcmp(argv[0], "floppy") == 0)
6551 {
6552 ComPtr<IFloppyImage> floppyImage;
6553 rc = virtualBox->GetFloppyImage(uuid, floppyImage.asOutParam());
6554 /* not a UUID or not registered? Then it must be a filename */
6555 if (!floppyImage)
6556 {
6557 ComPtr<IFloppyImageCollection> floppyColl;
6558 virtualBox->COMGETTER(FloppyImages)(floppyColl.asOutParam());
6559 CHECK_ERROR(floppyColl, FindByPath(Bstr(argv[1]), floppyImage.asOutParam()));
6560 }
6561 if (SUCCEEDED(rc) && floppyImage)
6562 {
6563 floppyImage->COMGETTER(Id)(uuid.asOutParam());
6564 CHECK_ERROR(virtualBox, UnregisterFloppyImage(uuid, floppyImage.asOutParam()));
6565 }
6566 }
6567 else
6568 return errorSyntax(USAGE_UNREGISTERIMAGE, "Invalid parameter '%s'", Utf8Str(argv[1]).raw());
6569
6570 return SUCCEEDED(rc) ? 0 : 1;
6571}
6572
6573#ifdef RT_OS_WINDOWS
6574static int handleCreateHostIF(int argc, char *argv[],
6575 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
6576{
6577 if (argc != 1)
6578 return errorSyntax(USAGE_CREATEHOSTIF, "Incorrect number of parameters");
6579
6580 HRESULT rc = S_OK;
6581
6582 do
6583 {
6584 ComPtr<IHost> host;
6585 CHECK_ERROR_BREAK(virtualBox, COMGETTER(Host)(host.asOutParam()));
6586
6587 ComPtr<IHostNetworkInterface> hostif;
6588 ComPtr<IProgress> progress;
6589 CHECK_ERROR_BREAK(host,
6590 CreateHostNetworkInterface(Bstr(argv[0]),
6591 hostif.asOutParam(),
6592 progress.asOutParam()));
6593
6594 showProgress(progress);
6595 HRESULT result;
6596 CHECK_ERROR_BREAK(progress, COMGETTER(ResultCode)(&result));
6597 if (FAILED(result))
6598 {
6599 com::ProgressErrorInfo info(progress);
6600 PRINT_ERROR_INFO(info);
6601 rc = result;
6602 }
6603 }
6604 while (0);
6605
6606 return SUCCEEDED(rc) ? 0 : 1;
6607}
6608
6609static int handleRemoveHostIF(int argc, char *argv[],
6610 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
6611{
6612 if (argc != 1)
6613 return errorSyntax(USAGE_REMOVEHOSTIF, "Incorrect number of parameters");
6614
6615 HRESULT rc = S_OK;
6616
6617 do
6618 {
6619 ComPtr<IHost> host;
6620 CHECK_ERROR_BREAK(virtualBox, COMGETTER(Host)(host.asOutParam()));
6621
6622 ComPtr<IHostNetworkInterface> hostif;
6623
6624 /* first guess is that it's a UUID */
6625 Guid uuid(argv[0]);
6626 if (uuid.isEmpty())
6627 {
6628 /* not a valid UUID, search for it */
6629 ComPtr<IHostNetworkInterfaceCollection> coll;
6630 CHECK_ERROR_BREAK(host, COMGETTER(NetworkInterfaces)(coll.asOutParam()));
6631 CHECK_ERROR_BREAK(coll, FindByName(Bstr(argv[0]), hostif.asOutParam()));
6632 CHECK_ERROR_BREAK(hostif, COMGETTER(Id)(uuid.asOutParam()));
6633 }
6634
6635 ComPtr<IProgress> progress;
6636 CHECK_ERROR_BREAK(host,
6637 RemoveHostNetworkInterface(uuid,
6638 hostif.asOutParam(),
6639 progress.asOutParam()));
6640
6641 showProgress(progress);
6642 HRESULT result;
6643 CHECK_ERROR_BREAK(progress, COMGETTER(ResultCode)(&result));
6644 if (FAILED(result))
6645 {
6646 com::ProgressErrorInfo info(progress);
6647 PRINT_ERROR_INFO(info);
6648 rc = result;
6649 }
6650 }
6651 while (0);
6652
6653 return SUCCEEDED(rc) ? 0 : 1;
6654}
6655#endif /* RT_OS_WINDOWS */
6656
6657static int handleGetExtraData(int argc, char *argv[],
6658 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
6659{
6660 HRESULT rc = S_OK;
6661
6662 if (argc != 2)
6663 return errorSyntax(USAGE_GETEXTRADATA, "Incorrect number of parameters");
6664
6665 /* global data? */
6666 if (strcmp(argv[0], "global") == 0)
6667 {
6668 /* enumeration? */
6669 if (strcmp(argv[1], "enumerate") == 0)
6670 {
6671 Bstr extraDataKey;
6672
6673 do
6674 {
6675 Bstr nextExtraDataKey;
6676 Bstr nextExtraDataValue;
6677 HRESULT rcEnum = virtualBox->GetNextExtraDataKey(extraDataKey, nextExtraDataKey.asOutParam(),
6678 nextExtraDataValue.asOutParam());
6679 extraDataKey = nextExtraDataKey;
6680
6681 if (SUCCEEDED(rcEnum) && extraDataKey)
6682 RTPrintf("Key: %lS, Value: %lS\n", nextExtraDataKey.raw(), nextExtraDataValue.raw());
6683 } while (extraDataKey);
6684 }
6685 else
6686 {
6687 Bstr value;
6688 CHECK_ERROR(virtualBox, GetExtraData(Bstr(argv[1]), value.asOutParam()));
6689 if (value)
6690 RTPrintf("Value: %lS\n", value.raw());
6691 else
6692 RTPrintf("No value set!\n");
6693 }
6694 }
6695 else
6696 {
6697 ComPtr<IMachine> machine;
6698 /* assume it's a UUID */
6699 rc = virtualBox->GetMachine(Guid(argv[0]), machine.asOutParam());
6700 if (FAILED(rc) || !machine)
6701 {
6702 /* must be a name */
6703 CHECK_ERROR(virtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam()));
6704 }
6705 if (machine)
6706 {
6707 /* enumeration? */
6708 if (strcmp(argv[1], "enumerate") == 0)
6709 {
6710 Bstr extraDataKey;
6711
6712 do
6713 {
6714 Bstr nextExtraDataKey;
6715 Bstr nextExtraDataValue;
6716 HRESULT rcEnum = machine->GetNextExtraDataKey(extraDataKey, nextExtraDataKey.asOutParam(),
6717 nextExtraDataValue.asOutParam());
6718 extraDataKey = nextExtraDataKey;
6719
6720 if (SUCCEEDED(rcEnum) && extraDataKey)
6721 {
6722 RTPrintf("Key: %lS, Value: %lS\n", nextExtraDataKey.raw(), nextExtraDataValue.raw());
6723 }
6724 } while (extraDataKey);
6725 }
6726 else
6727 {
6728 Bstr value;
6729 CHECK_ERROR(machine, GetExtraData(Bstr(argv[1]), value.asOutParam()));
6730 if (value)
6731 RTPrintf("Value: %lS\n", value.raw());
6732 else
6733 RTPrintf("No value set!\n");
6734 }
6735 }
6736 }
6737 return SUCCEEDED(rc) ? 0 : 1;
6738}
6739
6740static int handleSetExtraData(int argc, char *argv[],
6741 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
6742{
6743 HRESULT rc = S_OK;
6744
6745 if (argc < 2)
6746 return errorSyntax(USAGE_SETEXTRADATA, "Not enough parameters");
6747
6748 /* global data? */
6749 if (strcmp(argv[0], "global") == 0)
6750 {
6751 if (argc < 3)
6752 CHECK_ERROR(virtualBox, SetExtraData(Bstr(argv[1]), NULL));
6753 else if (argc == 3)
6754 CHECK_ERROR(virtualBox, SetExtraData(Bstr(argv[1]), Bstr(argv[2])));
6755 else
6756 return errorSyntax(USAGE_SETEXTRADATA, "Too many parameters");
6757 }
6758 else
6759 {
6760 ComPtr<IMachine> machine;
6761 /* assume it's a UUID */
6762 rc = virtualBox->GetMachine(Guid(argv[0]), machine.asOutParam());
6763 if (FAILED(rc) || !machine)
6764 {
6765 /* must be a name */
6766 CHECK_ERROR(virtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam()));
6767 }
6768 if (machine)
6769 {
6770 if (argc < 3)
6771 CHECK_ERROR(machine, SetExtraData(Bstr(argv[1]), NULL));
6772 else if (argc == 3)
6773 CHECK_ERROR(machine, SetExtraData(Bstr(argv[1]), Bstr(argv[2])));
6774 else
6775 return errorSyntax(USAGE_SETEXTRADATA, "Too many parameters");
6776 }
6777 }
6778 return SUCCEEDED(rc) ? 0 : 1;
6779}
6780
6781static int handleSetProperty(int argc, char *argv[],
6782 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
6783{
6784 HRESULT rc;
6785
6786 /* there must be two arguments: property name and value */
6787 if (argc != 2)
6788 return errorSyntax(USAGE_SETPROPERTY, "Incorrect number of parameters");
6789
6790 ComPtr<ISystemProperties> systemProperties;
6791 virtualBox->COMGETTER(SystemProperties)(systemProperties.asOutParam());
6792
6793 if (strcmp(argv[0], "vdifolder") == 0)
6794 {
6795 /* reset to default? */
6796 if (strcmp(argv[1], "default") == 0)
6797 CHECK_ERROR(systemProperties, COMSETTER(DefaultVDIFolder)(NULL));
6798 else
6799 CHECK_ERROR(systemProperties, COMSETTER(DefaultVDIFolder)(Bstr(argv[1])));
6800 }
6801 else if (strcmp(argv[0], "machinefolder") == 0)
6802 {
6803 /* reset to default? */
6804 if (strcmp(argv[1], "default") == 0)
6805 CHECK_ERROR(systemProperties, COMSETTER(DefaultMachineFolder)(NULL));
6806 else
6807 CHECK_ERROR(systemProperties, COMSETTER(DefaultMachineFolder)(Bstr(argv[1])));
6808 }
6809 else if (strcmp(argv[0], "vrdpauthlibrary") == 0)
6810 {
6811 /* reset to default? */
6812 if (strcmp(argv[1], "default") == 0)
6813 CHECK_ERROR(systemProperties, COMSETTER(RemoteDisplayAuthLibrary)(NULL));
6814 else
6815 CHECK_ERROR(systemProperties, COMSETTER(RemoteDisplayAuthLibrary)(Bstr(argv[1])));
6816 }
6817 else if (strcmp(argv[0], "websrvauthlibrary") == 0)
6818 {
6819 /* reset to default? */
6820 if (strcmp(argv[1], "default") == 0)
6821 CHECK_ERROR(systemProperties, COMSETTER(WebServiceAuthLibrary)(NULL));
6822 else
6823 CHECK_ERROR(systemProperties, COMSETTER(WebServiceAuthLibrary)(Bstr(argv[1])));
6824 }
6825 else if (strcmp(argv[0], "hwvirtexenabled") == 0)
6826 {
6827 if (strcmp(argv[1], "yes") == 0)
6828 CHECK_ERROR(systemProperties, COMSETTER(HWVirtExEnabled)(TRUE));
6829 else if (strcmp(argv[1], "no") == 0)
6830 CHECK_ERROR(systemProperties, COMSETTER(HWVirtExEnabled)(FALSE));
6831 else
6832 return errorArgument("Invalid value '%s' for hardware virtualization extension flag", argv[1]);
6833 }
6834 else if (strcmp(argv[0], "loghistorycount") == 0)
6835 {
6836 uint32_t uVal;
6837 int vrc;
6838 vrc = RTStrToUInt32Ex(argv[1], NULL, 0, &uVal);
6839 if (vrc != VINF_SUCCESS)
6840 return errorArgument("Error parsing Log history count '%s'", argv[1]);
6841 CHECK_ERROR(systemProperties, COMSETTER(LogHistoryCount)(uVal));
6842 }
6843 else
6844 return errorSyntax(USAGE_SETPROPERTY, "Invalid parameter '%s'", argv[0]);
6845
6846 return SUCCEEDED(rc) ? 0 : 1;
6847}
6848
6849static int handleUSBFilter (int argc, char *argv[],
6850 ComPtr <IVirtualBox> aVirtualBox, ComPtr<ISession> aSession)
6851{
6852 HRESULT rc = S_OK;
6853 USBFilterCmd cmd;
6854
6855 /* at least: 0: command, 1: index, 2: -target, 3: <target value> */
6856 if (argc < 4)
6857 return errorSyntax(USAGE_USBFILTER, "Not enough parameters");
6858
6859 /* which command? */
6860 cmd.mAction = USBFilterCmd::Invalid;
6861 if (strcmp (argv [0], "add") == 0) cmd.mAction = USBFilterCmd::Add;
6862 else if (strcmp (argv [0], "modify") == 0) cmd.mAction = USBFilterCmd::Modify;
6863 else if (strcmp (argv [0], "remove") == 0) cmd.mAction = USBFilterCmd::Remove;
6864
6865 if (cmd.mAction == USBFilterCmd::Invalid)
6866 return errorSyntax(USAGE_USBFILTER, "Invalid parameter '%s'", argv[0]);
6867
6868 /* which index? */
6869 char *endptr = NULL;
6870 cmd.mIndex = strtoul (argv[1], &endptr, 10);
6871 if (!endptr || *endptr)
6872 return errorSyntax(USAGE_USBFILTER, "Invalid index '%s'", argv[1]);
6873
6874 switch (cmd.mAction)
6875 {
6876 case USBFilterCmd::Add:
6877 case USBFilterCmd::Modify:
6878 {
6879 /* at least: 0: command, 1: index, 2: -target, 3: <target value>, 4: -name, 5: <name value> */
6880 if (argc < 6)
6881 {
6882 if (cmd.mAction == USBFilterCmd::Add)
6883 return errorSyntax(USAGE_USBFILTER_ADD, "Not enough parameters");
6884
6885 return errorSyntax(USAGE_USBFILTER_MODIFY, "Not enough parameters");
6886 }
6887
6888 // set Active to true by default
6889 // (assuming that the user sets up all necessary attributes
6890 // at once and wants the filter to be active immediately)
6891 if (cmd.mAction == USBFilterCmd::Add)
6892 cmd.mFilter.mActive = true;
6893
6894 for (int i = 2; i < argc; i++)
6895 {
6896 if (strcmp(argv [i], "-target") == 0)
6897 {
6898 if (argc <= i + 1 || !*argv[i+1])
6899 return errorArgument("Missing argument to '%s'", argv[i]);
6900 i++;
6901 if (strcmp (argv [i], "global") == 0)
6902 cmd.mGlobal = true;
6903 else
6904 {
6905 /* assume it's a UUID of a machine */
6906 rc = aVirtualBox->GetMachine(Guid(argv[i]), cmd.mMachine.asOutParam());
6907 if (FAILED(rc) || !cmd.mMachine)
6908 {
6909 /* must be a name */
6910 CHECK_ERROR_RET(aVirtualBox, FindMachine(Bstr(argv[i]), cmd.mMachine.asOutParam()), 1);
6911 }
6912 }
6913 }
6914 else if (strcmp(argv [i], "-name") == 0)
6915 {
6916 if (argc <= i + 1 || !*argv[i+1])
6917 return errorArgument("Missing argument to '%s'", argv[i]);
6918 i++;
6919 cmd.mFilter.mName = argv [i];
6920 }
6921 else if (strcmp(argv [i], "-active") == 0)
6922 {
6923 if (argc <= i + 1)
6924 return errorArgument("Missing argument to '%s'", argv[i]);
6925 i++;
6926 if (strcmp (argv [i], "yes") == 0)
6927 cmd.mFilter.mActive = true;
6928 else if (strcmp (argv [i], "no") == 0)
6929 cmd.mFilter.mActive = false;
6930 else
6931 return errorArgument("Invalid -active argument '%s'", argv[i]);
6932 }
6933 else if (strcmp(argv [i], "-vendorid") == 0)
6934 {
6935 if (argc <= i + 1)
6936 return errorArgument("Missing argument to '%s'", argv[i]);
6937 i++;
6938 cmd.mFilter.mVendorId = argv [i];
6939 }
6940 else if (strcmp(argv [i], "-productid") == 0)
6941 {
6942 if (argc <= i + 1)
6943 return errorArgument("Missing argument to '%s'", argv[i]);
6944 i++;
6945 cmd.mFilter.mProductId = argv [i];
6946 }
6947 else if (strcmp(argv [i], "-revision") == 0)
6948 {
6949 if (argc <= i + 1)
6950 return errorArgument("Missing argument to '%s'", argv[i]);
6951 i++;
6952 cmd.mFilter.mRevision = argv [i];
6953 }
6954 else if (strcmp(argv [i], "-manufacturer") == 0)
6955 {
6956 if (argc <= i + 1)
6957 return errorArgument("Missing argument to '%s'", argv[i]);
6958 i++;
6959 cmd.mFilter.mManufacturer = argv [i];
6960 }
6961 else if (strcmp(argv [i], "-product") == 0)
6962 {
6963 if (argc <= i + 1)
6964 return errorArgument("Missing argument to '%s'", argv[i]);
6965 i++;
6966 cmd.mFilter.mProduct = argv [i];
6967 }
6968 else if (strcmp(argv [i], "-remote") == 0)
6969 {
6970 if (argc <= i + 1)
6971 return errorArgument("Missing argument to '%s'", argv[i]);
6972 i++;
6973 cmd.mFilter.mRemote = argv[i];
6974 }
6975 else if (strcmp(argv [i], "-serialnumber") == 0)
6976 {
6977 if (argc <= i + 1)
6978 return errorArgument("Missing argument to '%s'", argv[i]);
6979 i++;
6980 cmd.mFilter.mSerialNumber = argv [i];
6981 }
6982 else if (strcmp(argv [i], "-maskedinterfaces") == 0)
6983 {
6984 if (argc <= i + 1)
6985 return errorArgument("Missing argument to '%s'", argv[i]);
6986 i++;
6987 uint32_t u32;
6988 rc = RTStrToUInt32Full(argv[i], 0, &u32);
6989 if (RT_FAILURE(rc))
6990 return errorArgument("Failed to convert the -maskedinterfaces value '%s' to a number, rc=%Rrc", argv[i], rc);
6991 cmd.mFilter.mMaskedInterfaces = u32;
6992 }
6993 else if (strcmp(argv [i], "-action") == 0)
6994 {
6995 if (argc <= i + 1)
6996 return errorArgument("Missing argument to '%s'", argv[i]);
6997 i++;
6998 if (strcmp (argv [i], "ignore") == 0)
6999 cmd.mFilter.mAction = USBDeviceFilterAction_Ignore;
7000 else if (strcmp (argv [i], "hold") == 0)
7001 cmd.mFilter.mAction = USBDeviceFilterAction_Hold;
7002 else
7003 return errorArgument("Invalid USB filter action '%s'", argv[i]);
7004 }
7005 else
7006 return errorSyntax(cmd.mAction == USBFilterCmd::Add ? USAGE_USBFILTER_ADD : USAGE_USBFILTER_MODIFY,
7007 "Unknown option '%s'", argv[i]);
7008 }
7009
7010 if (cmd.mAction == USBFilterCmd::Add)
7011 {
7012 // mandatory/forbidden options
7013 if ( cmd.mFilter.mName.isEmpty()
7014 ||
7015 ( cmd.mGlobal
7016 && cmd.mFilter.mAction == USBDeviceFilterAction_Null
7017 )
7018 || ( !cmd.mGlobal
7019 && !cmd.mMachine)
7020 || ( cmd.mGlobal
7021 && cmd.mFilter.mRemote)
7022 )
7023 {
7024 return errorSyntax(USAGE_USBFILTER_ADD, "Mandatory options not supplied");
7025 }
7026 }
7027 break;
7028 }
7029
7030 case USBFilterCmd::Remove:
7031 {
7032 /* at least: 0: command, 1: index, 2: -target, 3: <target value> */
7033 if (argc < 4)
7034 return errorSyntax(USAGE_USBFILTER_REMOVE, "Not enough parameters");
7035
7036 for (int i = 2; i < argc; i++)
7037 {
7038 if (strcmp(argv [i], "-target") == 0)
7039 {
7040 if (argc <= i + 1 || !*argv[i+1])
7041 return errorArgument("Missing argument to '%s'", argv[i]);
7042 i++;
7043 if (strcmp (argv [i], "global") == 0)
7044 cmd.mGlobal = true;
7045 else
7046 {
7047 /* assume it's a UUID of a machine */
7048 rc = aVirtualBox->GetMachine(Guid(argv[i]), cmd.mMachine.asOutParam());
7049 if (FAILED(rc) || !cmd.mMachine)
7050 {
7051 /* must be a name */
7052 CHECK_ERROR_RET(aVirtualBox, FindMachine(Bstr(argv[i]), cmd.mMachine.asOutParam()), 1);
7053 }
7054 }
7055 }
7056 }
7057
7058 // mandatory options
7059 if (!cmd.mGlobal && !cmd.mMachine)
7060 return errorSyntax(USAGE_USBFILTER_REMOVE, "Mandatory options not supplied");
7061
7062 break;
7063 }
7064
7065 default: break;
7066 }
7067
7068 USBFilterCmd::USBFilter &f = cmd.mFilter;
7069
7070 ComPtr <IHost> host;
7071 ComPtr <IUSBController> ctl;
7072 if (cmd.mGlobal)
7073 CHECK_ERROR_RET (aVirtualBox, COMGETTER(Host) (host.asOutParam()), 1);
7074 else
7075 {
7076 Guid uuid;
7077 cmd.mMachine->COMGETTER(Id)(uuid.asOutParam());
7078 /* open a session for the VM */
7079 CHECK_ERROR_RET (aVirtualBox, OpenSession(aSession, uuid), 1);
7080 /* get the mutable session machine */
7081 aSession->COMGETTER(Machine)(cmd.mMachine.asOutParam());
7082 /* and get the USB controller */
7083 CHECK_ERROR_RET (cmd.mMachine, COMGETTER(USBController) (ctl.asOutParam()), 1);
7084 }
7085
7086 switch (cmd.mAction)
7087 {
7088 case USBFilterCmd::Add:
7089 {
7090 if (cmd.mGlobal)
7091 {
7092 ComPtr <IHostUSBDeviceFilter> flt;
7093 CHECK_ERROR_BREAK (host, CreateUSBDeviceFilter (f.mName, flt.asOutParam()));
7094
7095 if (!f.mActive.isNull())
7096 CHECK_ERROR_BREAK (flt, COMSETTER(Active) (f.mActive));
7097 if (!f.mVendorId.isNull())
7098 CHECK_ERROR_BREAK (flt, COMSETTER(VendorId) (f.mVendorId.setNullIfEmpty()));
7099 if (!f.mProductId.isNull())
7100 CHECK_ERROR_BREAK (flt, COMSETTER(ProductId) (f.mProductId.setNullIfEmpty()));
7101 if (!f.mRevision.isNull())
7102 CHECK_ERROR_BREAK (flt, COMSETTER(Revision) (f.mRevision.setNullIfEmpty()));
7103 if (!f.mManufacturer.isNull())
7104 CHECK_ERROR_BREAK (flt, COMSETTER(Manufacturer) (f.mManufacturer.setNullIfEmpty()));
7105 if (!f.mSerialNumber.isNull())
7106 CHECK_ERROR_BREAK (flt, COMSETTER(SerialNumber) (f.mSerialNumber.setNullIfEmpty()));
7107 if (!f.mMaskedInterfaces.isNull())
7108 CHECK_ERROR_BREAK (flt, COMSETTER(MaskedInterfaces) (f.mMaskedInterfaces));
7109
7110 if (f.mAction != USBDeviceFilterAction_Null)
7111 CHECK_ERROR_BREAK (flt, COMSETTER(Action) (f.mAction));
7112
7113 CHECK_ERROR_BREAK (host, InsertUSBDeviceFilter (cmd.mIndex, flt));
7114 }
7115 else
7116 {
7117 ComPtr <IUSBDeviceFilter> flt;
7118 CHECK_ERROR_BREAK (ctl, CreateDeviceFilter (f.mName, flt.asOutParam()));
7119
7120 if (!f.mActive.isNull())
7121 CHECK_ERROR_BREAK (flt, COMSETTER(Active) (f.mActive));
7122 if (!f.mVendorId.isNull())
7123 CHECK_ERROR_BREAK (flt, COMSETTER(VendorId) (f.mVendorId.setNullIfEmpty()));
7124 if (!f.mProductId.isNull())
7125 CHECK_ERROR_BREAK (flt, COMSETTER(ProductId) (f.mProductId.setNullIfEmpty()));
7126 if (!f.mRevision.isNull())
7127 CHECK_ERROR_BREAK (flt, COMSETTER(Revision) (f.mRevision.setNullIfEmpty()));
7128 if (!f.mManufacturer.isNull())
7129 CHECK_ERROR_BREAK (flt, COMSETTER(Manufacturer) (f.mManufacturer.setNullIfEmpty()));
7130 if (!f.mRemote.isNull())
7131 CHECK_ERROR_BREAK (flt, COMSETTER(Remote) (f.mRemote.setNullIfEmpty()));
7132 if (!f.mSerialNumber.isNull())
7133 CHECK_ERROR_BREAK (flt, COMSETTER(SerialNumber) (f.mSerialNumber.setNullIfEmpty()));
7134 if (!f.mMaskedInterfaces.isNull())
7135 CHECK_ERROR_BREAK (flt, COMSETTER(MaskedInterfaces) (f.mMaskedInterfaces));
7136
7137 CHECK_ERROR_BREAK (ctl, InsertDeviceFilter (cmd.mIndex, flt));
7138 }
7139 break;
7140 }
7141 case USBFilterCmd::Modify:
7142 {
7143 if (cmd.mGlobal)
7144 {
7145 ComPtr <IHostUSBDeviceFilterCollection> coll;
7146 CHECK_ERROR_BREAK (host, COMGETTER(USBDeviceFilters) (coll.asOutParam()));
7147 ComPtr <IHostUSBDeviceFilter> flt;
7148 CHECK_ERROR_BREAK (coll, GetItemAt (cmd.mIndex, flt.asOutParam()));
7149
7150 if (!f.mName.isNull())
7151 CHECK_ERROR_BREAK (flt, COMSETTER(Name) (f.mName.setNullIfEmpty()));
7152 if (!f.mActive.isNull())
7153 CHECK_ERROR_BREAK (flt, COMSETTER(Active) (f.mActive));
7154 if (!f.mVendorId.isNull())
7155 CHECK_ERROR_BREAK (flt, COMSETTER(VendorId) (f.mVendorId.setNullIfEmpty()));
7156 if (!f.mProductId.isNull())
7157 CHECK_ERROR_BREAK (flt, COMSETTER(ProductId) (f.mProductId.setNullIfEmpty()));
7158 if (!f.mRevision.isNull())
7159 CHECK_ERROR_BREAK (flt, COMSETTER(Revision) (f.mRevision.setNullIfEmpty()));
7160 if (!f.mManufacturer.isNull())
7161 CHECK_ERROR_BREAK (flt, COMSETTER(Manufacturer) (f.mManufacturer.setNullIfEmpty()));
7162 if (!f.mSerialNumber.isNull())
7163 CHECK_ERROR_BREAK (flt, COMSETTER(SerialNumber) (f.mSerialNumber.setNullIfEmpty()));
7164 if (!f.mMaskedInterfaces.isNull())
7165 CHECK_ERROR_BREAK (flt, COMSETTER(MaskedInterfaces) (f.mMaskedInterfaces));
7166
7167 if (f.mAction != USBDeviceFilterAction_Null)
7168 CHECK_ERROR_BREAK (flt, COMSETTER(Action) (f.mAction));
7169 }
7170 else
7171 {
7172 ComPtr <IUSBDeviceFilterCollection> coll;
7173 CHECK_ERROR_BREAK (ctl, COMGETTER(DeviceFilters) (coll.asOutParam()));
7174
7175 ComPtr <IUSBDeviceFilter> flt;
7176 CHECK_ERROR_BREAK (coll, GetItemAt (cmd.mIndex, flt.asOutParam()));
7177
7178 if (!f.mName.isNull())
7179 CHECK_ERROR_BREAK (flt, COMSETTER(Name) (f.mName.setNullIfEmpty()));
7180 if (!f.mActive.isNull())
7181 CHECK_ERROR_BREAK (flt, COMSETTER(Active) (f.mActive));
7182 if (!f.mVendorId.isNull())
7183 CHECK_ERROR_BREAK (flt, COMSETTER(VendorId) (f.mVendorId.setNullIfEmpty()));
7184 if (!f.mProductId.isNull())
7185 CHECK_ERROR_BREAK (flt, COMSETTER(ProductId) (f.mProductId.setNullIfEmpty()));
7186 if (!f.mRevision.isNull())
7187 CHECK_ERROR_BREAK (flt, COMSETTER(Revision) (f.mRevision.setNullIfEmpty()));
7188 if (!f.mManufacturer.isNull())
7189 CHECK_ERROR_BREAK (flt, COMSETTER(Manufacturer) (f.mManufacturer.setNullIfEmpty()));
7190 if (!f.mRemote.isNull())
7191 CHECK_ERROR_BREAK (flt, COMSETTER(Remote) (f.mRemote.setNullIfEmpty()));
7192 if (!f.mSerialNumber.isNull())
7193 CHECK_ERROR_BREAK (flt, COMSETTER(SerialNumber) (f.mSerialNumber.setNullIfEmpty()));
7194 if (!f.mMaskedInterfaces.isNull())
7195 CHECK_ERROR_BREAK (flt, COMSETTER(MaskedInterfaces) (f.mMaskedInterfaces));
7196 }
7197 break;
7198 }
7199 case USBFilterCmd::Remove:
7200 {
7201 if (cmd.mGlobal)
7202 {
7203 ComPtr <IHostUSBDeviceFilter> flt;
7204 CHECK_ERROR_BREAK (host, RemoveUSBDeviceFilter (cmd.mIndex, flt.asOutParam()));
7205 }
7206 else
7207 {
7208 ComPtr <IUSBDeviceFilter> flt;
7209 CHECK_ERROR_BREAK (ctl, RemoveDeviceFilter (cmd.mIndex, flt.asOutParam()));
7210 }
7211 break;
7212 }
7213 default:
7214 break;
7215 }
7216
7217 if (cmd.mMachine)
7218 {
7219 /* commit and close the session */
7220 CHECK_ERROR(cmd.mMachine, SaveSettings());
7221 aSession->Close();
7222 }
7223
7224 return SUCCEEDED (rc) ? 0 : 1;
7225}
7226
7227static int handleSharedFolder (int argc, char *argv[],
7228 ComPtr <IVirtualBox> aVirtualBox, ComPtr<ISession> aSession)
7229{
7230 HRESULT rc;
7231
7232 /* we need at least a command and target */
7233 if (argc < 2)
7234 return errorSyntax(USAGE_SHAREDFOLDER, "Not enough parameters");
7235
7236 ComPtr<IMachine> machine;
7237 /* assume it's a UUID */
7238 rc = aVirtualBox->GetMachine(Guid(argv[1]), machine.asOutParam());
7239 if (FAILED(rc) || !machine)
7240 {
7241 /* must be a name */
7242 CHECK_ERROR(aVirtualBox, FindMachine(Bstr(argv[1]), machine.asOutParam()));
7243 }
7244 if (!machine)
7245 return 1;
7246 Guid uuid;
7247 machine->COMGETTER(Id)(uuid.asOutParam());
7248
7249 if (strcmp(argv[0], "add") == 0)
7250 {
7251 /* we need at least four more parameters */
7252 if (argc < 5)
7253 return errorSyntax(USAGE_SHAREDFOLDER_ADD, "Not enough parameters");
7254
7255 char *name = NULL;
7256 char *hostpath = NULL;
7257 bool fTransient = false;
7258 bool fWritable = true;
7259
7260 for (int i = 2; i < argc; i++)
7261 {
7262 if (strcmp(argv[i], "-name") == 0)
7263 {
7264 if (argc <= i + 1 || !*argv[i+1])
7265 return errorArgument("Missing argument to '%s'", argv[i]);
7266 i++;
7267 name = argv[i];
7268 }
7269 else if (strcmp(argv[i], "-hostpath") == 0)
7270 {
7271 if (argc <= i + 1 || !*argv[i+1])
7272 return errorArgument("Missing argument to '%s'", argv[i]);
7273 i++;
7274 hostpath = argv[i];
7275 }
7276 else if (strcmp(argv[i], "-readonly") == 0)
7277 {
7278 fWritable = false;
7279 }
7280 else if (strcmp(argv[i], "-transient") == 0)
7281 {
7282 fTransient = true;
7283 }
7284 else
7285 return errorSyntax(USAGE_SHAREDFOLDER_ADD, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());
7286 }
7287
7288 if (NULL != strstr(name, " "))
7289 return errorSyntax(USAGE_SHAREDFOLDER_ADD, "No spaces allowed in parameter '-name'!");
7290
7291 /* required arguments */
7292 if (!name || !hostpath)
7293 {
7294 return errorSyntax(USAGE_SHAREDFOLDER_ADD, "Parameters -name and -hostpath are required");
7295 }
7296
7297 if (fTransient)
7298 {
7299 ComPtr <IConsole> console;
7300
7301 /* open an existing session for the VM */
7302 CHECK_ERROR_RET(aVirtualBox, OpenExistingSession (aSession, uuid), 1);
7303 /* get the session machine */
7304 CHECK_ERROR_RET(aSession, COMGETTER(Machine)(machine.asOutParam()), 1);
7305 /* get the session console */
7306 CHECK_ERROR_RET(aSession, COMGETTER(Console)(console.asOutParam()), 1);
7307
7308 CHECK_ERROR(console, CreateSharedFolder(Bstr(name), Bstr(hostpath), fWritable));
7309
7310 if (console)
7311 aSession->Close();
7312 }
7313 else
7314 {
7315 /* open a session for the VM */
7316 CHECK_ERROR_RET (aVirtualBox, OpenSession(aSession, uuid), 1);
7317
7318 /* get the mutable session machine */
7319 aSession->COMGETTER(Machine)(machine.asOutParam());
7320
7321 CHECK_ERROR(machine, CreateSharedFolder(Bstr(name), Bstr(hostpath), fWritable));
7322
7323 if (SUCCEEDED(rc))
7324 CHECK_ERROR(machine, SaveSettings());
7325
7326 aSession->Close();
7327 }
7328 }
7329 else if (strcmp(argv[0], "remove") == 0)
7330 {
7331 /* we need at least two more parameters */
7332 if (argc < 3)
7333 return errorSyntax(USAGE_SHAREDFOLDER_REMOVE, "Not enough parameters");
7334
7335 char *name = NULL;
7336 bool fTransient = false;
7337
7338 for (int i = 2; i < argc; i++)
7339 {
7340 if (strcmp(argv[i], "-name") == 0)
7341 {
7342 if (argc <= i + 1 || !*argv[i+1])
7343 return errorArgument("Missing argument to '%s'", argv[i]);
7344 i++;
7345 name = argv[i];
7346 }
7347 else if (strcmp(argv[i], "-transient") == 0)
7348 {
7349 fTransient = true;
7350 }
7351 else
7352 return errorSyntax(USAGE_SHAREDFOLDER_REMOVE, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());
7353 }
7354
7355 /* required arguments */
7356 if (!name)
7357 return errorSyntax(USAGE_SHAREDFOLDER_REMOVE, "Parameter -name is required");
7358
7359 if (fTransient)
7360 {
7361 ComPtr <IConsole> console;
7362
7363 /* open an existing session for the VM */
7364 CHECK_ERROR_RET(aVirtualBox, OpenExistingSession (aSession, uuid), 1);
7365 /* get the session machine */
7366 CHECK_ERROR_RET(aSession, COMGETTER(Machine)(machine.asOutParam()), 1);
7367 /* get the session console */
7368 CHECK_ERROR_RET(aSession, COMGETTER(Console)(console.asOutParam()), 1);
7369
7370 CHECK_ERROR(console, RemoveSharedFolder(Bstr(name)));
7371
7372 if (console)
7373 aSession->Close();
7374 }
7375 else
7376 {
7377 /* open a session for the VM */
7378 CHECK_ERROR_RET (aVirtualBox, OpenSession(aSession, uuid), 1);
7379
7380 /* get the mutable session machine */
7381 aSession->COMGETTER(Machine)(machine.asOutParam());
7382
7383 CHECK_ERROR(machine, RemoveSharedFolder(Bstr(name)));
7384
7385 /* commit and close the session */
7386 CHECK_ERROR(machine, SaveSettings());
7387 aSession->Close();
7388 }
7389 }
7390 else
7391 return errorSyntax(USAGE_SETPROPERTY, "Invalid parameter '%s'", Utf8Str(argv[0]).raw());
7392
7393 return 0;
7394}
7395
7396static int handleVMStatistics(int argc, char *argv[],
7397 ComPtr<IVirtualBox> aVirtualBox, ComPtr<ISession> aSession)
7398{
7399 HRESULT rc;
7400
7401 /* at least one option: the UUID or name of the VM */
7402 if (argc < 1)
7403 return errorSyntax(USAGE_VM_STATISTICS, "Incorrect number of parameters");
7404
7405 /* try to find the given machine */
7406 ComPtr <IMachine> machine;
7407 Guid uuid (argv[0]);
7408 if (!uuid.isEmpty())
7409 CHECK_ERROR(aVirtualBox, GetMachine(uuid, machine.asOutParam()));
7410 else
7411 {
7412 CHECK_ERROR(aVirtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam()));
7413 if (SUCCEEDED (rc))
7414 machine->COMGETTER(Id)(uuid.asOutParam());
7415 }
7416 if (FAILED(rc))
7417 return 1;
7418
7419 /* parse arguments. */
7420 bool fReset = false;
7421 bool fWithDescriptions = false;
7422 const char *pszPattern = NULL; /* all */
7423 for (int i = 1; i < argc; i++)
7424 {
7425 if (!strcmp(argv[i], "-pattern"))
7426 {
7427 if (pszPattern)
7428 return errorSyntax(USAGE_VM_STATISTICS, "Multiple -patterns options is not permitted");
7429 if (i + 1 >= argc)
7430 return errorArgument("Missing argument to '%s'", argv[i]);
7431 pszPattern = argv[++i];
7432 }
7433 else if (!strcmp(argv[i], "-descriptions"))
7434 fWithDescriptions = true;
7435 /* add: -file <filename> and -formatted */
7436 else if (!strcmp(argv[i], "-reset"))
7437 fReset = true;
7438 else
7439 return errorSyntax(USAGE_VM_STATISTICS, "Unknown option '%s'", argv[i]);
7440 }
7441 if (fReset && fWithDescriptions)
7442 return errorSyntax(USAGE_VM_STATISTICS, "The -reset and -descriptions options does not mix");
7443
7444
7445 /* open an existing session for the VM. */
7446 CHECK_ERROR(aVirtualBox, OpenExistingSession(aSession, uuid));
7447 if (SUCCEEDED(rc))
7448 {
7449 /* get the session console. */
7450 ComPtr <IConsole> console;
7451 CHECK_ERROR(aSession, COMGETTER(Console)(console.asOutParam()));
7452 if (SUCCEEDED(rc))
7453 {
7454 /* get the machine debugger. */
7455 ComPtr <IMachineDebugger> debugger;
7456 CHECK_ERROR(console, COMGETTER(Debugger)(debugger.asOutParam()));
7457 if (SUCCEEDED(rc))
7458 {
7459 if (fReset)
7460 CHECK_ERROR(debugger, ResetStats(Bstr(pszPattern).raw()));
7461 else
7462 {
7463 Bstr stats;
7464 CHECK_ERROR(debugger, GetStats(Bstr(pszPattern).raw(), fWithDescriptions, stats.asOutParam()));
7465 if (SUCCEEDED(rc))
7466 {
7467 /* if (fFormatted)
7468 { big mess }
7469 else
7470 */
7471 RTPrintf("%ls\n", stats.raw());
7472 }
7473 }
7474 }
7475 aSession->Close();
7476 }
7477 }
7478
7479 return SUCCEEDED(rc) ? 0 : 1;
7480}
7481
7482#ifdef VBOX_WITH_INFO_SVC
7483static int handleGetGuestProperty(int argc, char *argv[],
7484 ComPtr<IVirtualBox> virtualBox,
7485 ComPtr<ISession> session)
7486{
7487 HRESULT rc = S_OK;
7488
7489 if (argc != 2)
7490 return errorSyntax(USAGE_GETGUESTPROPERTY, "Incorrect number of parameters");
7491
7492 ComPtr<IMachine> machine;
7493 /* assume it's a UUID */
7494 rc = virtualBox->GetMachine(Guid(argv[0]), machine.asOutParam());
7495 if (FAILED(rc) || !machine)
7496 {
7497 /* must be a name */
7498 CHECK_ERROR(virtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam()));
7499 }
7500 if (machine)
7501 {
7502 Bstr value;
7503 CHECK_ERROR(machine, GetGuestProperty(Bstr(argv[1]), value.asOutParam()));
7504 if (value)
7505 RTPrintf("Value: %lS\n", value.raw());
7506 else
7507 RTPrintf("No value set!\n");
7508 }
7509 return SUCCEEDED(rc) ? 0 : 1;
7510}
7511
7512static int handleSetGuestProperty(int argc, char *argv[],
7513 ComPtr<IVirtualBox> virtualBox,
7514 ComPtr<ISession> session)
7515{
7516 HRESULT rc = S_OK;
7517
7518 if (argc < 2)
7519 return errorSyntax(USAGE_SETGUESTPROPERTY, "Not enough parameters");
7520
7521 ComPtr<IMachine> machine;
7522 /* assume it's a UUID */
7523 rc = virtualBox->GetMachine(Guid(argv[0]), machine.asOutParam());
7524 if (FAILED(rc) || !machine)
7525 {
7526 /* must be a name */
7527 CHECK_ERROR(virtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam()));
7528 }
7529 if (machine)
7530 {
7531 if (argc < 3)
7532 CHECK_ERROR(machine, SetGuestProperty(Bstr(argv[1]), NULL));
7533 else if (argc == 3)
7534 CHECK_ERROR(machine, SetGuestProperty(Bstr(argv[1]), Bstr(argv[2])));
7535 else
7536 return errorSyntax(USAGE_SETGUESTPROPERTY, "Too many parameters");
7537 }
7538 return SUCCEEDED(rc) ? 0 : 1;
7539}
7540#endif /* VBOX_WITH_INFO_SVC defined */
7541
7542enum ConvertSettings
7543{
7544 ConvertSettings_No = 0,
7545 ConvertSettings_Yes = 1,
7546 ConvertSettings_Backup = 2,
7547 ConvertSettings_Ignore = 3,
7548};
7549
7550/**
7551 * Checks if any of the settings files were auto-converted and informs the
7552 * user if so.
7553 *
7554 * @return @false if the program should terminate and @true otherwise.
7555 */
7556static bool checkForAutoConvertedSettings (ComPtr<IVirtualBox> virtualBox,
7557 ComPtr<ISession> session,
7558 ConvertSettings fConvertSettings)
7559{
7560 /* return early if nothing to do */
7561 if (fConvertSettings == ConvertSettings_Ignore)
7562 return true;
7563
7564 HRESULT rc;
7565
7566 do
7567 {
7568 Bstr formatVersion;
7569 CHECK_RC_BREAK (virtualBox->
7570 COMGETTER(SettingsFormatVersion) (formatVersion.asOutParam()));
7571
7572 bool isGlobalConverted = false;
7573 std::list <ComPtr <IMachine> > cvtMachines;
7574 std::list <Utf8Str> fileList;
7575 Bstr version;
7576 Bstr filePath;
7577
7578 com::SafeIfaceArray <IMachine> machines;
7579 CHECK_RC_BREAK (virtualBox->
7580 COMGETTER(Machines2) (ComSafeArrayAsOutParam (machines)));
7581
7582 for (size_t i = 0; i < machines.size(); ++ i)
7583 {
7584 BOOL accessible;
7585 CHECK_RC_BREAK (machines [i]->
7586 COMGETTER(Accessible) (&accessible));
7587 if (!accessible)
7588 continue;
7589
7590 CHECK_RC_BREAK (machines [i]->
7591 COMGETTER(SettingsFileVersion) (version.asOutParam()));
7592
7593 if (version != formatVersion)
7594 {
7595 cvtMachines.push_back (machines [i]);
7596 Bstr filePath;
7597 CHECK_RC_BREAK (machines [i]->
7598 COMGETTER(SettingsFilePath) (filePath.asOutParam()));
7599 fileList.push_back (Utf8StrFmt ("%ls (%ls)", filePath.raw(),
7600 version.raw()));
7601 }
7602 }
7603
7604 CHECK_RC_BREAK (rc);
7605
7606 CHECK_RC_BREAK (virtualBox->
7607 COMGETTER(SettingsFileVersion) (version.asOutParam()));
7608 if (version != formatVersion)
7609 {
7610 isGlobalConverted = true;
7611 CHECK_RC_BREAK (virtualBox->
7612 COMGETTER(SettingsFilePath) (filePath.asOutParam()));
7613 fileList.push_back (Utf8StrFmt ("%ls (%ls)", filePath.raw(),
7614 version.raw()));
7615 }
7616
7617 if (fileList.size() > 0)
7618 {
7619 switch (fConvertSettings)
7620 {
7621 case ConvertSettings_No:
7622 {
7623 RTPrintf (
7624"WARNING! The following VirtualBox settings files have been automatically\n"
7625"converted to the new settings file format version '%ls':\n"
7626"\n",
7627 formatVersion.raw());
7628
7629 for (std::list <Utf8Str>::const_iterator f = fileList.begin();
7630 f != fileList.end(); ++ f)
7631 RTPrintf (" %S\n", (*f).raw());
7632 RTPrintf (
7633"\n"
7634"The current command was aborted to prevent overwriting the above settings\n"
7635"files with the results of the auto-conversion without your permission.\n"
7636"Please put one of the following command line switches to the beginning of\n"
7637"the VBoxManage command line and repeat the command:\n"
7638"\n"
7639" -convertSettings - to save all auto-converted files (it will not\n"
7640" be possible to use these settings files with an\n"
7641" older version of VirtualBox in the future);\n"
7642" -convertSettingsBackup - to create backup copies of the settings files in\n"
7643" the old format before saving them in the new format;\n"
7644" -convertSettingsIgnore - to not save the auto-converted settings files.\n"
7645"\n"
7646"Note that if you use -convertSettingsIgnore, the auto-converted settings files\n"
7647"will be implicitly saved in the new format anyway once you change a setting or\n"
7648"start a virtual machine, but NO backup copies will be created in this case.\n");
7649 return false;
7650 }
7651 case ConvertSettings_Yes:
7652 case ConvertSettings_Backup:
7653 {
7654 break;
7655 }
7656 default:
7657 AssertFailedReturn (false);
7658 }
7659
7660 for (std::list <ComPtr <IMachine> >::const_iterator m = cvtMachines.begin();
7661 m != cvtMachines.end(); ++ m)
7662 {
7663 Guid id;
7664 CHECK_RC_BREAK ((*m)->COMGETTER(Id) (id.asOutParam()));
7665
7666 /* open a session for the VM */
7667 CHECK_ERROR_BREAK (virtualBox, OpenSession (session, id));
7668
7669 ComPtr <IMachine> sm;
7670 CHECK_RC_BREAK (session->COMGETTER(Machine) (sm.asOutParam()));
7671
7672 Bstr bakFileName;
7673 if (fConvertSettings == ConvertSettings_Backup)
7674 CHECK_ERROR (sm, SaveSettingsWithBackup (bakFileName.asOutParam()));
7675 else
7676 CHECK_ERROR (sm, SaveSettings());
7677
7678 session->Close();
7679
7680 CHECK_RC_BREAK (rc);
7681 }
7682
7683 CHECK_RC_BREAK (rc);
7684
7685 if (isGlobalConverted)
7686 {
7687 Bstr bakFileName;
7688 if (fConvertSettings == ConvertSettings_Backup)
7689 CHECK_ERROR (virtualBox, SaveSettingsWithBackup (bakFileName.asOutParam()));
7690 else
7691 CHECK_ERROR (virtualBox, SaveSettings());
7692 }
7693
7694 CHECK_RC_BREAK (rc);
7695 }
7696 }
7697 while (0);
7698
7699 return SUCCEEDED (rc);
7700}
7701
7702// main
7703///////////////////////////////////////////////////////////////////////////////
7704
7705int main(int argc, char *argv[])
7706{
7707 /*
7708 * Before we do anything, init the runtime without loading
7709 * the support driver.
7710 */
7711 RTR3Init(false);
7712
7713 bool fShowLogo = true;
7714 int iCmd = 1;
7715 int iCmdArg;
7716
7717 ConvertSettings fConvertSettings = ConvertSettings_No;
7718
7719 /* global options */
7720 for (int i = 1; i < argc || argc <= iCmd; i++)
7721 {
7722 if ( argc <= iCmd
7723 || (strcmp(argv[i], "help") == 0)
7724 || (strcmp(argv[i], "-?") == 0)
7725 || (strcmp(argv[i], "-h") == 0)
7726 || (strcmp(argv[i], "-help") == 0)
7727 || (strcmp(argv[i], "--help") == 0))
7728 {
7729 showLogo();
7730 printUsage(USAGE_ALL);
7731 return 0;
7732 }
7733 else if ( strcmp(argv[i], "-v") == 0
7734 || strcmp(argv[i], "-version") == 0
7735 || strcmp(argv[i], "-Version") == 0
7736 || strcmp(argv[i], "--version") == 0)
7737 {
7738 /* Print version number, and do nothing else. */
7739 RTPrintf("%sr%d\n", VBOX_VERSION_STRING, VBoxSVNRev ());
7740 exit(0);
7741 }
7742 else if (strcmp(argv[i], "-dumpopts") == 0)
7743 {
7744 /* Special option to dump really all commands,
7745 * even the ones not understood on this platform. */
7746 printUsage(USAGE_DUMPOPTS);
7747 return 0;
7748 }
7749 else if (strcmp(argv[i], "-nologo") == 0)
7750 {
7751 /* suppress the logo */
7752 fShowLogo = false;
7753 iCmd++;
7754 }
7755 else if (strcmp(argv[i], "-convertSettings") == 0)
7756 {
7757 fConvertSettings = ConvertSettings_Yes;
7758 iCmd++;
7759 }
7760 else if (strcmp(argv[i], "-convertSettingsBackup") == 0)
7761 {
7762 fConvertSettings = ConvertSettings_Backup;
7763 iCmd++;
7764 }
7765 else if (strcmp(argv[i], "-convertSettingsIgnore") == 0)
7766 {
7767 fConvertSettings = ConvertSettings_Ignore;
7768 iCmd++;
7769 }
7770 else
7771 {
7772 break;
7773 }
7774 }
7775
7776 iCmdArg = iCmd + 1;
7777
7778 if (fShowLogo)
7779 showLogo();
7780
7781 HRESULT rc;
7782
7783 CHECK_RC_RET (com::Initialize());
7784
7785 /*
7786 * The input is in the host OS'es codepage (NT guarantees ACP).
7787 * For VBox we use UTF-8 and convert to UCS-2 when calling (XP)COM APIs.
7788 * For simplicity, just convert the argv[] array here.
7789 */
7790 for (int i = iCmdArg; i < argc; i++)
7791 {
7792 char *converted;
7793 RTStrCurrentCPToUtf8(&converted, argv[i]);
7794 argv[i] = converted;
7795 }
7796
7797 do
7798 {
7799 // scopes all the stuff till shutdown
7800 ////////////////////////////////////////////////////////////////////////////
7801
7802 /* convertdd: does not need a VirtualBox instantiation) */
7803 if (argc >= iCmdArg && (strcmp(argv[iCmd], "convertdd") == 0))
7804 {
7805 rc = handleConvertDDImage(argc - iCmdArg, argv + iCmdArg);
7806 break;
7807 }
7808
7809 ComPtr <IVirtualBox> virtualBox;
7810 ComPtr <ISession> session;
7811
7812 rc = virtualBox.createLocalObject (CLSID_VirtualBox);
7813 if (FAILED(rc))
7814 {
7815 RTPrintf ("[!] Failed to create the VirtualBox object!\n");
7816 PRINT_RC_MESSAGE (rc);
7817
7818 com::ErrorInfo info;
7819 if (!info.isFullAvailable() && !info.isBasicAvailable())
7820 RTPrintf ("[!] Most likely, the VirtualBox COM server is not running "
7821 "or failed to start.\n");
7822 else
7823 PRINT_ERROR_INFO (info);
7824 break;
7825 }
7826
7827 CHECK_RC_BREAK (session.createInprocObject (CLSID_Session));
7828
7829 /* create the event queue
7830 * (here it is necessary only to process remaining XPCOM/IPC events
7831 * after the session is closed) */
7832
7833 EventQueue eventQ;
7834
7835 if (!checkForAutoConvertedSettings (virtualBox, session, fConvertSettings))
7836 break;
7837
7838 /*
7839 * All registered command handlers
7840 */
7841 struct
7842 {
7843 const char *command;
7844 PFNHANDLER handler;
7845 } commandHandlers[] =
7846 {
7847 { "internalcommands", handleInternalCommands },
7848 { "list", handleList },
7849 { "showvminfo", handleShowVMInfo },
7850 { "registervm", handleRegisterVM },
7851 { "unregistervm", handleUnregisterVM },
7852 { "createvdi", handleCreateVDI },
7853 { "modifyvdi", handleModifyVDI },
7854 { "addiscsidisk", handleAddiSCSIDisk },
7855 { "createvm", handleCreateVM },
7856 { "modifyvm", handleModifyVM },
7857 { "clonevdi", handleCloneVDI },
7858 { "startvm", handleStartVM },
7859 { "controlvm", handleControlVM },
7860 { "discardstate", handleDiscardState },
7861 { "adoptstate", handleAdoptdState },
7862 { "snapshot", handleSnapshot },
7863 { "registerimage", handleRegisterImage },
7864 { "unregisterimage", handleUnregisterImage },
7865 { "showvdiinfo", handleShowVDIInfo },
7866#ifdef RT_OS_WINDOWS
7867 { "createhostif", handleCreateHostIF },
7868 { "removehostif", handleRemoveHostIF },
7869#endif
7870 { "getextradata", handleGetExtraData },
7871 { "setextradata", handleSetExtraData },
7872 { "setproperty", handleSetProperty },
7873 { "usbfilter", handleUSBFilter },
7874 { "sharedfolder", handleSharedFolder },
7875 { "vmstatistics", handleVMStatistics },
7876#ifdef VBOX_WITH_INFO_SVC
7877 { "getguestproperty", handleGetGuestProperty },
7878 { "setguestproperty", handleSetGuestProperty },
7879#endif /* VBOX_WITH_INFO_SVC defined */
7880 { NULL, NULL }
7881 };
7882
7883 int commandIndex;
7884 for (commandIndex = 0; commandHandlers[commandIndex].command != NULL; commandIndex++)
7885 {
7886 if (strcmp(commandHandlers[commandIndex].command, argv[iCmd]) == 0)
7887 {
7888 rc = commandHandlers[commandIndex].handler(argc - iCmdArg, &argv[iCmdArg], virtualBox, session);
7889 break;
7890 }
7891 }
7892 if (!commandHandlers[commandIndex].command)
7893 {
7894 rc = errorSyntax(USAGE_ALL, "Invalid command '%s'", Utf8Str(argv[iCmd]).raw());
7895 }
7896
7897 /* Although all handlers should always close the session if they open it,
7898 * we do it here just in case if some of the handlers contains a bug --
7899 * leaving the direct session not closed will turn the machine state to
7900 * Aborted which may have unwanted side effects like killing the saved
7901 * state file (if the machine was in the Saved state before). */
7902 session->Close();
7903
7904 // end "all-stuff" scope
7905 ////////////////////////////////////////////////////////////////////////////
7906 }
7907 while (0);
7908
7909 com::Shutdown();
7910
7911 /*
7912 * Free converted argument vector
7913 */
7914 for (int i = iCmdArg; i < argc; i++)
7915 RTStrFree(argv[i]);
7916
7917 return rc;
7918}
Note: See TracBrowser for help on using the repository browser.

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