VirtualBox

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

Last change on this file since 10557 was 10427, checked in by vboxsync, 17 years ago

This needs to be adjusted as well of course..

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

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