VirtualBox

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

Last change on this file since 1061 was 1061, checked in by vboxsync, 18 years ago

corrected syntax diagram

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 205.0 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 InnoTek Systemberatung GmbH
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 as published by the Free Software Foundation,
16 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
17 * distribution. VirtualBox OSE is distributed in the hope that it will
18 * be useful, but WITHOUT ANY WARRANTY of any kind.
19 *
20 * If you received this file as part of a commercial VirtualBox
21 * distribution, then only the terms of your commercial VirtualBox
22 * license agreement apply instead of the previous paragraph.
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/ErrorInfo.h>
34#include <VBox/com/EventQueue.h>
35
36#include <VBox/com/VirtualBox.h>
37
38#define CFGLDR_HAVE_COM
39#include <VBox/cfgldr.h>
40
41#include <stdlib.h>
42#include <stdarg.h>
43
44#include <vector>
45
46#include <iprt/runtime.h>
47#include <iprt/stream.h>
48#include <iprt/string.h>
49#include <iprt/asm.h>
50#include <iprt/uuid.h>
51#include <iprt/thread.h>
52#include <iprt/path.h>
53#include <iprt/param.h>
54#include <iprt/dir.h>
55#include <iprt/file.h>
56#include <VBox/err.h>
57#include <VBox/version.h>
58#include <VBox/VBoxHDD.h>
59
60#include "VBoxManage.h"
61
62using namespace com;
63
64/* missing XPCOM <-> COM wrappers */
65#ifndef STDMETHOD_
66# define STDMETHOD_(ret, meth) NS_IMETHOD_(ret) meth
67#endif
68#ifndef NS_GET_IID
69# define NS_GET_IID(I) IID_##I
70#endif
71#ifndef __WIN__
72#define IUnknown nsISupports
73#endif
74
75/** command handler type */
76typedef DECLCALLBACK(int) FNHANDLER(int argc, char *argv[], ComPtr<IVirtualBox> aVirtualBox, ComPtr<ISession> aSession);
77typedef FNHANDLER *PFNHANDLER;
78
79/**
80 * Quick IUSBDevice implementation for detaching / attaching
81 * devices to the USB Controller.
82 */
83class MyUSBDevice : public IUSBDevice
84{
85public:
86 // public initializer/uninitializer for internal purposes only
87 MyUSBDevice(uint16_t a_u16VendorId, uint16_t a_u16ProductId, uint16_t a_bcdRevision, uint64_t a_u64SerialHash, const char *a_pszComment)
88 : m_usVendorId(a_u16VendorId), m_usProductId(a_u16ProductId),
89 m_bcdRevision(a_bcdRevision), m_u64SerialHash(a_u64SerialHash),
90 m_bstrComment(a_pszComment),
91 m_cRefs(0)
92 {
93 }
94
95 STDMETHOD_(ULONG, AddRef)(void)
96 {
97 return ASMAtomicIncU32(&m_cRefs);
98 }
99 STDMETHOD_(ULONG, Release)(void)
100 {
101 ULONG cRefs = ASMAtomicDecU32(&m_cRefs);
102 if (!cRefs)
103 delete this;
104 return cRefs;
105 }
106 STDMETHOD(QueryInterface)(const IID &iid, void **ppvObject)
107 {
108 Guid guid(iid);
109 if (guid == Guid(NS_GET_IID(IUnknown)))
110 *ppvObject = (IUnknown *)this;
111 else if (guid == Guid(NS_GET_IID(IUSBDevice)))
112 *ppvObject = (IUSBDevice *)this;
113 else
114 return E_NOINTERFACE;
115 AddRef();
116 return S_OK;
117 }
118
119 STDMETHOD(COMGETTER(Id))(GUIDPARAMOUT a_pId) { return E_NOTIMPL; }
120 STDMETHOD(COMGETTER(VendorId))(USHORT *a_pusVendorId) { *a_pusVendorId = m_usVendorId; return S_OK; }
121 STDMETHOD(COMGETTER(ProductId))(USHORT *a_pusProductId) { *a_pusProductId = m_usProductId; return S_OK; }
122 STDMETHOD(COMGETTER(Revision))(USHORT *a_pusRevision) { *a_pusRevision = m_bcdRevision; return S_OK; }
123 STDMETHOD(COMGETTER(SerialHash))(ULONG64 *a_pullSerialHash) { *a_pullSerialHash = m_u64SerialHash; return S_OK; }
124 STDMETHOD(COMGETTER(Manufacturer))(BSTR *a_pManufacturer) { return E_NOTIMPL; }
125 STDMETHOD(COMGETTER(Product))(BSTR *a_pProduct) { return E_NOTIMPL; }
126 STDMETHOD(COMGETTER(SerialNumber))(BSTR *a_pSerialNumber) { return E_NOTIMPL; }
127 STDMETHOD(COMGETTER(Address))(BSTR *a_pAddress) { return E_NOTIMPL; }
128
129private:
130 /** The vendor id of this USB device. */
131 USHORT m_usVendorId;
132 /** The product id of this USB device. */
133 USHORT m_usProductId;
134 /** The product revision number of this USB device.
135 * (high byte = integer; low byte = decimal) */
136 USHORT m_bcdRevision;
137 /** The USB serial hash of the device. */
138 uint64_t m_u64SerialHash;
139 /** The user comment string. */
140 Bstr m_bstrComment;
141 /** Reference counter. */
142 uint32_t volatile m_cRefs;
143};
144
145
146// types
147///////////////////////////////////////////////////////////////////////////////
148
149template <typename T>
150class Nullable
151{
152public:
153
154 Nullable() : mIsNull (true) {}
155 Nullable (const T &aValue, bool aIsNull = false)
156 : mIsNull (aIsNull), mValue (aValue) {}
157
158 bool isNull() const { return mIsNull; };
159 void setNull (bool aIsNull = true) { mIsNull = aIsNull; }
160
161 operator const T&() const { return mValue; }
162
163 Nullable &operator= (const T &aValue)
164 {
165 mValue = aValue;
166 mIsNull = false;
167 return *this;
168 }
169
170private:
171
172 bool mIsNull;
173 T mValue;
174};
175
176/** helper structure to encapsulate USB filter manipulation commands */
177struct USBFilterCmd
178{
179 struct USBFilter
180 {
181 USBFilter ()
182 : mAction (USBDeviceFilterAction_InvalidUSBDeviceFilterAction)
183 {}
184
185 Bstr mName;
186 Nullable <bool> mActive;
187 Bstr mVendorId;
188 Bstr mProductId;
189 Bstr mRevision;
190 Bstr mManufacturer;
191 Bstr mProduct;
192 Bstr mRemote;
193 Bstr mSerialNumber;
194 USBDeviceFilterAction_T mAction;
195 };
196
197 enum Action { Invalid, Add, Modify, Remove };
198
199 USBFilterCmd() : mAction (Invalid), mIndex (0), mGlobal (false) {}
200
201 Action mAction;
202 ULONG mIndex;
203 /** flag whether the command target is a global filter */
204 bool mGlobal;
205 /** machine this command is targeted at (null for global filters) */
206 ComPtr<IMachine> mMachine;
207 USBFilter mFilter;
208};
209
210// funcs
211///////////////////////////////////////////////////////////////////////////////
212
213static void printUsage(USAGECATEGORY enmCmd)
214{
215#ifdef __LINUX__
216 bool fLinux = true;
217#else
218 bool fLinux = false;
219#endif
220#ifdef __WIN__
221 bool fWin = true;
222#else
223 bool fWin = false;
224#endif
225#ifdef VBOX_VRDP
226 bool fVRDP = true;
227#else
228 bool fVRDP = false;
229#endif
230
231 if (enmCmd == USAGE_DUMPOPTS)
232 {
233 fLinux = true;
234 fWin = true;
235 fVRDP = true;
236 enmCmd = USAGE_ALL;
237 }
238
239 RTPrintf("Usage:\n"
240 "\n");
241
242 if (enmCmd & USAGE_LIST)
243 {
244 RTPrintf("VBoxManage list vms|ostypes|hostdvds|hostfloppies|");
245 if (fWin)
246 RTPrintf( "hostifs|");
247 RTPrintf( "\n"
248 " hdds|dvds|floppies|usbhost|usbfilters|\n"
249 " systemproperties\n"
250 "\n");
251 }
252
253 if (enmCmd & USAGE_SHOWVMINFO)
254 {
255 RTPrintf("VBoxManage showvminfo <uuid>|<name>\n"
256 "\n");
257 }
258
259 if (enmCmd & USAGE_REGISTERVM)
260 {
261 RTPrintf("VBoxManage registervm <filename>\n"
262 "\n");
263 }
264
265 if (enmCmd & USAGE_UNREGISTERVM)
266 {
267 RTPrintf("VBoxManage unregistervm <uuid>|<name>\n"
268 " [-delete]\n"
269 "\n");
270 }
271
272 if (enmCmd & USAGE_CREATEVM)
273 {
274 RTPrintf("VBoxManage createvm -name <name>\n"
275 " [-register]\n"
276 " [-basefolder <path> | -settingsfile <path>]\n"
277 " \n"
278 "\n");
279 }
280
281 if (enmCmd & USAGE_MODIFYVM)
282 {
283 RTPrintf("VBoxManage modifyvm <uuid|name>\n"
284 " [-name <name>]\n"
285 " [-ostype <ostype>]\n"
286 " [-memory <memorysize>]\n"
287 " [-vram <vramsize>]\n"
288 " [-acpi on|off]\n"
289 " [-ioapic on|off]\n"
290 " [-hwvirtex on|off|default]\n"
291 " [-bioslogofadein on|off]\n"
292 " [-bioslogofadeout on|off]\n"
293 " [-bioslogodisplaytime <msec>]\n"
294 " [-bioslogoimagepath <imagepath>]\n"
295 " [-biosbootmenu <disabled|menuonly|messageandmenu>]\n"
296 " [-boot<1-4> none|floppy|dvd|disk|net>]\n"
297 " [-hd<a|b|d> none|<uuid>|<filename>]\n"
298 " [-dvd none|<uuid>|<filename>|host:<drive>]\n"
299 " [-dvdpassthrough on|off]\n"
300 " [-floppy disabled|empty|<uuid>|\n"
301 " <filename>|host:<drive>]\n"
302 " [-nic<1-N> none|null|nat|hostif|intnet]\n"
303 " [-nictype<1-N> Am79C970A|Am79C973]\n"
304 " [-cableconnected<1-N> on|off]\n"
305 " [-nictrace<1-N> on|off]\n"
306 " [-nictracefile<1-N> <filename>]\n"
307 " [-hostifdev<1-N> none|<devicename>]\n"
308 " [-intnet<1-N> network]\n"
309 " [-macaddress<1-N> auto|<mac>\n");
310 if (fLinux)
311 {
312 RTPrintf(" [-tapsetup<1-N> none|<application>]\n"
313 " [-tapterminate<1-N> none|<application>]\n");
314 }
315 RTPrintf(" [-audio none|null");
316 if (fLinux)
317 {
318 RTPrintf( "|oss"
319#ifdef VBOX_WITH_ALSA
320 "|alsa"
321#endif
322 );
323 }
324 if (fWin)
325 {
326 RTPrintf( "|winmm|dsound");
327 }
328 RTPrintf( "]\n");
329 if (fVRDP)
330 {
331 RTPrintf(" [-vrdp on|off]\n"
332 " [-vrdpport default|<port>]\n"
333 " [-vrdpauthtype null|external|guest]\n");
334 }
335 RTPrintf(" [-usb on|off]\n"
336 " [-snapshotfolder default|<path>]\n"
337 "\n");
338 }
339
340 if (enmCmd & USAGE_STARTVM)
341 {
342 RTPrintf("VBoxManage startvm <uuid>|<name>\n"
343 " [-type gui|vrdp]\n"
344 "\n");
345 }
346
347 if (enmCmd & USAGE_CONTROLVM)
348 {
349 RTPrintf("VBoxManage controlvm <uuid>|<name>\n"
350 " pause|resume|reset|poweroff|savestate|\n"
351 " acpipowerbutton |\n"
352 " setlinkstate<1-4> on|off |\n"
353 " usbattach <uuid>|<address> |\n"
354 " usbdetach <uuid>|<address> |\n"
355 " dvdattach none|<uuid>|<filename>|host:<drive> |\n"
356 " floppyattach none|<uuid>|<filename>|host:<drive> |\n"
357 " setvideomodehint <xres> <yres> <bpp> |\n"
358 " setcredentials <username> <password> <domain>\n"
359 " [-allowlocallogon <yes|no>]\n"
360 "\n");
361 }
362
363 if (enmCmd & USAGE_DISCARDSTATE)
364 {
365 RTPrintf("VBoxManage discardstate <uuid>|<name>\n"
366 "\n");
367 }
368
369 if (enmCmd & USAGE_SNAPSHOT)
370 {
371 RTPrintf("VBoxManage snapshot <uuid>|<name>\n"
372 " take <name> [-desc <desc>] |\n"
373 " discard <uuid>|<name> |\n"
374 " discardcurrent -state|-all |\n"
375 " edit <uuid>|<name>|-current\n"
376 " [-newname <name>]\n"
377 " [-newdesc <desc>] |\n"
378 " showvminfo <uuid>|<name>\n"
379 "\n");
380 }
381
382 if (enmCmd & USAGE_REGISTERIMAGE)
383 {
384 RTPrintf("VBoxManage registerimage disk|dvd|floppy <filename>\n"
385 " [-type normal|immutable|writethrough] (disk only)\n"
386 "\n");
387 }
388
389 if (enmCmd & USAGE_UNREGISTERIMAGE)
390 {
391 RTPrintf("VBoxManage unregisterimage disk|dvd|floppy <uuid>|<filename>\n"
392 "\n");
393 }
394
395 if (enmCmd & USAGE_SHOWVDIINFO)
396 {
397 RTPrintf("VBoxManage showvdiinfo <uuid>|<filename>\n"
398 "\n");
399 }
400
401 if (enmCmd & USAGE_CREATEVDI)
402 {
403 RTPrintf("VBoxManage createvdi -filename <filename>\n"
404 " -size <megabytes>\n"
405 " [-static]\n"
406 " [-comment <comment>]\n"
407 " [-register]\n"
408 " [-type normal|writethrough] (default: normal)\n"
409 "\n");
410 }
411
412 if (enmCmd & USAGE_MODIFYVDI)
413 {
414 RTPrintf("VBoxManage modifyvdi <uuid>|<filename>\n"
415#if 0 /* doesn't currently work */
416 " settype normal|writethrough|immutable |\n"
417#endif
418 " compact\n"
419 "\n");
420 }
421
422 if (enmCmd & USAGE_CLONEVDI)
423 {
424 RTPrintf("VBoxManage clonevdi <uuid>|<filename> <outputfile>\n"
425 "\n");
426 }
427
428 if (enmCmd & USAGE_ADDISCSIDISK)
429 {
430 RTPrintf("VBoxManage addiscsidisk -server <name>|<ip>\n"
431 " -target <target>\n"
432 " [-port <port>]\n"
433 " [-lun <lun>]\n"
434 " [-encodedlun <lun>]\n"
435 " [-username <username>]\n"
436 " [-password <password>]\n"
437 " [-comment <comment>]\n"
438 "\n");
439 }
440
441 if (enmCmd & USAGE_CREATEHOSTIF && fWin)
442 {
443 RTPrintf("VBoxManage createhostif <name>\n"
444 "\n");
445 }
446
447 if (enmCmd & USAGE_REMOVEHOSTIF && fWin)
448 {
449 RTPrintf("VBoxManage removehostif <uuid>|<name>\n"
450 "\n");
451 }
452
453 if (enmCmd & USAGE_GETEXTRADATA)
454 {
455 RTPrintf("VBoxManage getextradata global|<uuid>|<name>\n"
456 " <key>|enumerate\n"
457 "\n");
458 }
459
460 if (enmCmd & USAGE_SETEXTRADATA)
461 {
462 RTPrintf("VBoxManage setextradata global|<uuid>|<name>\n"
463 " <key>\n"
464 " [<value>] (no value deletes key)\n"
465 "\n");
466 }
467
468 if (enmCmd & USAGE_SETPROPERTY)
469 {
470 RTPrintf("VBoxManage setproperty vdifolder default|<folder> |\n"
471 " machinefolder default|<folder> |\n"
472 " vrdpauthlibrary default|<library> |\n"
473 " hwvirtexenabled yes|no\n"
474 "\n");
475 }
476
477 if (enmCmd & USAGE_USBFILTER_ADD)
478 {
479 RTPrintf("VBoxManage usbfilter add <index,0-N>\n"
480 " -target <uuid>|<name>|global\n"
481 " -name <string>\n"
482 " -action ignore|hold (global filters only)\n"
483 " [-active yes|no] (yes)\n"
484 " [-vendorid <XXXX>] (null)\n"
485 " [-productid <XXXX>] (null)\n"
486 " [-revision <IIFF>] (null)\n"
487 " [-manufacturer <string>] (null)\n"
488 " [-product <string>] (null)\n"
489 " [-remote yes|no] (null, VM filters only)\n"
490 " [-serialnumber <string>] (null)\n"
491 "\n");
492 }
493
494 if (enmCmd & USAGE_USBFILTER_MODIFY)
495 {
496 RTPrintf("VBoxManage usbfilter modify <index,0-N>\n"
497 " -target <uuid>|<name>|global\n"
498 " [-name <string>]\n"
499 " [-action ignore|hold] (global filters only)\n"
500 " [-active yes|no]\n"
501 " [-vendorid <XXXX>|\"\"]\n"
502 " [-productid <XXXX>|\"\"]\n"
503 " [-revision <IIFF>|\"\"]\n"
504 " [-manufacturer <string>|\"\"]\n"
505 " [-product <string>|\"\"]\n"
506 " [-remote yes|no] (null, VM filters only)\n"
507 " [-serialnumber <string>|\"\"]\n"
508 "\n");
509 }
510
511 if (enmCmd & USAGE_USBFILTER_REMOVE)
512 {
513 RTPrintf("VBoxManage usbfilter remove <index,0-N>\n"
514 " -target <uuid>|<name>|global\n"
515 "\n");
516 }
517
518 if (enmCmd & USAGE_SHAREDFOLDER_ADD)
519 {
520 RTPrintf("VBoxManage sharedfolder add <vmname>|<uuid>\n"
521 " -name <name> -hostpath <hostpath>\n"
522 " [-transient]\n"
523 "\n");
524 }
525
526 if (enmCmd & USAGE_SHAREDFOLDER_REMOVE)
527 {
528 RTPrintf("VBoxManage sharedfolder remove <vmname>|<uuid>\n"
529 " -name <name> [-transient]\n"
530 "\n");
531 }
532
533 if (enmCmd & USAGE_UPDATESETTINGS)
534 {
535 RTPrintf("VBoxManage updatesettings [<dir>|<file>] [-apply]\n"
536 " [-nobackup] [-skipinvalid]\n"
537 "\n");
538 }
539}
540
541/**
542 * Print a usage synopsis and the syntax error message.
543 */
544int errorSyntax(USAGECATEGORY enmCmd, const char *pszFormat, ...)
545{
546 va_list args;
547 if (fInternalMode)
548 printUsageInternal(enmCmd);
549 else
550 printUsage(enmCmd);
551 va_start(args, pszFormat);
552 RTPrintf("\n"
553 "Syntax error: %N\n", pszFormat, &args);
554 va_end(args);
555 return 1;
556}
557
558/**
559 * Print an error message without the syntax stuff.
560 */
561int errorArgument(const char *pszFormat, ...)
562{
563 va_list args;
564 va_start(args, pszFormat);
565 RTPrintf("error: %N\n", pszFormat, &args);
566 va_end(args);
567 return 1;
568}
569
570/**
571 * Print out progress on the console
572 */
573static void showProgress(ComPtr<IProgress> progress)
574{
575 BOOL fCompleted;
576 LONG currentPercent, lastPercent = 0;
577
578 RTPrintf("0%%...");
579 RTStrmFlush(g_pStdOut);
580 while (SUCCEEDED(progress->COMGETTER(Completed(&fCompleted))))
581 {
582 progress->COMGETTER(Percent(&currentPercent));
583 /* did we cross a 10% mark? */
584 if (((currentPercent / 10) > (lastPercent / 10)))
585 {
586 /* make sure to also print out missed steps */
587 for (LONG curVal = (lastPercent / 10) * 10 + 10; curVal <= (currentPercent / 10) * 10; curVal += 10)
588 {
589 if (curVal < 100)
590 {
591 RTPrintf("%ld%%...", curVal);
592 RTStrmFlush(g_pStdOut);
593 }
594 }
595 }
596 lastPercent = currentPercent;
597 if (fCompleted)
598 {
599 RTPrintf("100%%\n");
600 RTStrmFlush(g_pStdOut);
601 break;
602 }
603 /* make sure the loop is not too tight */
604 RTThreadSleep(100);
605 }
606}
607
608static void showSnapshots(ComPtr<ISnapshot> rootSnapshot, int level = 0)
609{
610 /* start with the root */
611 Bstr name;
612 Guid uuid;
613 rootSnapshot->COMGETTER(Name)(name.asOutParam());
614 rootSnapshot->COMGETTER(Id)(uuid.asOutParam());
615 /* print with indentation */
616 RTPrintf("%*sName: %lS (UUID: %s)\n", level * 3, "", name.raw(), uuid.toString().raw());
617
618 /* get the children */
619 ComPtr<ISnapshotCollection> coll;
620 rootSnapshot->COMGETTER(Children)(coll.asOutParam());
621 if (coll)
622 {
623 ComPtr<ISnapshotEnumerator> enumerator;
624 coll->Enumerate(enumerator.asOutParam());
625 BOOL hasMore = FALSE;
626 while (enumerator->HasMore(&hasMore), hasMore)
627 {
628 ComPtr<ISnapshot> snapshot;
629 enumerator->GetNext(snapshot.asOutParam());
630 if (snapshot)
631 {
632 /* recursive call */
633 showSnapshots(snapshot, level + 1);
634 }
635 }
636 }
637}
638
639static void makeTimeStr (char *s, int cb, int64_t millies)
640{
641 RTTIME t;
642 RTTIMESPEC ts;
643
644 RTTimeSpecSetMilli(&ts, millies);
645
646 RTTimeExplode (&t, &ts);
647
648 RTStrPrintf(s, cb, "%04d/%02d/%02d %02d:%02d:%02d UTC",
649 t.i32Year, t.u8Month, t.u8MonthDay,
650 t.u8Hour, t.u8Minute, t.u8Second);
651}
652
653static HRESULT showVMInfo (ComPtr <IVirtualBox> virtualBox, ComPtr<IMachine> machine,
654 ComPtr <IConsole> console = ComPtr <IConsole> ())
655{
656 HRESULT rc;
657
658 BOOL accessible = FALSE;
659 CHECK_ERROR (machine, COMGETTER(Accessible) (&accessible));
660 CheckComRCReturnRC (rc);
661
662 if (!accessible)
663 {
664 RTPrintf ("Name: <inaccessible!>\n");
665 Guid uuid;
666 rc = machine->COMGETTER(Id) (uuid.asOutParam());
667 RTPrintf ("UUID: %s\n", uuid.toString().raw());
668 Bstr settingsFilePath;
669 rc = machine->COMGETTER(SettingsFilePath) (settingsFilePath.asOutParam());
670 RTPrintf ("Config file: %lS\n", settingsFilePath.raw());
671 ComPtr<IVirtualBoxErrorInfo> accessError;
672 rc = machine->COMGETTER(AccessError) (accessError.asOutParam());
673 RTPrintf ("Access error details:\n");
674 ErrorInfo ei (accessError);
675 ei.print ("[-] ");
676 RTPrintf ("\n");
677 return S_OK;
678 }
679
680 Bstr machineName;
681 rc = machine->COMGETTER(Name)(machineName.asOutParam());
682 RTPrintf("Name: %lS\n", machineName.raw());
683
684 ComPtr<IGuestOSType> osType;
685 Bstr osName;
686 rc = machine->COMGETTER(OSType)(osType.asOutParam());
687 rc = osType->COMGETTER(Description)(osName.asOutParam());
688 RTPrintf("Guest OS: %lS\n", osName.raw());
689
690 Guid uuid;
691 rc = machine->COMGETTER(Id)(uuid.asOutParam());
692 RTPrintf("UUID: %s\n", uuid.toString().raw());
693
694 Bstr settingsFilePath;
695 rc = machine->COMGETTER(SettingsFilePath)(settingsFilePath.asOutParam());
696 RTPrintf("Config file: %lS\n", settingsFilePath.raw());
697
698 ULONG memorySize;
699 rc = machine->COMGETTER(MemorySize)(&memorySize);
700 RTPrintf("Memory size: %uMB\n", memorySize);
701
702 ULONG vramSize;
703 rc = machine->COMGETTER(VRAMSize)(&vramSize);
704 RTPrintf("VRAM size: %uMB\n", vramSize);
705
706 ComPtr <IBIOSSettings> biosSettings;
707 machine->COMGETTER(BIOSSettings)(biosSettings.asOutParam());
708
709 BIOSBootMenuMode_T bootMenuMode;
710 biosSettings->COMGETTER(BootMenuMode)(&bootMenuMode);
711 RTPrintf("Boot menu mode: ");
712 switch (bootMenuMode)
713 {
714 case BIOSBootMenuMode_Disabled:
715 RTPrintf("disabled\n");
716 break;
717 case BIOSBootMenuMode_MenuOnly:
718 RTPrintf("menu only\n");
719 break;
720 default:
721 RTPrintf("message and menu\n");
722 }
723
724 BOOL acpiEnabled;
725 biosSettings->COMGETTER(ACPIEnabled)(&acpiEnabled);
726 RTPrintf("ACPI: %s\n", acpiEnabled ? "on" : "off");
727
728 BOOL ioapicEnabled;
729 biosSettings->COMGETTER(IOAPICEnabled)(&ioapicEnabled);
730 RTPrintf("IOAPIC: %s\n", ioapicEnabled ? "on" : "off");
731
732 TriStateBool_T hwVirtExEnabled;
733 machine->COMGETTER(HWVirtExEnabled)(&hwVirtExEnabled);
734 if (hwVirtExEnabled == TriStateBool_Default)
735 {
736 BOOL fHWVirtExEnabled;
737 ComPtr<ISystemProperties> systemProperties;
738 virtualBox->COMGETTER(SystemProperties)(systemProperties.asOutParam());
739 systemProperties->COMGETTER(HWVirtExEnabled)(&fHWVirtExEnabled);
740 RTPrintf("Hardw. virt.ext: Default (%s)\n", fHWVirtExEnabled ? "on" : "off");
741 }
742 else
743 {
744 RTPrintf("Hardw. virt.ext: %s\n", hwVirtExEnabled == TriStateBool_True ? "on" : "off");
745 }
746
747 MachineState_T machineState;
748 const char *pszState = NULL;
749 rc = machine->COMGETTER(State)(&machineState);
750 switch (machineState)
751 {
752 case MachineState_PoweredOff:
753 pszState = "powered off";
754 break;
755 case MachineState_Saved:
756 pszState = "saved";
757 break;
758 case MachineState_Aborted:
759 pszState = "aborted";
760 break;
761 case MachineState_Running:
762 pszState = "running";
763 break;
764 case MachineState_Paused:
765 pszState = "paused";
766 break;
767 case MachineState_Starting:
768 pszState = "starting";
769 break;
770 case MachineState_Stopping:
771 pszState = "stopping";
772 break;
773 case MachineState_Saving:
774 pszState = "saving";
775 break;
776 case MachineState_Restoring:
777 pszState = "restoring";
778 break;
779 default:
780 pszState = "unknown";
781 break;
782 }
783 RTPrintf("State: %s\n", pszState);
784
785 ComPtr<IFloppyDrive> floppyDrive;
786 rc = machine->COMGETTER(FloppyDrive)(floppyDrive.asOutParam());
787 if (SUCCEEDED(rc) && floppyDrive)
788 {
789 BOOL fFloppyEnabled;
790 floppyDrive->COMGETTER(Enabled)(&fFloppyEnabled);
791 Utf8Str pszFloppy = "invalid";
792 if (fFloppyEnabled)
793 {
794 DriveState_T floppyState;
795 floppyDrive->COMGETTER(State)(&floppyState);
796 switch (floppyState)
797 {
798 case DriveState_ImageMounted:
799 {
800 ComPtr<IFloppyImage> floppyImage;
801 rc = floppyDrive->GetImage(floppyImage.asOutParam());
802 if (SUCCEEDED(rc) && floppyImage)
803 {
804 Bstr imagePath;
805 floppyImage->COMGETTER(FilePath)(imagePath.asOutParam());
806 Guid imageGuid;
807 floppyImage->COMGETTER(Id)(imageGuid.asOutParam());
808 pszFloppy = Utf8StrFmt("%lS (UUID: %s)", imagePath.raw(), imageGuid.toString().raw());
809 }
810 break;
811 }
812
813 case DriveState_HostDriveCaptured:
814 {
815 ComPtr<IHostFloppyDrive> hostFloppyDrive;
816 rc = floppyDrive->GetHostDrive(hostFloppyDrive.asOutParam());
817 if (SUCCEEDED(rc) && floppyDrive)
818 {
819 Bstr driveName;
820 hostFloppyDrive->COMGETTER(Name)(driveName.asOutParam());
821 pszFloppy = Utf8StrFmt("Host drive %lS", driveName.raw());
822 }
823 break;
824 }
825
826 case DriveState_NotMounted:
827 {
828 pszFloppy = "empty";
829 break;
830 }
831 }
832 }
833 else
834 {
835 pszFloppy = "disabled";
836 }
837 RTPrintf("Floppy: %s\n", pszFloppy.raw());
838 }
839
840 ComPtr<IHardDisk> hardDisk;
841 Bstr filePath;
842 rc = machine->GetHardDisk(DiskControllerType_IDE0Controller, 0, hardDisk.asOutParam());
843 if (SUCCEEDED(rc) && hardDisk)
844 {
845 /// @todo (dmik) we temporarily use the location property to
846 // determine the image file name. This is subject to change
847 // when iSCSI disks are here (we should either query a
848 // storage-specific interface from IHardDisk, or "standardize"
849 // the location property)
850 hardDisk->COMGETTER(Location)(filePath.asOutParam());
851 hardDisk->COMGETTER(Id)(uuid.asOutParam());
852 RTPrintf("Primary master: %lS (UUID: %s)\n", filePath.raw(), uuid.toString().raw());
853 }
854 rc = machine->GetHardDisk(DiskControllerType_IDE0Controller, 1, hardDisk.asOutParam());
855 if (SUCCEEDED(rc) && hardDisk)
856 {
857 /// @todo (dmik) we temporarily use the location property to
858 // determine the image file name. This is subject to change
859 // when iSCSI disks are here (we should either query a
860 // storage-specific interface from IHardDisk, or "standardize"
861 // the location property)
862 hardDisk->COMGETTER(Location)(filePath.asOutParam());
863 hardDisk->COMGETTER(Id)(uuid.asOutParam());
864 RTPrintf("Primary slave: %lS (UUID: %s)\n", filePath.raw(), uuid.toString().raw());
865 }
866 rc = machine->GetHardDisk(DiskControllerType_IDE1Controller, 1, hardDisk.asOutParam());
867 if (SUCCEEDED(rc) && hardDisk)
868 {
869 /// @todo (dmik) we temporarily use the location property to
870 // determine the image file name. This is subject to change
871 // when iSCSI disks are here (we should either query a
872 // storage-specific interface from IHardDisk, or "standardize"
873 // the location property)
874 hardDisk->COMGETTER(Location)(filePath.asOutParam());
875 hardDisk->COMGETTER(Id)(uuid.asOutParam());
876 RTPrintf("Secondary slave: %lS (UUID: %s)\n", filePath.raw(), uuid.toString().raw());
877 }
878 ComPtr<IDVDDrive> dvdDrive;
879 rc = machine->COMGETTER(DVDDrive)(dvdDrive.asOutParam());
880 if (SUCCEEDED(rc) && dvdDrive)
881 {
882 ComPtr<IDVDImage> dvdImage;
883 rc = dvdDrive->GetImage(dvdImage.asOutParam());
884 if (SUCCEEDED(rc) && dvdImage)
885 {
886 rc = dvdImage->COMGETTER(FilePath)(filePath.asOutParam());
887 if (SUCCEEDED(rc) && filePath)
888 {
889 rc = dvdImage->COMGETTER(Id)(uuid.asOutParam());
890 RTPrintf("DVD: %lS (UUID: %s)\n", filePath.raw(), uuid.toString().raw());
891 }
892 }
893 else
894 {
895 ComPtr<IHostDVDDrive> hostDVDDrive;
896 rc = dvdDrive->GetHostDrive(hostDVDDrive.asOutParam());
897 if (SUCCEEDED(rc) && hostDVDDrive)
898 {
899 Bstr name;
900 hostDVDDrive->COMGETTER(Name)(name.asOutParam());
901 RTPrintf("DVD: Host drive %lS", name.raw());
902 }
903 else
904 RTPrintf("DVD: empty");
905 BOOL fPassthrough;
906 dvdDrive->COMGETTER(Passthrough)(&fPassthrough);
907 if (fPassthrough)
908 RTPrintf(" (passthrough enabled)");
909 RTPrintf("\n");
910 }
911 }
912
913 /* get the maximum amount of NICS */
914 ComPtr<ISystemProperties> sysProps;
915 virtualBox->COMGETTER(SystemProperties)(sysProps.asOutParam());
916 ULONG maxNICs = 0;
917 sysProps->COMGETTER(NetworkAdapterCount)(&maxNICs);
918 for (ULONG currentNIC = 0; currentNIC < maxNICs; currentNIC++)
919 {
920 ComPtr<INetworkAdapter> nic;
921 rc = machine->GetNetworkAdapter(currentNIC, nic.asOutParam());
922 if (SUCCEEDED(rc) && nic)
923 {
924 BOOL fEnabled;
925 nic->COMGETTER(Enabled)(&fEnabled);
926 if (!fEnabled)
927 {
928 RTPrintf("NIC %d: disabled\n", currentNIC + 1);
929 }
930 else
931 {
932 Bstr strMACAddress;
933 nic->COMGETTER(MACAddress)(strMACAddress.asOutParam());
934 Utf8Str strAttachment;
935 NetworkAttachmentType_T attachment;
936 nic->COMGETTER(AttachmentType)(&attachment);
937 switch (attachment)
938 {
939 case NetworkAttachmentType_NoNetworkAttachment:
940 strAttachment = "none";
941 break;
942 case NetworkAttachmentType_NATNetworkAttachment:
943 strAttachment = "NAT";
944 break;
945 case NetworkAttachmentType_HostInterfaceNetworkAttachment:
946 strAttachment = "Host Interface";
947 break;
948 case NetworkAttachmentType_InternalNetworkAttachment:
949 {
950 Bstr strNetwork;
951 nic->COMGETTER(InternalNetwork)(strNetwork.asOutParam());
952 strAttachment = Utf8StrFmt("Internal Network '%s'", Utf8Str(strNetwork).raw());
953 break;
954 }
955 default:
956 strAttachment = "unknown";
957 break;
958 }
959
960 /* trace stuff */
961 BOOL fTraceEnabled;
962 nic->COMGETTER(TraceEnabled)(&fTraceEnabled);
963 Bstr traceFile;
964 nic->COMGETTER(TraceFile)(traceFile.asOutParam());
965
966 RTPrintf("NIC %d: MAC: %lS, Attachment: %s, Trace: %s (file: %lS)\n",
967 currentNIC + 1, strMACAddress.raw(), strAttachment.raw(),
968 fTraceEnabled ? "on" : "off", traceFile.raw());
969 }
970 }
971 }
972
973 ComPtr<IAudioAdapter> AudioAdapter;
974 rc = machine->COMGETTER(AudioAdapter)(AudioAdapter.asOutParam());
975 if (SUCCEEDED(rc))
976 {
977 const char *psz = "Unknown";
978 BOOL fEnabled;
979 rc = AudioAdapter->COMGETTER(Enabled)(&fEnabled);
980 if (SUCCEEDED(rc) && fEnabled)
981 {
982 AudioDriverType_T enmType;
983 rc = AudioAdapter->COMGETTER(AudioDriver)(&enmType);
984 switch (enmType)
985 {
986 case AudioDriverType_NullAudioDriver: psz = "Null"; break;
987 case AudioDriverType_WINMMAudioDriver: psz = "WINMM"; break;
988 case AudioDriverType_DSOUNDAudioDriver: psz = "DSOUND"; break;
989 case AudioDriverType_OSSAudioDriver: psz = "OSS"; break;
990 case AudioDriverType_ALSAAudioDriver: psz = "ALSA"; break;
991 default: ; break;
992 }
993 }
994 else
995 fEnabled = FALSE;
996 RTPrintf("Audio: %s (Driver: %s)\n", fEnabled ? "enabled" : "disabled", psz);
997 }
998
999 if (console)
1000 {
1001 ComPtr<IDisplay> display;
1002 CHECK_ERROR_RET(console, COMGETTER(Display)(display.asOutParam()), rc);
1003 ULONG xRes, yRes, bpp;
1004 CHECK_ERROR_RET(display, COMGETTER(Width)(&xRes), rc);
1005 CHECK_ERROR_RET(display, COMGETTER(Height)(&yRes), rc);
1006 CHECK_ERROR_RET(display, COMGETTER(ColorDepth)(&bpp), rc);
1007 RTPrintf("Video mode: %dx%dx%d\n", xRes, yRes, bpp);
1008 }
1009
1010 /*
1011 * VRDP
1012 */
1013 ComPtr<IVRDPServer> vrdpServer;
1014 rc = machine->COMGETTER(VRDPServer)(vrdpServer.asOutParam());
1015 if (SUCCEEDED(rc) && vrdpServer)
1016 {
1017 BOOL fEnabled = false;
1018 vrdpServer->COMGETTER(Enabled)(&fEnabled);
1019 if (fEnabled)
1020 {
1021 ULONG port;
1022 vrdpServer->COMGETTER(Port)(&port);
1023 VRDPAuthType_T vrdpAuthType;
1024 char *strAuthType;
1025 vrdpServer->COMGETTER(AuthType)(&vrdpAuthType);
1026 switch (vrdpAuthType)
1027 {
1028 case VRDPAuthType_VRDPAuthNull:
1029 strAuthType = "null";
1030 break;
1031 case VRDPAuthType_VRDPAuthExternal:
1032 strAuthType = "external";
1033 break;
1034 case VRDPAuthType_VRDPAuthGuest:
1035 strAuthType = "guest";
1036 break;
1037 default:
1038 strAuthType = "unknown";
1039 break;
1040 }
1041 RTPrintf("VRDP: enabled (Port %d, Authentication type: %s)\n", port, strAuthType);
1042 }
1043 else
1044 RTPrintf("VRDP: disabled\n");
1045 }
1046
1047 /*
1048 * USB.
1049 */
1050 ComPtr<IUSBController> USBCtl;
1051 rc = machine->COMGETTER(USBController)(USBCtl.asOutParam());
1052 if (SUCCEEDED(rc))
1053 {
1054 BOOL fEnabled;
1055 rc = USBCtl->COMGETTER(Enabled)(&fEnabled);
1056 if (FAILED(rc))
1057 fEnabled = false;
1058 RTPrintf("USB: %s\n", fEnabled ? "enabled" : "disabled");
1059
1060 RTPrintf("\nUSB Device Filters:\n\n");
1061
1062 ComPtr<IUSBDeviceFilterCollection> Coll;
1063 CHECK_ERROR_RET (USBCtl, COMGETTER(DeviceFilters)(Coll.asOutParam()), rc);
1064
1065 ComPtr<IUSBDeviceFilterEnumerator> Enum;
1066 CHECK_ERROR_RET (Coll, Enumerate(Enum.asOutParam()), rc);
1067
1068 ULONG index = 0;
1069 BOOL fMore = FALSE;
1070 rc = Enum->HasMore (&fMore);
1071 ASSERT_RET (SUCCEEDED (rc), rc);
1072
1073 if (!fMore)
1074 {
1075 RTPrintf("<none>\n\n");
1076 }
1077 else
1078 while (fMore)
1079 {
1080 ComPtr<IUSBDeviceFilter> DevPtr;
1081 rc = Enum->GetNext(DevPtr.asOutParam());
1082 ASSERT_RET (SUCCEEDED (rc), rc);
1083
1084 /* Query info. */
1085
1086 RTPrintf("Index: %lu\n", index);
1087
1088 BOOL bActive = FALSE;
1089 CHECK_ERROR_RET (DevPtr, COMGETTER (Active) (&bActive), rc);
1090 RTPrintf("Active: %s\n", bActive ? "yes" : "no");
1091
1092 Bstr bstr;
1093 CHECK_ERROR_RET (DevPtr, COMGETTER (Name) (bstr.asOutParam()), rc);
1094 RTPrintf("Name: %lS\n", bstr.raw());
1095 CHECK_ERROR_RET (DevPtr, COMGETTER (VendorId) (bstr.asOutParam()), rc);
1096 RTPrintf("VendorId: %lS\n", bstr.raw());
1097 CHECK_ERROR_RET (DevPtr, COMGETTER (ProductId) (bstr.asOutParam()), rc);
1098 RTPrintf("ProductId: %lS\n", bstr.raw());
1099 CHECK_ERROR_RET (DevPtr, COMGETTER (Revision) (bstr.asOutParam()), rc);
1100 RTPrintf("Revision: %lS\n", bstr.raw());
1101 CHECK_ERROR_RET (DevPtr, COMGETTER (Manufacturer) (bstr.asOutParam()), rc);
1102 RTPrintf("Manufacturer: %lS\n", bstr.raw());
1103 CHECK_ERROR_RET (DevPtr, COMGETTER (Product) (bstr.asOutParam()), rc);
1104 RTPrintf("Product: %lS\n", bstr.raw());
1105 CHECK_ERROR_RET (DevPtr, COMGETTER (SerialNumber) (bstr.asOutParam()), rc);
1106 RTPrintf("Serial Number: %lS\n\n", bstr.raw());
1107
1108 rc = Enum->HasMore (&fMore);
1109 ASSERT_RET (SUCCEEDED (rc), rc);
1110
1111 index ++;
1112 }
1113
1114 if (console)
1115 {
1116 /* scope */
1117 {
1118 RTPrintf("Available remote USB devices:\n\n");
1119
1120 ComPtr<IHostUSBDeviceCollection> coll;
1121 CHECK_ERROR_RET (console, COMGETTER(RemoteUSBDevices) (coll.asOutParam()), rc);
1122
1123 ComPtr <IHostUSBDeviceEnumerator> en;
1124 CHECK_ERROR_RET (coll, Enumerate (en.asOutParam()), rc);
1125
1126 BOOL more = FALSE;
1127 rc = en->HasMore (&more);
1128 ASSERT_RET (SUCCEEDED (rc), rc);
1129
1130 if (!more)
1131 {
1132 RTPrintf("<none>\n\n");
1133 }
1134 else
1135 while (more)
1136 {
1137 ComPtr <IHostUSBDevice> dev;
1138 rc = en->GetNext (dev.asOutParam());
1139 ASSERT_RET (SUCCEEDED (rc), rc);
1140
1141 /* Query info. */
1142 Guid id;
1143 CHECK_ERROR_RET (dev, COMGETTER(Id)(id.asOutParam()), rc);
1144 USHORT usVendorId;
1145 CHECK_ERROR_RET (dev, COMGETTER(VendorId)(&usVendorId), rc);
1146 USHORT usProductId;
1147 CHECK_ERROR_RET (dev, COMGETTER(ProductId)(&usProductId), rc);
1148 USHORT bcdRevision;
1149 CHECK_ERROR_RET (dev, COMGETTER(Revision)(&bcdRevision), rc);
1150
1151 RTPrintf("UUID: %S\n"
1152 "VendorId: 0x%04x (%04X)\n"
1153 "ProductId: 0x%04x (%04X)\n"
1154 "Revision: %u.%u (%02u%02u)\n",
1155 id.toString().raw(),
1156 usVendorId, usVendorId, usProductId, usProductId,
1157 bcdRevision >> 8, bcdRevision & 0xff,
1158 bcdRevision >> 8, bcdRevision & 0xff);
1159
1160 /* optional stuff. */
1161 Bstr bstr;
1162 CHECK_ERROR_RET (dev, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
1163 if (!bstr.isEmpty())
1164 RTPrintf("Manufacturer: %lS\n", bstr.raw());
1165 CHECK_ERROR_RET (dev, COMGETTER(Product)(bstr.asOutParam()), rc);
1166 if (!bstr.isEmpty())
1167 RTPrintf("Product: %lS\n", bstr.raw());
1168 CHECK_ERROR_RET (dev, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
1169 if (!bstr.isEmpty())
1170 RTPrintf("SerialNumber: %lS\n", bstr.raw());
1171 CHECK_ERROR_RET (dev, COMGETTER(Address)(bstr.asOutParam()), rc);
1172 if (!bstr.isEmpty())
1173 RTPrintf("Address: %lS\n", bstr.raw());
1174
1175 RTPrintf("\n");
1176
1177 rc = en->HasMore (&more);
1178 ASSERT_RET (SUCCEEDED (rc), rc);
1179 }
1180 }
1181
1182 /* scope */
1183 {
1184 RTPrintf ("Currently Attached USB Devices:\n\n");
1185
1186 ComPtr <IUSBDeviceCollection> coll;
1187 CHECK_ERROR_RET (console, COMGETTER(USBDevices) (coll.asOutParam()), rc);
1188
1189 ComPtr <IUSBDeviceEnumerator> en;
1190 CHECK_ERROR_RET (coll, Enumerate (en.asOutParam()), rc);
1191
1192 BOOL more = FALSE;
1193 rc = en->HasMore (&more);
1194 ASSERT_RET (SUCCEEDED (rc), rc);
1195
1196 if (!more)
1197 {
1198 RTPrintf("<none>\n\n");
1199 }
1200 else
1201 while (more)
1202 {
1203 ComPtr <IUSBDevice> dev;
1204 rc = en->GetNext (dev.asOutParam());
1205 ASSERT_RET (SUCCEEDED (rc), rc);
1206
1207 /* Query info. */
1208 Guid id;
1209 CHECK_ERROR_RET (dev, COMGETTER(Id)(id.asOutParam()), rc);
1210 USHORT usVendorId;
1211 CHECK_ERROR_RET (dev, COMGETTER(VendorId)(&usVendorId), rc);
1212 USHORT usProductId;
1213 CHECK_ERROR_RET (dev, COMGETTER(ProductId)(&usProductId), rc);
1214 USHORT bcdRevision;
1215 CHECK_ERROR_RET (dev, COMGETTER(Revision)(&bcdRevision), rc);
1216
1217 RTPrintf("UUID: %S\n"
1218 "VendorId: 0x%04x (%04X)\n"
1219 "ProductId: 0x%04x (%04X)\n"
1220 "Revision: %u.%u (%02u%02u)\n",
1221 id.toString().raw(),
1222 usVendorId, usVendorId, usProductId, usProductId,
1223 bcdRevision >> 8, bcdRevision & 0xff,
1224 bcdRevision >> 8, bcdRevision & 0xff);
1225
1226 /* optional stuff. */
1227 Bstr bstr;
1228 CHECK_ERROR_RET (dev, COMGETTER(Manufacturer)(bstr.asOutParam()), rc);
1229 if (!bstr.isEmpty())
1230 RTPrintf("Manufacturer: %lS\n", bstr.raw());
1231 CHECK_ERROR_RET (dev, COMGETTER(Product)(bstr.asOutParam()), rc);
1232 if (!bstr.isEmpty())
1233 RTPrintf("Product: %lS\n", bstr.raw());
1234 CHECK_ERROR_RET (dev, COMGETTER(SerialNumber)(bstr.asOutParam()), rc);
1235 if (!bstr.isEmpty())
1236 RTPrintf("SerialNumber: %lS\n", bstr.raw());
1237 CHECK_ERROR_RET (dev, COMGETTER(Address)(bstr.asOutParam()), rc);
1238 if (!bstr.isEmpty())
1239 RTPrintf("Address: %lS\n", bstr.raw());
1240
1241 RTPrintf("\n");
1242
1243 rc = en->HasMore (&more);
1244 ASSERT_RET (SUCCEEDED (rc), rc);
1245 }
1246 }
1247 }
1248 } /* USB */
1249
1250 /*
1251 * Shared folders
1252 */
1253 RTPrintf("Shared folders:\n\n");
1254 uint32_t numSharedFolders = 0;
1255#if 0 // not yet implemented
1256 /* globally shared folders first */
1257 {
1258 ComPtr<ISharedFolderCollection> sfColl;
1259 ComPtr<ISharedFolderEnumerator> sfEnum;
1260 CHECK_ERROR_RET(virtualBox, COMGETTER(SharedFolders)(sfColl.asOutParam()), rc);
1261 CHECK_ERROR_RET(sfColl, Enumerate(sfEnum.asOutParam()), rc);
1262 BOOL fMore;
1263 sfEnum->HasMore(&fMore);
1264 while (fMore)
1265 {
1266 ComPtr<ISharedFolder> sf;
1267 CHECK_ERROR_RET(sfEnum, GetNext(sf.asOutParam()), rc);
1268 Bstr name, hostPath;
1269 sf->COMGETTER(Name)(name.asOutParam());
1270 sf->COMGETTER(HostPath)(hostPath.asOutParam());
1271 RTPrintf("Name: '%lS', Host path: '%lS' (global mapping)\n", name.raw(), hostPath.raw());
1272 ++numSharedFolders;
1273 CHECK_ERROR_RET(sfEnum, HasMore(&fMore), rc);
1274 }
1275 }
1276#endif
1277 /* now VM mappings */
1278 {
1279 ComPtr<ISharedFolderCollection> sfColl;
1280 ComPtr<ISharedFolderEnumerator> sfEnum;
1281 CHECK_ERROR_RET(machine, COMGETTER(SharedFolders)(sfColl.asOutParam()), rc);
1282 CHECK_ERROR_RET(sfColl, Enumerate(sfEnum.asOutParam()), rc);
1283 BOOL fMore;
1284 sfEnum->HasMore(&fMore);
1285 while (fMore)
1286 {
1287 ComPtr<ISharedFolder> sf;
1288 CHECK_ERROR_RET(sfEnum, GetNext(sf.asOutParam()), rc);
1289 Bstr name, hostPath;
1290 sf->COMGETTER(Name)(name.asOutParam());
1291 sf->COMGETTER(HostPath)(hostPath.asOutParam());
1292 RTPrintf("Name: '%lS', Host path: '%lS' (machine mapping)\n", name.raw(), hostPath.raw());
1293 ++numSharedFolders;
1294 CHECK_ERROR_RET(sfEnum, HasMore(&fMore), rc);
1295 }
1296 }
1297 /* transient mappings */
1298 if (console)
1299 {
1300 ComPtr<ISharedFolderCollection> sfColl;
1301 ComPtr<ISharedFolderEnumerator> sfEnum;
1302 CHECK_ERROR_RET(console, COMGETTER(SharedFolders)(sfColl.asOutParam()), rc);
1303 CHECK_ERROR_RET(sfColl, Enumerate(sfEnum.asOutParam()), rc);
1304 BOOL fMore;
1305 sfEnum->HasMore(&fMore);
1306 while (fMore)
1307 {
1308 ComPtr<ISharedFolder> sf;
1309 CHECK_ERROR_RET(sfEnum, GetNext(sf.asOutParam()), rc);
1310 Bstr name, hostPath;
1311 sf->COMGETTER(Name)(name.asOutParam());
1312 sf->COMGETTER(HostPath)(hostPath.asOutParam());
1313 RTPrintf("Name: '%lS', Host path: '%lS' (transient mapping)\n", name.raw(), hostPath.raw());
1314 ++numSharedFolders;
1315 CHECK_ERROR_RET(sfEnum, HasMore(&fMore), rc);
1316 }
1317 }
1318 if (!numSharedFolders)
1319 RTPrintf("<none>\n");
1320 RTPrintf("\n");
1321
1322 if (console)
1323 {
1324 /*
1325 * Live VRDP info.
1326 */
1327 ComPtr<IRemoteDisplayInfo> remoteDisplayInfo;
1328 CHECK_ERROR_RET(console, COMGETTER(RemoteDisplayInfo)(remoteDisplayInfo.asOutParam()), rc);
1329 BOOL Active;
1330 ULONG NumberOfClients;
1331 LONG64 BeginTime;
1332 LONG64 EndTime;
1333 ULONG64 BytesSent;
1334 ULONG64 BytesSentTotal;
1335 ULONG64 BytesReceived;
1336 ULONG64 BytesReceivedTotal;
1337 Bstr User;
1338 Bstr Domain;
1339 Bstr ClientName;
1340 Bstr ClientIP;
1341 ULONG ClientVersion;
1342 ULONG EncryptionStyle;
1343
1344 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(Active) (&Active), rc);
1345 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(NumberOfClients) (&NumberOfClients), rc);
1346 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(BeginTime) (&BeginTime), rc);
1347 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(EndTime) (&EndTime), rc);
1348 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(BytesSent) (&BytesSent), rc);
1349 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(BytesSentTotal) (&BytesSentTotal), rc);
1350 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(BytesReceived) (&BytesReceived), rc);
1351 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(BytesReceivedTotal) (&BytesReceivedTotal), rc);
1352 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(User) (User.asOutParam ()), rc);
1353 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(Domain) (Domain.asOutParam ()), rc);
1354 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(ClientName) (ClientName.asOutParam ()), rc);
1355 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(ClientIP) (ClientIP.asOutParam ()), rc);
1356 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(ClientVersion) (&ClientVersion), rc);
1357 CHECK_ERROR_RET(remoteDisplayInfo, COMGETTER(EncryptionStyle) (&EncryptionStyle), rc);
1358
1359 RTPrintf("VRDP Connection: %s\n", Active? "active": "not active");
1360 RTPrintf("Clients so far: %d\n", NumberOfClients);
1361
1362 if (NumberOfClients > 0)
1363 {
1364 char timestr[128];
1365
1366 if (Active)
1367 {
1368 makeTimeStr (timestr, sizeof (timestr), BeginTime);
1369 RTPrintf("Start time: %s\n", timestr);
1370 }
1371 else
1372 {
1373 makeTimeStr (timestr, sizeof (timestr), BeginTime);
1374 RTPrintf("Last started: %s\n", timestr);
1375 makeTimeStr (timestr, sizeof (timestr), EndTime);
1376 RTPrintf("Last ended: %s\n", timestr);
1377 }
1378
1379 RTPrintf("Sent: %llu Bytes\n", BytesSent);
1380 RTPrintf("Average speed: %llu B/s\n", (BytesSent * 1000) / (EndTime - BeginTime) );
1381 RTPrintf("Sent total: %llu Bytes\n", BytesSentTotal);
1382
1383 RTPrintf("Received: %llu Bytes\n", BytesReceived);
1384 RTPrintf("Speed: %llu B/s\n", (BytesReceived * 1000) / (EndTime - BeginTime) );
1385 RTPrintf("Received total: %llu Bytes\n", BytesReceivedTotal);
1386
1387 if (Active)
1388 {
1389 RTPrintf("User name: %lS\n", User.raw());
1390 RTPrintf("Domain: %lS\n", Domain.raw());
1391 RTPrintf("Client name: %lS\n", ClientName.raw());
1392 RTPrintf("Client IP: %lS\n", ClientIP.raw());
1393 RTPrintf("Client version: %d\n", ClientVersion);
1394 RTPrintf("Encryption: %s\n", EncryptionStyle == 0? "RDP4": "RDP5 (X.509)");
1395 }
1396 }
1397
1398 RTPrintf("\n");
1399 }
1400
1401 /*
1402 * snapshots
1403 */
1404 ComPtr<ISnapshot> snapshot;
1405 rc = machine->GetSnapshot(Guid(), snapshot.asOutParam());
1406 if (SUCCEEDED(rc) && snapshot)
1407 {
1408 RTPrintf("Snapshots:\n\n");
1409 showSnapshots(snapshot);
1410 }
1411
1412 RTPrintf("\n");
1413 return S_OK;
1414}
1415
1416static int handleShowVMInfo(int argc, char *argv[],
1417 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
1418{
1419 HRESULT rc;
1420
1421 /* exactly one option: the UUID or name of the VM */
1422 if (argc != 1)
1423 {
1424 return errorSyntax(USAGE_SHOWVMINFO, "Incorrect number of parameters");
1425 }
1426
1427 /* try to find the given machine */
1428 ComPtr <IMachine> machine;
1429 Guid uuid (argv[0]);
1430 if (!uuid.isEmpty())
1431 {
1432 CHECK_ERROR (virtualBox, GetMachine (uuid, machine.asOutParam()));
1433 }
1434 else
1435 {
1436 CHECK_ERROR (virtualBox, FindMachine (Bstr(argv[0]), machine.asOutParam()));
1437 if (SUCCEEDED (rc))
1438 machine->COMGETTER(Id) (uuid.asOutParam());
1439 }
1440 if (FAILED (rc))
1441 return 1;
1442
1443 ComPtr <IConsole> console;
1444
1445 /* open an existing session for the VM */
1446 rc = virtualBox->OpenExistingSession (session, uuid);
1447 if (SUCCEEDED(rc))
1448 /* get the session machine */
1449 rc = session->COMGETTER(Machine)(machine.asOutParam());
1450 if (SUCCEEDED(rc))
1451 /* get the session console */
1452 rc = session->COMGETTER(Console)(console.asOutParam());
1453
1454 rc = showVMInfo (virtualBox, machine, console);
1455
1456 if (console)
1457 session->Close();
1458
1459 return SUCCEEDED (rc) ? 0 : 1;
1460}
1461
1462
1463static int handleList(int argc, char *argv[],
1464 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
1465{
1466 HRESULT rc = S_OK;
1467
1468 /* exactly one option: the object */
1469 if (argc != 1)
1470 {
1471 return errorSyntax(USAGE_LIST, "Incorrect number of parameters");
1472 }
1473
1474 /* which object? */
1475 if (strcmp(argv[0], "vms") == 0)
1476 {
1477 /*
1478 * Get the list of all registered VMs
1479 */
1480 ComPtr<IMachineCollection> collection;
1481 rc = virtualBox->COMGETTER(Machines)(collection.asOutParam());
1482 ComPtr<IMachineEnumerator> enumerator;
1483 if (SUCCEEDED(rc))
1484 rc = collection->Enumerate(enumerator.asOutParam());
1485 if (SUCCEEDED(rc))
1486 {
1487 /*
1488 * Iterate through the collection
1489 */
1490 BOOL hasMore = FALSE;
1491 while (enumerator->HasMore(&hasMore), hasMore)
1492 {
1493 ComPtr<IMachine> machine;
1494 rc = enumerator->GetNext(machine.asOutParam());
1495 if ((SUCCEEDED(rc)) && machine)
1496 {
1497 rc = showVMInfo(virtualBox, machine);
1498 }
1499 }
1500 }
1501 }
1502 else
1503 if (strcmp(argv[0], "ostypes") == 0)
1504 {
1505 ComPtr<IGuestOSTypeCollection> coll;
1506 ComPtr<IGuestOSTypeEnumerator> enumerator;
1507 CHECK_ERROR(virtualBox, COMGETTER(GuestOSTypes)(coll.asOutParam()));
1508 if (SUCCEEDED(rc) && coll)
1509 {
1510 CHECK_ERROR(coll, Enumerate(enumerator.asOutParam()));
1511 BOOL hasMore;
1512 while (SUCCEEDED(enumerator->HasMore(&hasMore)) && hasMore)
1513 {
1514 ComPtr<IGuestOSType> guestOS;
1515 CHECK_RC_BREAK(enumerator->GetNext(guestOS.asOutParam()));
1516 Bstr guestId;
1517 guestOS->COMGETTER(Id)(guestId.asOutParam());
1518 RTPrintf("ID: %lS\n", guestId.raw());
1519 Bstr guestDescription;
1520 guestOS->COMGETTER(Description)(guestDescription.asOutParam());
1521 RTPrintf("Description: %lS\n\n", guestDescription.raw());
1522 }
1523 }
1524 }
1525 else
1526 if (strcmp(argv[0], "hostdvds") == 0)
1527 {
1528 ComPtr<IHost> host;
1529 CHECK_ERROR(virtualBox, COMGETTER(Host)(host.asOutParam()));
1530 ComPtr<IHostDVDDriveCollection> coll;
1531 ComPtr<IHostDVDDriveEnumerator> enumerator;
1532 CHECK_ERROR(host, COMGETTER(DVDDrives)(coll.asOutParam()));
1533 if (SUCCEEDED(rc) && coll)
1534 {
1535 CHECK_ERROR(coll, Enumerate(enumerator.asOutParam()));
1536 BOOL hasMore;
1537 while (SUCCEEDED(enumerator->HasMore(&hasMore)) && hasMore)
1538 {
1539 ComPtr<IHostDVDDrive> dvdDrive;
1540 CHECK_RC_BREAK(enumerator->GetNext(dvdDrive.asOutParam()));
1541 Bstr name;
1542 dvdDrive->COMGETTER(Name)(name.asOutParam());
1543 RTPrintf("Name: %lS\n\n", name.raw());
1544 }
1545 }
1546 }
1547 else
1548 if (strcmp(argv[0], "hostfloppies") == 0)
1549 {
1550 ComPtr<IHost> host;
1551 CHECK_ERROR(virtualBox, COMGETTER(Host)(host.asOutParam()));
1552 ComPtr<IHostFloppyDriveCollection> coll;
1553 ComPtr<IHostFloppyDriveEnumerator> enumerator;
1554 CHECK_ERROR(host, COMGETTER(FloppyDrives)(coll.asOutParam()));
1555 if (SUCCEEDED(rc) && coll)
1556 {
1557 CHECK_ERROR(coll, Enumerate(enumerator.asOutParam()));
1558 BOOL hasMore;
1559 while (SUCCEEDED(enumerator->HasMore(&hasMore)) && hasMore)
1560 {
1561 ComPtr<IHostFloppyDrive> floppyDrive;
1562 CHECK_RC_BREAK(enumerator->GetNext(floppyDrive.asOutParam()));
1563 Bstr name;
1564 floppyDrive->COMGETTER(Name)(name.asOutParam());
1565 RTPrintf("Name: %lS\n\n", name.raw());
1566 }
1567 }
1568 }
1569#ifdef __WIN__
1570 else
1571 if (strcmp(argv[0], "hostifs") == 0)
1572 {
1573 ComPtr<IHost> host;
1574 CHECK_ERROR(virtualBox, COMGETTER(Host)(host.asOutParam()));
1575 ComPtr<IHostNetworkInterfaceCollection> coll;
1576 ComPtr<IHostNetworkInterfaceEnumerator> enumerator;
1577 CHECK_ERROR(host, COMGETTER(NetworkInterfaces)(coll.asOutParam()));
1578 if (SUCCEEDED(rc) && coll)
1579 {
1580 CHECK_ERROR(coll, Enumerate(enumerator.asOutParam()));
1581 BOOL hasMore;
1582 while (SUCCEEDED(enumerator->HasMore(&hasMore)) && hasMore)
1583 {
1584 ComPtr<IHostNetworkInterface> networkInterface;
1585 CHECK_RC_BREAK(enumerator->GetNext(networkInterface.asOutParam()));
1586 Bstr interfaceName;
1587 networkInterface->COMGETTER(Name)(interfaceName.asOutParam());
1588 RTPrintf("Name: %lS\n", interfaceName.raw());
1589 Guid interfaceGuid;
1590 networkInterface->COMGETTER(Id)(interfaceGuid.asOutParam());
1591 RTPrintf("GUID: %lS\n\n", Bstr(interfaceGuid.toString()));
1592 }
1593 }
1594 }
1595#endif /* __WIN__ */
1596 else
1597 if (strcmp(argv[0], "hdds") == 0)
1598 {
1599 ComPtr<IHardDiskCollection> hddColl;
1600 CHECK_ERROR(virtualBox, COMGETTER(HardDisks)(hddColl.asOutParam()));
1601 ComPtr<IHardDiskEnumerator> enumerator;
1602 CHECK_ERROR(hddColl, Enumerate(enumerator.asOutParam()));
1603 BOOL hasMore;
1604 while (SUCCEEDED(enumerator->HasMore(&hasMore)) && hasMore)
1605 {
1606 ComPtr<IHardDisk> hdd;
1607 CHECK_RC_BREAK(enumerator->GetNext(hdd.asOutParam()));
1608 Guid uuid;
1609 hdd->COMGETTER(Id)(uuid.asOutParam());
1610 RTPrintf("UUID: %s\n", uuid.toString().raw());
1611 HardDiskStorageType_T storageType;
1612 hdd->COMGETTER(StorageType)(&storageType);
1613 char *storageTypeString = "unknown";
1614 switch (storageType)
1615 {
1616 case HardDiskStorageType_VirtualDiskImage:
1617 storageTypeString = "Virtual Disk Image";
1618 break;
1619 case HardDiskStorageType_ISCSIHardDisk:
1620 storageTypeString = "iSCSI hard disk";
1621 break;
1622 }
1623 RTPrintf("Storage type: %s\n", storageTypeString);
1624 Bstr filepath;
1625 /// @todo (dmik) we temporarily use the location property to
1626 // determine the image file name. This is subject to change
1627 // when iSCSI disks are here (we should either query a
1628 // storage-specific interface from IHardDisk, or "standardize"
1629 // the location property)
1630 hdd->COMGETTER(Location)(filepath.asOutParam());
1631 RTPrintf("Path: %lS\n", filepath.raw());
1632 BOOL fAccessible;
1633 hdd->COMGETTER(AllAccessible)(&fAccessible);
1634 RTPrintf("Accessible: %s\n", fAccessible ? "yes" : "no");
1635 Guid machineUUID;
1636 hdd->COMGETTER(MachineId)(machineUUID.asOutParam());
1637 if (!machineUUID.isEmpty())
1638 {
1639 ComPtr<IMachine> machine;
1640 CHECK_ERROR(virtualBox, GetMachine(machineUUID, machine.asOutParam()));
1641 ASSERT(machine);
1642 Bstr name;
1643 machine->COMGETTER(Name)(name.asOutParam());
1644 machine->COMGETTER(Id)(uuid.asOutParam());
1645 RTPrintf("Usage: %lS (UUID: %s)\n", name.raw(), uuid.toString().raw());
1646 }
1647 RTPrintf("\n");
1648 }
1649 }
1650 else
1651 if (strcmp(argv[0], "dvds") == 0)
1652 {
1653 ComPtr<IDVDImageCollection> dvdColl;
1654 CHECK_ERROR(virtualBox, COMGETTER(DVDImages)(dvdColl.asOutParam()));
1655 ComPtr<IDVDImageEnumerator> enumerator;
1656 CHECK_ERROR(dvdColl, Enumerate(enumerator.asOutParam()));
1657 BOOL hasMore;
1658 while (SUCCEEDED(enumerator->HasMore(&hasMore)) && hasMore)
1659 {
1660 ComPtr<IDVDImage> dvdImage;
1661 CHECK_RC_BREAK(enumerator->GetNext(dvdImage.asOutParam()));
1662 Guid uuid;
1663 dvdImage->COMGETTER(Id)(uuid.asOutParam());
1664 RTPrintf("UUID: %s\n", uuid.toString().raw());
1665 Bstr filePath;
1666 dvdImage->COMGETTER(FilePath)(filePath.asOutParam());
1667 RTPrintf("Path: %lS\n", filePath.raw());
1668 BOOL fAccessible;
1669 dvdImage->COMGETTER(Accessible)(&fAccessible);
1670 RTPrintf("Accessible: %s\n", fAccessible ? "yes" : "no");
1671 Bstr machineUUIDs;
1672 CHECK_ERROR(virtualBox, GetDVDImageUsage(uuid, ResourceUsage_AllUsage, machineUUIDs.asOutParam()));
1673 /** @todo usage */
1674 RTPrintf("\n");
1675 }
1676 }
1677 else
1678 if (strcmp(argv[0], "floppies") == 0)
1679 {
1680 ComPtr<IFloppyImageCollection> floppyColl;
1681 CHECK_ERROR(virtualBox, COMGETTER(FloppyImages)(floppyColl.asOutParam()));
1682 ComPtr<IFloppyImageEnumerator> enumerator;
1683 CHECK_ERROR(floppyColl, Enumerate(enumerator.asOutParam()));
1684 BOOL hasMore;
1685 while (SUCCEEDED(enumerator->HasMore(&hasMore)) && hasMore)
1686 {
1687 ComPtr<IFloppyImage> floppyImage;
1688 CHECK_RC_BREAK(enumerator->GetNext(floppyImage.asOutParam()));
1689 Guid uuid;
1690 floppyImage->COMGETTER(Id)(uuid.asOutParam());
1691 RTPrintf("UUID: %s\n", uuid.toString().raw());
1692 Bstr filePath;
1693 floppyImage->COMGETTER(FilePath)(filePath.asOutParam());
1694 RTPrintf("Path: %lS\n", filePath.raw());
1695 BOOL fAccessible;
1696 floppyImage->COMGETTER(Accessible)(&fAccessible);
1697 RTPrintf("Accessible: %s\n", fAccessible ? "yes" : "no");
1698 Bstr machineUUIDs;
1699 CHECK_ERROR(virtualBox, GetFloppyImageUsage(uuid, ResourceUsage_AllUsage, machineUUIDs.asOutParam()));
1700 /** @todo usage */
1701 RTPrintf("\n");
1702 }
1703 }
1704 else
1705 if (strcmp(argv[0], "usbhost") == 0)
1706 {
1707 ComPtr<IHost> Host;
1708 CHECK_ERROR_RET (virtualBox, COMGETTER(Host)(Host.asOutParam()), 1);
1709
1710 ComPtr<IHostUSBDeviceCollection> CollPtr;
1711 CHECK_ERROR_RET (Host, COMGETTER(USBDevices)(CollPtr.asOutParam()), 1);
1712
1713 ComPtr<IHostUSBDeviceEnumerator> EnumPtr;
1714 CHECK_ERROR_RET (CollPtr, Enumerate(EnumPtr.asOutParam()), 1);
1715
1716 RTPrintf("Host USB Devices:\n\n");
1717
1718 BOOL fMore = FALSE;
1719 rc = EnumPtr->HasMore (&fMore);
1720 ASSERT_RET (SUCCEEDED (rc), 1);
1721
1722 if (!fMore)
1723 {
1724 RTPrintf("<none>\n\n");
1725 }
1726 else
1727 while (fMore)
1728 {
1729 ComPtr <IHostUSBDevice> dev;
1730 rc = EnumPtr->GetNext (dev.asOutParam());
1731 ASSERT_RET (SUCCEEDED (rc), 1);
1732
1733 /* Query info. */
1734 Guid id;
1735 CHECK_ERROR_RET (dev, COMGETTER(Id)(id.asOutParam()), 1);
1736 USHORT usVendorId;
1737 CHECK_ERROR_RET (dev, COMGETTER(VendorId)(&usVendorId), 1);
1738 USHORT usProductId;
1739 CHECK_ERROR_RET (dev, COMGETTER(ProductId)(&usProductId), 1);
1740 USHORT bcdRevision;
1741 CHECK_ERROR_RET (dev, COMGETTER(Revision)(&bcdRevision), 1);
1742
1743 RTPrintf("UUID: %S\n"
1744 "VendorId: 0x%04x (%04X)\n"
1745 "ProductId: 0x%04x (%04X)\n"
1746 "Revision: %u.%u (%02u%02u)\n",
1747 id.toString().raw(),
1748 usVendorId, usVendorId, usProductId, usProductId,
1749 bcdRevision >> 8, bcdRevision & 0xff,
1750 bcdRevision >> 8, bcdRevision & 0xff);
1751
1752 /* optional stuff. */
1753 Bstr bstr;
1754 CHECK_ERROR_RET (dev, COMGETTER(Manufacturer)(bstr.asOutParam()), 1);
1755 if (!bstr.isEmpty())
1756 RTPrintf("Manufacturer: %lS\n", bstr.raw());
1757 CHECK_ERROR_RET (dev, COMGETTER(Product)(bstr.asOutParam()), 1);
1758 if (!bstr.isEmpty())
1759 RTPrintf("Product: %lS\n", bstr.raw());
1760 CHECK_ERROR_RET (dev, COMGETTER(SerialNumber)(bstr.asOutParam()), 1);
1761 if (!bstr.isEmpty())
1762 RTPrintf("SerialNumber: %lS\n", bstr.raw());
1763 CHECK_ERROR_RET (dev, COMGETTER(Address)(bstr.asOutParam()), 1);
1764 if (!bstr.isEmpty())
1765 RTPrintf("Address: %lS\n", bstr.raw());
1766
1767 /* current state */
1768 USBDeviceState_T state;
1769 CHECK_ERROR_RET (dev, COMGETTER(State)(&state), 1);
1770 char *pszState = "?";
1771 switch (state)
1772 {
1773 case USBDeviceState_USBDeviceNotSupported:
1774 pszState = "Not supported"; break;
1775 case USBDeviceState_USBDeviceUnavailable:
1776 pszState = "Unavailable"; break;
1777 case USBDeviceState_USBDeviceBusy:
1778 pszState = "Busy"; break;
1779 case USBDeviceState_USBDeviceAvailable:
1780 pszState = "Available"; break;
1781 case USBDeviceState_USBDeviceHeld:
1782 pszState = "Held"; break;
1783 case USBDeviceState_USBDeviceCaptured:
1784 pszState = "Captured"; break;
1785 default:
1786 ASSERT (false);
1787 break;
1788 }
1789 RTPrintf("Current State: %s\n\n", pszState);
1790
1791 rc = EnumPtr->HasMore (&fMore);
1792 ASSERT_RET (SUCCEEDED (rc), rc);
1793 }
1794 }
1795 else
1796 if (strcmp(argv[0], "usbfilters") == 0)
1797 {
1798 RTPrintf("Global USB Device Filters:\n\n");
1799
1800 ComPtr <IHost> host;
1801 CHECK_ERROR_RET (virtualBox, COMGETTER(Host) (host.asOutParam()), 1);
1802
1803 ComPtr<IHostUSBDeviceFilterCollection> coll;
1804 CHECK_ERROR_RET (host, COMGETTER (USBDeviceFilters)(coll.asOutParam()), 1);
1805
1806 ComPtr<IHostUSBDeviceFilterEnumerator> en;
1807 CHECK_ERROR_RET (coll, Enumerate(en.asOutParam()), 1);
1808
1809 ULONG index = 0;
1810 BOOL more = FALSE;
1811 rc = en->HasMore (&more);
1812 ASSERT_RET (SUCCEEDED (rc), 1);
1813
1814 if (!more)
1815 {
1816 RTPrintf("<none>\n\n");
1817 }
1818 else
1819 while (more)
1820 {
1821 ComPtr<IHostUSBDeviceFilter> flt;
1822 rc = en->GetNext (flt.asOutParam());
1823 ASSERT_RET (SUCCEEDED (rc), 1);
1824
1825 /* Query info. */
1826
1827 RTPrintf("Index: %lu\n", index);
1828
1829 BOOL active = FALSE;
1830 CHECK_ERROR_RET (flt, COMGETTER (Active) (&active), 1);
1831 RTPrintf("Active: %s\n", active ? "yes" : "no");
1832
1833 USBDeviceFilterAction_T action;
1834 CHECK_ERROR_RET (flt, COMGETTER (Action) (&action), 1);
1835 char *pszAction = "<invalid>";
1836 switch (action)
1837 {
1838 case USBDeviceFilterAction_USBDeviceFilterIgnore:
1839 pszAction = "Ignore";
1840 break;
1841 case USBDeviceFilterAction_USBDeviceFilterHold:
1842 pszAction = "Hold";
1843 break;
1844 default:
1845 break;
1846 }
1847 RTPrintf("Action: %s\n", pszAction);
1848
1849 Bstr bstr;
1850 CHECK_ERROR_RET (flt, COMGETTER (Name) (bstr.asOutParam()), 1);
1851 RTPrintf("Name: %lS\n", bstr.raw());
1852 CHECK_ERROR_RET (flt, COMGETTER (VendorId) (bstr.asOutParam()), 1);
1853 RTPrintf("VendorId: %lS\n", bstr.raw());
1854 CHECK_ERROR_RET (flt, COMGETTER (ProductId) (bstr.asOutParam()), 1);
1855 RTPrintf("ProductId: %lS\n", bstr.raw());
1856 CHECK_ERROR_RET (flt, COMGETTER (Revision) (bstr.asOutParam()), 1);
1857 RTPrintf("Revision: %lS\n", bstr.raw());
1858 CHECK_ERROR_RET (flt, COMGETTER (Manufacturer) (bstr.asOutParam()), 1);
1859 RTPrintf("Manufacturer: %lS\n", bstr.raw());
1860 CHECK_ERROR_RET (flt, COMGETTER (Product) (bstr.asOutParam()), 1);
1861 RTPrintf("Product: %lS\n", bstr.raw());
1862 CHECK_ERROR_RET (flt, COMGETTER (SerialNumber) (bstr.asOutParam()), 1);
1863 RTPrintf("Serial Number: %lS\n\n", bstr.raw());
1864
1865 rc = en->HasMore (&more);
1866 ASSERT_RET (SUCCEEDED (rc), 1);
1867
1868 index ++;
1869 }
1870 }
1871 else if (strcmp(argv[0], "systemproperties") == 0)
1872 {
1873 ComPtr<ISystemProperties> systemProperties;
1874 virtualBox->COMGETTER(SystemProperties)(systemProperties.asOutParam());
1875
1876 Bstr str;
1877 ULONG ulValue;
1878 ULONG64 ul64Value;
1879 BOOL flag;
1880
1881 systemProperties->COMGETTER(MinGuestRAM)(&ulValue);
1882 RTPrintf("Minimum guest RAM size: %u Megabytes\n", ulValue);
1883 systemProperties->COMGETTER(MaxGuestRAM)(&ulValue);
1884 RTPrintf("Maximum guest RAM size: %u Megabytes\n", ulValue);
1885 systemProperties->COMGETTER(MaxGuestVRAM)(&ulValue);
1886 RTPrintf("Maximum video RAM size: %u Megabytes\n", ulValue);
1887 systemProperties->COMGETTER(MaxVDISize)(&ul64Value);
1888 RTPrintf("Maximum VDI size: %lu Megabytes\n", ul64Value);
1889 systemProperties->COMGETTER(DefaultVDIFolder)(str.asOutParam());
1890 RTPrintf("Default VDI filder: %lS\n", str.raw());
1891 systemProperties->COMGETTER(DefaultMachineFolder)(str.asOutParam());
1892 RTPrintf("Default machine folder: %lS\n", str.raw());
1893 systemProperties->COMGETTER(RemoteDisplayAuthLibrary)(str.asOutParam());
1894 RTPrintf("VRDP authentication library: %lS\n", str.raw());
1895 systemProperties->COMGETTER(HWVirtExEnabled)(&flag);
1896 RTPrintf("Hardware virt. extensions: %s\n", flag ? "yes" : "no");
1897
1898 }
1899 else
1900 {
1901 return errorSyntax(USAGE_LIST, "Invalid parameter '%s'", Utf8Str(argv[0]).raw());
1902 }
1903 return SUCCEEDED(rc) ? 0 : 1;
1904}
1905
1906static int handleRegisterVM(int argc, char *argv[],
1907 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
1908{
1909 HRESULT rc;
1910
1911 if (argc != 1)
1912 {
1913 return errorSyntax(USAGE_REGISTERVM, "Incorrect number of parameters");
1914 }
1915
1916 ComPtr<IMachine> machine;
1917 CHECK_ERROR(virtualBox, OpenMachine(Bstr(argv[0]), machine.asOutParam()));
1918 if (SUCCEEDED(rc))
1919 {
1920 ASSERT(machine);
1921 CHECK_ERROR(virtualBox, RegisterMachine(machine));
1922 }
1923 return SUCCEEDED(rc) ? 0 : 1;
1924}
1925
1926static int handleUnregisterVM(int argc, char *argv[],
1927 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
1928{
1929 HRESULT rc;
1930
1931 if ((argc != 1) && (argc != 2))
1932 {
1933 return errorSyntax(USAGE_UNREGISTERVM, "Incorrect number of parameters");
1934 }
1935
1936 ComPtr<IMachine> machine;
1937 /* assume it's a UUID */
1938 rc = virtualBox->GetMachine(Guid(argv[0]), machine.asOutParam());
1939 if (FAILED(rc) || !machine)
1940 {
1941 /* must be a name */
1942 CHECK_ERROR(virtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam()));
1943 }
1944 if (machine)
1945 {
1946 Guid uuid;
1947 machine->COMGETTER(Id)(uuid.asOutParam());
1948 machine = NULL;
1949 CHECK_ERROR(virtualBox, UnregisterMachine(uuid, machine.asOutParam()));
1950 if (SUCCEEDED(rc) && machine)
1951 {
1952 /* are we supposed to delete the config file? */
1953 if ((argc == 2) && (strcmp(argv[1], "-delete") == 0))
1954 {
1955 CHECK_ERROR(machine, DeleteSettings());
1956 }
1957 }
1958 }
1959 return SUCCEEDED(rc) ? 0 : 1;
1960}
1961
1962static int handleCreateVDI(int argc, char *argv[],
1963 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
1964{
1965 HRESULT rc;
1966 Bstr filename;
1967 uint64_t sizeMB = 0;
1968 bool fStatic = false;
1969 Bstr comment;
1970 bool fRegister = false;
1971 char *type = "normal";
1972
1973 /* let's have a closer look at the arguments */
1974 for (int i = 0; i < argc; i++)
1975 {
1976 if (strcmp(argv[i], "-filename") == 0)
1977 {
1978 if (argc <= i + 1)
1979 {
1980 return errorArgument("Missing argument to '%s'", argv[i]);
1981 }
1982 i++;
1983 filename = argv[i];
1984 }
1985 else if (strcmp(argv[i], "-size") == 0)
1986 {
1987 if (argc <= i + 1)
1988 {
1989 return errorArgument("Missing argument to '%s'", argv[i]);
1990 }
1991 i++;
1992 sizeMB = RTStrToUInt64(argv[i]);
1993 }
1994 else if (strcmp(argv[i], "-static") == 0)
1995 {
1996 fStatic = true;
1997 }
1998 else if (strcmp(argv[i], "-comment") == 0)
1999 {
2000 if (argc <= i + 1)
2001 {
2002 return errorArgument("Missing argument to '%s'", argv[i]);
2003 }
2004 i++;
2005 comment = argv[i];
2006 }
2007 else if (strcmp(argv[i], "-register") == 0)
2008 {
2009 fRegister = true;
2010 }
2011 else if (strcmp(argv[i], "-type") == 0)
2012 {
2013 if (argc <= i + 1)
2014 {
2015 return errorArgument("Missing argument to '%s'", argv[i]);
2016 }
2017 i++;
2018 type = argv[i];
2019 }
2020 else
2021 {
2022 return errorSyntax(USAGE_CREATEVDI, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());
2023 }
2024 }
2025 /* check the outcome */
2026 if (!filename || (sizeMB == 0))
2027 {
2028 return errorSyntax(USAGE_CREATEVDI, "Parameters -filename and -size are required");
2029 }
2030 if (strcmp(type, "normal") && strcmp(type, "writethrough"))
2031 {
2032 return errorArgument("Invalid VDI type '%s' specified", Utf8Str(type).raw());
2033 }
2034
2035 ComPtr<IHardDisk> hardDisk;
2036 CHECK_ERROR(virtualBox, CreateHardDisk(HardDiskStorageType_VirtualDiskImage, hardDisk.asOutParam()));
2037 if (SUCCEEDED(rc) && hardDisk)
2038 {
2039 CHECK_ERROR(hardDisk,COMSETTER(Description)(comment));
2040 ComPtr<IVirtualDiskImage> vdi = hardDisk;
2041 CHECK_ERROR(vdi, COMSETTER(FilePath)(filename));
2042 ComPtr<IProgress> progress;
2043 if (fStatic)
2044 {
2045 CHECK_ERROR(vdi, CreateFixedImage(sizeMB, progress.asOutParam()));
2046 }
2047 else
2048 {
2049 CHECK_ERROR(vdi, CreateDynamicImage(sizeMB, progress.asOutParam()));
2050 }
2051 if (SUCCEEDED(rc) && progress)
2052 {
2053 CHECK_ERROR(progress, WaitForCompletion(-1));
2054 if (SUCCEEDED(rc))
2055 {
2056 progress->COMGETTER(ResultCode)(&rc);
2057 if (FAILED(rc))
2058 {
2059 com::ProgressErrorInfo info(progress);
2060 if (info.isBasicAvailable())
2061 {
2062 RTPrintf("Error: failed to create disk image. Error message: %lS\n", info.getText().raw());
2063 }
2064 else
2065 {
2066 RTPrintf("Error: failed to create disk image. No error message available!\n");
2067 }
2068 }
2069 else
2070 {
2071 Guid uuid;
2072 CHECK_ERROR(hardDisk, COMGETTER(Id)(uuid.asOutParam()));
2073
2074 if (strcmp(type, "normal") == 0)
2075 {
2076 /* nothing required, default */
2077 }
2078 else if (strcmp(type, "writethrough") == 0)
2079 {
2080 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_WritethroughHardDisk));
2081 }
2082
2083 RTPrintf("Disk image created. UUID: %s\n", uuid.toString().raw());
2084 }
2085 }
2086 }
2087 if (SUCCEEDED(rc) && fRegister)
2088 {
2089 CHECK_ERROR(virtualBox, RegisterHardDisk(hardDisk));
2090 }
2091 }
2092 return SUCCEEDED(rc) ? 0 : 1;
2093}
2094
2095static DECLCALLBACK(int) vdiProgressCallback(PVM pVM, unsigned uPercent, void *pvUser)
2096{
2097 unsigned *pPercent = (unsigned *)pvUser;
2098
2099 if (*pPercent != uPercent)
2100 {
2101 *pPercent = uPercent;
2102 RTPrintf(".");
2103 if ((uPercent % 10) == 0 && uPercent)
2104 RTPrintf("%d%%", uPercent);
2105 RTStrmFlush(g_pStdOut);
2106 }
2107
2108 return VINF_SUCCESS;
2109}
2110
2111
2112static int handleModifyVDI(int argc, char *argv[],
2113 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
2114{
2115 HRESULT rc;
2116
2117 /* The uuid/filename and a command */
2118 if (argc < 2)
2119 {
2120 return errorSyntax(USAGE_MODIFYVDI, "Incorrect number of parameters");
2121 }
2122
2123 ComPtr<IHardDisk> hardDisk;
2124 ComPtr<IVirtualDiskImage> vdi;
2125 Bstr filepath;
2126
2127 /* first guess is that it's a UUID */
2128 Guid uuid(argv[0]);
2129 rc = virtualBox->GetHardDisk(uuid, hardDisk.asOutParam());
2130 /* no? then it must be a filename */
2131 if (!hardDisk)
2132 {
2133 filepath = argv[0];
2134 CHECK_ERROR(virtualBox, FindVirtualDiskImage(filepath, vdi.asOutParam()));
2135 hardDisk = vdi;
2136 }
2137 else
2138 {
2139 vdi = hardDisk;
2140 }
2141
2142 /* let's find out which command */
2143// doesn't currently work if (strcmp(argv[1], "settype") == 0)
2144 if (0)
2145 {
2146 /* hard disk must be registered */
2147 if (SUCCEEDED(rc) && hardDisk && vdi)
2148 {
2149 char *type = NULL;
2150
2151 if (argc <= 2)
2152 {
2153 return errorArgument("Missing argument to for settype");
2154 }
2155 type = argv[2];
2156
2157 HardDiskType_T hddType;
2158 CHECK_ERROR(hardDisk, COMGETTER(Type)(&hddType));
2159
2160 if (strcmp(type, "normal") == 0)
2161 {
2162 if (hddType != HardDiskType_NormalHardDisk)
2163 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_NormalHardDisk));
2164 }
2165 else if (strcmp(type, "writethrough") == 0)
2166 {
2167 if (hddType != HardDiskType_WritethroughHardDisk)
2168 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_WritethroughHardDisk));
2169
2170 }
2171 else if (strcmp(type, "immutable") == 0)
2172 {
2173 if (hddType != HardDiskType_ImmutableHardDisk)
2174 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_ImmutableHardDisk));
2175 }
2176 else
2177 {
2178 return errorArgument("Invalid VDI type '%s' specified", Utf8Str(type).raw());
2179 }
2180 }
2181 else
2182 {
2183 return errorArgument("Hard disk image not registered");
2184 }
2185 }
2186 else if (strcmp(argv[1], "compact") == 0)
2187 {
2188 ComPtr<IVirtualDiskImage> vdi;
2189
2190 /* the hard disk image might not be registered */
2191 if (!hardDisk)
2192 {
2193 virtualBox->OpenVirtualDiskImage(Bstr(argv[0]), vdi.asOutParam());
2194 if (!hardDisk)
2195 {
2196 return errorArgument("Hard disk image not found");
2197 }
2198 }
2199 else
2200 vdi = hardDisk;
2201
2202 if (!vdi)
2203 return errorArgument("Invalid hard disk type. The command only works on VDI files\n");
2204
2205 Bstr fileName;
2206 vdi->COMGETTER(FilePath)(fileName.asOutParam());
2207
2208 /* close the file */
2209 hardDisk = NULL;
2210 vdi = NULL;
2211
2212 unsigned uProcent;
2213
2214 RTPrintf("Shrinking '%lS': 0%%", fileName.raw());
2215 int vrc = VDIShrinkImage(Utf8Str(fileName).raw(), vdiProgressCallback, &uProcent);
2216 if (VBOX_FAILURE(vrc))
2217 {
2218 RTPrintf("Error while shrinking hard disk image: %Vrc\n", vrc);
2219 rc = E_FAIL;
2220 }
2221 }
2222 else
2223 {
2224 return errorSyntax(USAGE_MODIFYVDI, "Invalid parameter '%s'", Utf8Str(argv[1]).raw());
2225 }
2226 return SUCCEEDED(rc) ? 0 : 1;
2227}
2228
2229static int handleCloneVDI(int argc, char *argv[],
2230 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
2231{
2232 HRESULT rc;
2233
2234 /* source VDI and target path */
2235 if (argc != 2)
2236 {
2237 return errorSyntax(USAGE_CLONEVDI, "Incorrect number of parameters");
2238 }
2239
2240 /* first guess is that it's a UUID */
2241 Guid uuid(argv[0]);
2242 ComPtr<IHardDisk> hardDisk;
2243 rc = virtualBox->GetHardDisk(uuid, hardDisk.asOutParam());
2244 if (!hardDisk)
2245 {
2246 /* not successful? Then it must be a filename */
2247 ComPtr<IVirtualDiskImage> vdi;
2248 CHECK_ERROR(virtualBox, OpenVirtualDiskImage(Bstr(argv[0]), vdi.asOutParam()));
2249 hardDisk = vdi;
2250 }
2251 if (hardDisk)
2252 {
2253 ComPtr<IVirtualDiskImage> vdiOut;
2254 ComPtr<IProgress> progress;
2255 CHECK_ERROR(hardDisk, CloneToImage(Bstr(argv[1]), vdiOut.asOutParam(), progress.asOutParam()));
2256 if (SUCCEEDED(rc))
2257 {
2258 showProgress(progress);
2259 progress->COMGETTER(ResultCode)(&rc);
2260 if (FAILED(rc))
2261 {
2262 com::ProgressErrorInfo info(progress);
2263 if (info.isBasicAvailable())
2264 {
2265 RTPrintf("Error: failed to clone disk image. Error message: %lS\n", info.getText().raw());
2266 }
2267 else
2268 {
2269 RTPrintf("Error: failed to clone disk image. No error message available!\n");
2270 }
2271 }
2272 }
2273 }
2274 return SUCCEEDED(rc) ? 0 : 1;
2275}
2276
2277static int handleAddiSCSIDisk(int argc, char *argv[],
2278 ComPtr <IVirtualBox> aVirtualBox, ComPtr<ISession> aSession)
2279{
2280 HRESULT rc;
2281 Bstr server;
2282 Bstr target;
2283 uint16_t port = UINT16_MAX;
2284 uint64_t lun = UINT64_MAX;
2285 Bstr username;
2286 Bstr password;
2287 Bstr comment;
2288
2289 /* at least server and target */
2290 if (argc < 4)
2291 {
2292 return errorSyntax(USAGE_ADDISCSIDISK, "Not enough parameters");
2293 }
2294
2295 /* let's have a closer look at the arguments */
2296 for (int i = 0; i < argc; i++)
2297 {
2298 if (strcmp(argv[i], "-server") == 0)
2299 {
2300 if (argc <= i + 1)
2301 {
2302 return errorArgument("Missing argument to '%s'", argv[i]);
2303 }
2304 i++;
2305 server = argv[i];
2306 }
2307 else if (strcmp(argv[i], "-target") == 0)
2308 {
2309 if (argc <= i + 1)
2310 {
2311 return errorArgument("Missing argument to '%s'", argv[i]);
2312 }
2313 i++;
2314 target = argv[i];
2315 }
2316 else if (strcmp(argv[i], "-port") == 0)
2317 {
2318 if (argc <= i + 1)
2319 {
2320 return errorArgument("Missing argument to '%s'", argv[i]);
2321 }
2322 i++;
2323 port = atoi(argv[i]);
2324 }
2325 else if (strcmp(argv[i], "-lun") == 0)
2326 {
2327 /** @todo move the LUN encoding algorithm into IISCSIHardDisk, add decoding */
2328 if (argc <= i + 1)
2329 {
2330 return errorArgument("Missing argument to '%s'", argv[i]);
2331 }
2332 i++;
2333 char *pszNext;
2334 int rc = RTStrToUInt64Ex(argv[i], &pszNext, 0, &lun);
2335 if (VBOX_FAILURE(rc) || *pszNext != '\0' || lun >= 16384)
2336 return errorArgument("Invalid LUN number '%s'", argv[i]);
2337 if (lun <= 255)
2338 {
2339 /* Assume bus identifier = 0. */
2340 lun = (lun << 48); /* uses peripheral device addressing method */
2341 }
2342 else
2343 {
2344 /* Check above already limited the LUN to 14 bits. */
2345 lun = (lun << 48) | RT_BIT_64(62); /* uses flat space addressing method */
2346 }
2347 }
2348 else if (strcmp(argv[i], "-encodedlun") == 0)
2349 {
2350 if (argc <= i + 1)
2351 {
2352 return errorArgument("Missing argument to '%s'", argv[i]);
2353 }
2354 i++;
2355 char *pszNext;
2356 int rc = RTStrToUInt64Ex(argv[i], &pszNext, 0, &lun);
2357 if (VBOX_FAILURE(rc) || *pszNext != '\0')
2358 return errorArgument("Invalid encoded LUN number '%s'", argv[i]);
2359 }
2360 else if (strcmp(argv[i], "-username") == 0)
2361 {
2362 if (argc <= i + 1)
2363 {
2364 return errorArgument("Missing argument to '%s'", argv[i]);
2365 }
2366 i++;
2367 username = argv[i];
2368 }
2369 else if (strcmp(argv[i], "-password") == 0)
2370 {
2371 if (argc <= i + 1)
2372 {
2373 return errorArgument("Missing argument to '%s'", argv[i]);
2374 }
2375 i++;
2376 password = argv[i];
2377 }
2378 else if (strcmp(argv[i], "-comment") == 0)
2379 {
2380 if (argc <= i + 1)
2381 {
2382 return errorArgument("Missing argument to '%s'", argv[i]);
2383 }
2384 i++;
2385 comment = argv[i];
2386 }
2387 else
2388 {
2389 return errorSyntax(USAGE_ADDISCSIDISK, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());
2390 }
2391 }
2392
2393 /* check for required options */
2394 if (!server || !target)
2395 {
2396 return errorSyntax(USAGE_ADDISCSIDISK, "Parameters -server and -target are required");
2397 }
2398
2399 ComPtr<IHardDisk> hardDisk;
2400 CHECK_ERROR(aVirtualBox, CreateHardDisk(HardDiskStorageType_ISCSIHardDisk, hardDisk.asOutParam()));
2401 if (SUCCEEDED(rc) && hardDisk)
2402 {
2403 CHECK_ERROR(hardDisk, COMSETTER(Description)(comment));
2404 ComPtr<IISCSIHardDisk> iSCSIDisk = hardDisk;
2405 CHECK_ERROR(iSCSIDisk, COMSETTER(Server)(server));
2406 if (port != UINT16_MAX)
2407 CHECK_ERROR(iSCSIDisk, COMSETTER(Port)(port));
2408 CHECK_ERROR(iSCSIDisk, COMSETTER(Target)(target));
2409 if (lun != UINT64_MAX)
2410 CHECK_ERROR(iSCSIDisk, COMSETTER(Lun)(lun));
2411 CHECK_ERROR(iSCSIDisk, COMSETTER(UserName)(username));
2412 CHECK_ERROR(iSCSIDisk, COMSETTER(Password)(password));
2413
2414 if (SUCCEEDED(rc))
2415 {
2416 CHECK_ERROR(aVirtualBox, RegisterHardDisk(hardDisk));
2417 }
2418
2419 if (SUCCEEDED(rc))
2420 {
2421 Guid guid;
2422 CHECK_ERROR(hardDisk, COMGETTER(Id)(guid.asOutParam()));
2423 RTPrintf("iSCSI disk created. UUID: %s\n", guid.toString().raw());
2424 }
2425 }
2426
2427 return SUCCEEDED(rc) ? 0 : 1;
2428}
2429
2430static int handleCreateVM(int argc, char *argv[],
2431 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
2432{
2433 HRESULT rc;
2434 Bstr baseFolder;
2435 Bstr settingsFile;
2436 Bstr name;
2437 bool fRegister = false;
2438
2439 for (int i = 0; i < argc; i++)
2440 {
2441 if (strcmp(argv[i], "-basefolder") == 0)
2442 {
2443 if (argc <= i + 1)
2444 {
2445 return errorArgument("Missing argument to '%s'", argv[i]);
2446 }
2447 i++;
2448 baseFolder = argv[i];
2449 }
2450 else if (strcmp(argv[i], "-settingsfile") == 0)
2451 {
2452 if (argc <= i + 1)
2453 {
2454 return errorArgument("Missing argument to '%s'", argv[i]);
2455 }
2456 i++;
2457 settingsFile = argv[i];
2458 }
2459 else if (strcmp(argv[i], "-name") == 0)
2460 {
2461 if (argc <= i + 1)
2462 {
2463 return errorArgument("Missing argument to '%s'", argv[i]);
2464 }
2465 i++;
2466 name = argv[i];
2467 }
2468 else if (strcmp(argv[i], "-register") == 0)
2469 {
2470 fRegister = true;
2471 }
2472 else
2473 {
2474 return errorSyntax(USAGE_CREATEVM, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());
2475 }
2476 }
2477 if (!name)
2478 {
2479 return errorSyntax(USAGE_CREATEVM, "Parameter -name is required");
2480 }
2481 if (!!baseFolder && !!settingsFile)
2482 {
2483 return errorSyntax(USAGE_CREATEVM, "Either -basefolder or -settingsfile may be specified");
2484 }
2485
2486 do
2487 {
2488 ComPtr<IMachine> machine;
2489
2490 if (!settingsFile)
2491 CHECK_ERROR_BREAK(virtualBox,
2492 CreateMachine(baseFolder, name, machine.asOutParam()));
2493 else
2494 CHECK_ERROR_BREAK(virtualBox,
2495 CreateLegacyMachine(settingsFile, name, machine.asOutParam()));
2496
2497 CHECK_ERROR_BREAK(machine, SaveSettings());
2498 if (fRegister)
2499 {
2500 CHECK_ERROR_BREAK(virtualBox, RegisterMachine(machine));
2501 }
2502 Guid uuid;
2503 CHECK_ERROR_BREAK(machine, COMGETTER(Id)(uuid.asOutParam()));
2504 CHECK_ERROR_BREAK(machine, COMGETTER(SettingsFilePath)(settingsFile.asOutParam()));
2505 RTPrintf("Virtual machine '%ls' is created%s.\n"
2506 "UUID: %s\n"
2507 "Settings file: '%ls'\n",
2508 name.raw(), fRegister ? " and registered" : "",
2509 uuid.toString().raw(), settingsFile.raw());
2510 }
2511 while (0);
2512
2513 return SUCCEEDED(rc) ? 0 : 1;
2514}
2515
2516/**
2517 * Parses a NIC number.
2518 *
2519 * @returns Valid nic number on success.
2520 * @returns 0 if invalid nic. All necesary bitching has been done.
2521 * @param psz Pointer to the nic number.
2522 */
2523static unsigned parseNicNum(const char *psz, unsigned cMaxNics)
2524{
2525 uint32_t u32;
2526 char *pszNext;
2527 int rc = RTStrToUInt32Ex(psz, &pszNext, 10, &u32);
2528 if ( VBOX_SUCCESS(rc)
2529 && *pszNext == '\0'
2530 && u32 >= 1
2531 && u32 <= cMaxNics)
2532 return (unsigned)u32;
2533 errorArgument("Invalid NIC number '%s'", psz);
2534 return 0;
2535}
2536
2537static int handleModifyVM(int argc, char *argv[],
2538 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
2539{
2540 HRESULT rc;
2541 Bstr name;
2542 Bstr ostype;
2543 ULONG memorySize = 0;
2544 ULONG vramSize = 0;
2545 char *acpi = NULL;
2546 char *hwvirtex = NULL;
2547 char *ioapic = NULL;
2548 char *bioslogofadein = NULL;
2549 char *bioslogofadeout = NULL;
2550 uint32_t bioslogodisplaytime = ~0;
2551 char *bioslogoimagepath = NULL;
2552 char *biosbootmenumode = NULL;
2553 DeviceType_T bootDevice[4];
2554 int bootDeviceChanged[4] = { false };
2555 char *hdds[4] = {0};
2556 char *dvd = NULL;
2557 char *dvdpassthrough = NULL;
2558 char *floppy = NULL;
2559 char *audio = NULL;
2560#ifdef VBOX_VRDP
2561 char *vrdp = NULL;
2562 uint16_t vrdpport = UINT16_MAX;
2563 char *vrdpauthtype = NULL;
2564#endif
2565 int fUsbEnabled = -1;
2566 char *snapshotFolder = NULL;
2567
2568 /* VM ID + at least one parameter + value */
2569 if (argc < 3)
2570 {
2571 return errorSyntax(USAGE_MODIFYVM, "Not enough parameters");
2572 }
2573
2574 /* Get the number of network adapters */
2575 ULONG NetworkAdapterCount = 0;
2576 {
2577 ComPtr <ISystemProperties> info;
2578 CHECK_ERROR_RET (virtualBox, COMGETTER(SystemProperties) (info.asOutParam()), 1);
2579 CHECK_ERROR_RET (info, COMGETTER(NetworkAdapterCount) (&NetworkAdapterCount), 1);
2580 }
2581
2582 std::vector <char *> nics (NetworkAdapterCount, 0);
2583 std::vector <char *> nictype (NetworkAdapterCount, 0);
2584 std::vector <char *> cableconnected (NetworkAdapterCount, 0);
2585 std::vector <char *> nictrace (NetworkAdapterCount, 0);
2586 std::vector <char *> nictracefile (NetworkAdapterCount, 0);
2587 std::vector <char *> hostifdev (NetworkAdapterCount, 0);
2588 std::vector <const char *> intnet (NetworkAdapterCount, 0);
2589#ifdef __LINUX__
2590 std::vector <char *> tapsetup (NetworkAdapterCount, 0);
2591 std::vector <char *> tapterm (NetworkAdapterCount, 0);
2592#endif
2593 std::vector <char *> macs (NetworkAdapterCount, 0);
2594
2595 for (int i = 1; i < argc; i++)
2596 {
2597 if (strcmp(argv[i], "-name") == 0)
2598 {
2599 if (argc <= i + 1)
2600 {
2601 return errorArgument("Missing argument to '%s'", argv[i]);
2602 }
2603 i++;
2604 name = argv[i];
2605 }
2606 else if (strcmp(argv[i], "-ostype") == 0)
2607 {
2608 if (argc <= i + 1)
2609 {
2610 return errorArgument("Missing argument to '%s'", argv[i]);
2611 }
2612 i++;
2613 ostype = argv[i];
2614 }
2615 else if (strcmp(argv[i], "-memory") == 0)
2616 {
2617 if (argc <= i + 1)
2618 {
2619 return errorArgument("Missing argument to '%s'", argv[i]);
2620 }
2621 i++;
2622 memorySize = atoi(argv[i]);
2623 }
2624 else if (strcmp(argv[i], "-vram") == 0)
2625 {
2626 if (argc <= i + 1)
2627 {
2628 return errorArgument("Missing argument to '%s'", argv[i]);
2629 }
2630 i++;
2631 vramSize = atoi(argv[i]);
2632 }
2633 else if (strcmp(argv[i], "-acpi") == 0)
2634 {
2635 if (argc <= i + 1)
2636 {
2637 return errorArgument("Missing argument to '%s'", argv[i]);
2638 }
2639 i++;
2640 acpi = argv[i];
2641 }
2642 else if (strcmp(argv[i], "-ioapic") == 0)
2643 {
2644 if (argc <= i + 1)
2645 {
2646 return errorArgument("Missing argument to '%s'", argv[i]);
2647 }
2648 i++;
2649 ioapic = argv[i];
2650 }
2651 else if (strcmp(argv[i], "-hwvirtex") == 0)
2652 {
2653 if (argc <= i + 1)
2654 {
2655 return errorArgument("Missing argument to '%s'", argv[i]);
2656 }
2657 i++;
2658 hwvirtex = argv[i];
2659 }
2660 else if (strcmp(argv[i], "-bioslogofadein") == 0)
2661 {
2662 if (argc <= i + 1)
2663 {
2664 return errorArgument("Missing argument to '%s'", argv[i]);
2665 }
2666 i++;
2667 bioslogofadein = argv[i];
2668 }
2669 else if (strcmp(argv[i], "-bioslogofadeout") == 0)
2670 {
2671 if (argc <= i + 1)
2672 {
2673 return errorArgument("Missing argument to '%s'", argv[i]);
2674 }
2675 i++;
2676 bioslogofadeout = argv[i];
2677 }
2678 else if (strcmp(argv[i], "-bioslogodisplaytime") == 0)
2679 {
2680 if (argc <= i + 1)
2681 {
2682 return errorArgument("Missing argument to '%s'", argv[i]);
2683 }
2684 i++;
2685 bioslogodisplaytime = atoi(argv[i]);
2686 }
2687 else if (strcmp(argv[i], "-bioslogoimagepath") == 0)
2688 {
2689 if (argc <= i + 1)
2690 {
2691 return errorArgument("Missing argument to '%s'", argv[i]);
2692 }
2693 i++;
2694 bioslogoimagepath = argv[i];
2695 }
2696 else if (strcmp(argv[i], "-biosbootmenu") == 0)
2697 {
2698 if (argc <= i + 1)
2699 {
2700 return errorArgument("Missing argument to '%s'", argv[i]);
2701 }
2702 i++;
2703 biosbootmenumode = argv[i];
2704 }
2705 else if (strncmp(argv[i], "-boot", 5) == 0)
2706 {
2707 ULONG n = 0;
2708 if (!argv[i][5])
2709 {
2710 return errorSyntax(USAGE_MODIFYVM, "Missing boot slot number in '%s'", argv[i]);
2711 }
2712 if ((n = strtoul(&argv[i][5], NULL, 10)) < 1)
2713 {
2714 return errorSyntax(USAGE_MODIFYVM, "Invalid boot slot number in '%s'", argv[i]);
2715 }
2716 if (argc <= i + 1)
2717 {
2718 return errorArgument("Missing argument to '%s'", argv[i]);
2719 }
2720 i++;
2721 if (strcmp(argv[i], "none") == 0)
2722 {
2723 bootDevice[n - 1] = DeviceType_NoDevice;
2724 }
2725 else if (strcmp(argv[i], "floppy") == 0)
2726 {
2727 bootDevice[n - 1] = DeviceType_FloppyDevice;
2728 }
2729 else if (strcmp(argv[i], "dvd") == 0)
2730 {
2731 bootDevice[n - 1] = DeviceType_DVDDevice;
2732 }
2733 else if (strcmp(argv[i], "disk") == 0)
2734 {
2735 bootDevice[n - 1] = DeviceType_HardDiskDevice;
2736 }
2737 else if (strcmp(argv[i], "net") == 0)
2738 {
2739 bootDevice[n - 1] = DeviceType_NetworkDevice;
2740 }
2741 else
2742 {
2743 return errorArgument("Invalid boot device '%s'", argv[i]);
2744 }
2745 bootDeviceChanged[n - 1] = true;
2746 }
2747 else if (strcmp(argv[i], "-hda") == 0)
2748 {
2749 if (argc <= i + 1)
2750 {
2751 return errorArgument("Missing argument to '%s'", argv[i]);
2752 }
2753 i++;
2754 hdds[0] = argv[i];
2755 }
2756 else if (strcmp(argv[i], "-hdb") == 0)
2757 {
2758 if (argc <= i + 1)
2759 {
2760 return errorArgument("Missing argument to '%s'", argv[i]);
2761 }
2762 i++;
2763 hdds[1] = argv[i];
2764 }
2765 else if (strcmp(argv[i], "-hdd") == 0)
2766 {
2767 if (argc <= i + 1)
2768 {
2769 return errorArgument("Missing argument to '%s'", argv[i]);
2770 }
2771 i++;
2772 hdds[2] = argv[i];
2773 }
2774 else if (strcmp(argv[i], "-dvd") == 0)
2775 {
2776 if (argc <= i + 1)
2777 {
2778 return errorArgument("Missing argument to '%s'", argv[i]);
2779 }
2780 i++;
2781 dvd = argv[i];
2782 }
2783 else if (strcmp(argv[i], "-dvdpassthrough") == 0)
2784 {
2785 if (argc <= i + 1)
2786 {
2787 return errorArgument("Missing argument to '%s'", argv[i]);
2788 }
2789 i++;
2790 dvdpassthrough = argv[i];
2791 }
2792 else if (strcmp(argv[i], "-floppy") == 0)
2793 {
2794 if (argc <= i + 1)
2795 {
2796 return errorArgument("Missing argument to '%s'", argv[i]);
2797 }
2798 i++;
2799 floppy = argv[i];
2800 }
2801 else if (strcmp(argv[i], "-audio") == 0)
2802 {
2803 if (argc <= i + 1)
2804 {
2805 return errorArgument("Missing argument to '%s'", argv[i]);
2806 }
2807 i++;
2808 audio = argv[i];
2809 }
2810 else if (strncmp(argv[i], "-cableconnected", 15) == 0)
2811 {
2812 unsigned n = parseNicNum(&argv[i][15], NetworkAdapterCount);
2813 if (!n)
2814 return 1;
2815 if (argc <= i + 1)
2816 {
2817 return errorArgument("Missing argument to '%s'", argv[i]);
2818 }
2819 cableconnected[n - 1] = argv[i + 1];
2820 i++;
2821 }
2822 /* watch for the right order of these -nic* comparisons! */
2823 else if (strncmp(argv[i], "-nictracefile", 13) == 0)
2824 {
2825 unsigned n = parseNicNum(&argv[i][13], NetworkAdapterCount);
2826 if (!n)
2827 return 1;
2828 if (argc <= i + 1)
2829 {
2830 return errorArgument("Missing argument to '%s'", argv[i]);
2831 }
2832 nictracefile[n - 1] = argv[i + 1];
2833 i++;
2834 }
2835 else if (strncmp(argv[i], "-nictrace", 9) == 0)
2836 {
2837 unsigned n = parseNicNum(&argv[i][9], NetworkAdapterCount);
2838 if (!n)
2839 return 1;
2840 if (argc <= i + 1)
2841 {
2842 return errorArgument("Missing argument to '%s'", argv[i]);
2843 }
2844 nictrace[n - 1] = argv[i + 1];
2845 i++;
2846 }
2847 else if (strncmp(argv[i], "-nictype", 8) == 0)
2848 {
2849 unsigned n = parseNicNum(&argv[i][8], NetworkAdapterCount);
2850 if (!n)
2851 return 1;
2852 if (argc <= i + 1)
2853 {
2854 return errorArgument("Missing argument to '%s'", argv[i]);
2855 }
2856 nictype[n - 1] = argv[i + 1];
2857 i++;
2858 }
2859 else if (strncmp(argv[i], "-nic", 4) == 0)
2860 {
2861 unsigned n = parseNicNum(&argv[i][4], NetworkAdapterCount);
2862 if (!n)
2863 return 1;
2864 if (argc <= i + 1)
2865 {
2866 return errorArgument("Missing argument to '%s'", argv[i]);
2867 }
2868 nics[n - 1] = argv[i + 1];
2869 i++;
2870 }
2871 else if (strncmp(argv[i], "-hostifdev", 10) == 0)
2872 {
2873 unsigned n = parseNicNum(&argv[i][10], NetworkAdapterCount);
2874 if (!n)
2875 return 1;
2876 if (argc <= i + 1)
2877 {
2878 return errorArgument("Missing argument to '%s'", argv[i]);
2879 }
2880 hostifdev[n - 1] = argv[i + 1];
2881 i++;
2882 }
2883 else if (strncmp(argv[i], "-intnet", 7) == 0)
2884 {
2885 unsigned n = parseNicNum(&argv[i][7], NetworkAdapterCount);
2886 if (!n)
2887 return 1;
2888 if (argc <= i + 1)
2889 {
2890 return errorArgument("Missing argument to '%s'", argv[i]);
2891 }
2892 intnet[n - 1] = argv[i + 1];
2893 i++;
2894 }
2895#ifdef __LINUX__
2896 else if (strncmp(argv[i], "-tapsetup", 9) == 0)
2897 {
2898 unsigned n = parseNicNum(&argv[i][9], NetworkAdapterCount);
2899 if (!n)
2900 return 1;
2901 if (argc <= i + 1)
2902 {
2903 return errorArgument("Missing argument to '%s'", argv[i]);
2904 }
2905 tapsetup[n - 1] = argv[i + 1];
2906 i++;
2907 }
2908 else if (strncmp(argv[i], "-tapterminate", 13) == 0)
2909 {
2910 unsigned n = parseNicNum(&argv[i][13], NetworkAdapterCount);
2911 if (!n)
2912 return 1;
2913 if (argc <= i + 1)
2914 {
2915 return errorArgument("Missing argument to '%s'", argv[i]);
2916 }
2917 tapterm[n - 1] = argv[i + 1];
2918 i++;
2919 }
2920#endif /* __LINUX__ */
2921 else if (strncmp(argv[i], "-macaddress", 11) == 0)
2922 {
2923 unsigned n = parseNicNum(&argv[i][11], NetworkAdapterCount);
2924 if (!n)
2925 return 1;
2926 if (argc <= i + 1)
2927 {
2928 return errorArgument("Missing argument to '%s'", argv[i]);
2929 }
2930 macs[n - 1] = argv[i + 1];
2931 i++;
2932 }
2933#ifdef VBOX_VRDP
2934 else if (strcmp(argv[i], "-vrdp") == 0)
2935 {
2936 if (argc <= i + 1)
2937 {
2938 return errorArgument("Missing argument to '%s'", argv[i]);
2939 }
2940 i++;
2941 vrdp = argv[i];
2942 }
2943 else if (strcmp(argv[i], "-vrdpport") == 0)
2944 {
2945 if (argc <= i + 1)
2946 {
2947 return errorArgument("Missing argument to '%s'", argv[i]);
2948 }
2949 i++;
2950 if (strcmp(argv[i], "default") == 0)
2951 vrdpport = 0;
2952 else
2953 vrdpport = atoi(argv[i]);
2954 }
2955 else if (strcmp(argv[i], "-vrdpauthtype") == 0)
2956 {
2957 if (argc <= i + 1)
2958 {
2959 return errorArgument("Missing argument to '%s'", argv[i]);
2960 }
2961 i++;
2962 vrdpauthtype = argv[i];
2963 }
2964#endif /* VBOX_VRDP */
2965 else if (strcmp(argv[i], "-usb") == 0)
2966 {
2967 if (argc <= i + 1)
2968 {
2969 return errorArgument("Missing argument to '%s'", argv[i]);
2970 }
2971 i++;
2972 if (strcmp(argv[i], "on") == 0 || strcmp(argv[i], "enable") == 0)
2973 fUsbEnabled = 1;
2974 else if (strcmp(argv[i], "off") == 0 || strcmp(argv[i], "disable") == 0)
2975 fUsbEnabled = 0;
2976 else
2977 return errorArgument("Invalid -usb argument '%s'", argv[i]);
2978 }
2979 else if (strcmp(argv[i], "-snapshotfolder") == 0)
2980 {
2981 if (argc <= i + 1)
2982 {
2983 return errorArgument("Missing argument to '%s'", argv[i]);
2984 }
2985 i++;
2986 snapshotFolder = argv[i];
2987 }
2988 else
2989 {
2990 return errorSyntax(USAGE_MODIFYVM, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());
2991 }
2992 }
2993
2994 /* try to find the given machine */
2995 ComPtr <IMachine> machine;
2996 Guid uuid (argv[0]);
2997 if (!uuid.isEmpty())
2998 {
2999 CHECK_ERROR (virtualBox, GetMachine (uuid, machine.asOutParam()));
3000 }
3001 else
3002 {
3003 CHECK_ERROR (virtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam()));
3004 if (SUCCEEDED (rc))
3005 machine->COMGETTER(Id)(uuid.asOutParam());
3006 }
3007 if (FAILED (rc))
3008 return 1;
3009
3010 /* open a session for the VM */
3011 CHECK_ERROR_RET (virtualBox, OpenSession(session, uuid), 1);
3012
3013 do
3014 {
3015 /* get the mutable session machine */
3016 session->COMGETTER(Machine)(machine.asOutParam());
3017
3018 ComPtr <IBIOSSettings> biosSettings;
3019 machine->COMGETTER(BIOSSettings)(biosSettings.asOutParam());
3020
3021 if (name)
3022 CHECK_ERROR(machine, COMSETTER(Name)(name));
3023 if (ostype)
3024 {
3025 ComPtr<IGuestOSType> guestOSType;
3026 CHECK_ERROR(virtualBox, FindGuestOSType(ostype, guestOSType.asOutParam()));
3027 if (SUCCEEDED(rc) && guestOSType)
3028 {
3029 CHECK_ERROR(machine, COMSETTER(OSType)(guestOSType));
3030 }
3031 else
3032 {
3033 errorArgument("Invalid guest OS type '%s'", Utf8Str(ostype).raw());
3034 rc = E_FAIL;
3035 break;
3036 }
3037 }
3038 if (memorySize > 0)
3039 CHECK_ERROR(machine, COMSETTER(MemorySize)(memorySize));
3040 if (vramSize > 0)
3041 CHECK_ERROR(machine, COMSETTER(VRAMSize)(vramSize));
3042 if (acpi)
3043 {
3044 if (strcmp(acpi, "on") == 0)
3045 {
3046 CHECK_ERROR(biosSettings, COMSETTER(ACPIEnabled)(true));
3047 }
3048 else if (strcmp(acpi, "off") == 0)
3049 {
3050 CHECK_ERROR(biosSettings, COMSETTER(ACPIEnabled)(false));
3051 }
3052 else
3053 {
3054 errorArgument("Invalid -acpi argument '%s'", acpi);
3055 rc = E_FAIL;
3056 break;
3057 }
3058 }
3059 if (ioapic)
3060 {
3061 if (strcmp(ioapic, "on") == 0)
3062 {
3063 CHECK_ERROR(biosSettings, COMSETTER(IOAPICEnabled)(true));
3064 }
3065 else if (strcmp(ioapic, "off") == 0)
3066 {
3067 CHECK_ERROR(biosSettings, COMSETTER(IOAPICEnabled)(false));
3068 }
3069 else
3070 {
3071 errorArgument("Invalid -ioapic argument '%s'", ioapic);
3072 rc = E_FAIL;
3073 break;
3074 }
3075 }
3076 if (hwvirtex)
3077 {
3078 if (strcmp(hwvirtex, "on") == 0)
3079 {
3080 CHECK_ERROR(machine, COMSETTER(HWVirtExEnabled)(TriStateBool_True));
3081 }
3082 else if (strcmp(hwvirtex, "off") == 0)
3083 {
3084 CHECK_ERROR(machine, COMSETTER(HWVirtExEnabled)(TriStateBool_False));
3085 }
3086 else if (strcmp(hwvirtex, "default") == 0)
3087 {
3088 CHECK_ERROR(machine, COMSETTER(HWVirtExEnabled)(TriStateBool_Default));
3089 }
3090 else
3091 {
3092 errorArgument("Invalid -hwvirtex argument '%s'", hwvirtex);
3093 rc = E_FAIL;
3094 break;
3095 }
3096 }
3097 if (bioslogofadein)
3098 {
3099 if (strcmp(bioslogofadein, "on") == 0)
3100 {
3101 CHECK_ERROR(biosSettings, COMSETTER(LogoFadeIn)(true));
3102 }
3103 else if (strcmp(bioslogofadein, "off") == 0)
3104 {
3105 CHECK_ERROR(biosSettings, COMSETTER(LogoFadeIn)(false));
3106 }
3107 else
3108 {
3109 errorArgument("Invalid -bioslogofadein argument '%s'", bioslogofadein);
3110 rc = E_FAIL;
3111 break;
3112 }
3113 }
3114 if (bioslogofadeout)
3115 {
3116 if (strcmp(bioslogofadeout, "on") == 0)
3117 {
3118 CHECK_ERROR(biosSettings, COMSETTER(LogoFadeOut)(true));
3119 }
3120 else if (strcmp(bioslogofadeout, "off") == 0)
3121 {
3122 CHECK_ERROR(biosSettings, COMSETTER(LogoFadeOut)(false));
3123 }
3124 else
3125 {
3126 errorArgument("Invalid -bioslogofadeout argument '%s'", bioslogofadeout);
3127 rc = E_FAIL;
3128 break;
3129 }
3130 }
3131 if (bioslogodisplaytime != ~0U)
3132 {
3133 CHECK_ERROR(biosSettings, COMSETTER(LogoDisplayTime)(bioslogodisplaytime));
3134 }
3135 if (bioslogoimagepath)
3136 {
3137 CHECK_ERROR(biosSettings, COMSETTER(LogoImagePath)(Bstr(bioslogoimagepath)));
3138 }
3139 if (biosbootmenumode)
3140 {
3141 if (strcmp(biosbootmenumode, "disabled") == 0)
3142 CHECK_ERROR(biosSettings, COMSETTER(BootMenuMode)(BIOSBootMenuMode_Disabled));
3143 else if (strcmp(biosbootmenumode, "menuonly") == 0)
3144 CHECK_ERROR(biosSettings, COMSETTER(BootMenuMode)(BIOSBootMenuMode_MenuOnly));
3145 else if (strcmp(biosbootmenumode, "messageandmenu") == 0)
3146 CHECK_ERROR(biosSettings, COMSETTER(BootMenuMode)(BIOSBootMenuMode_MessageAndMenu));
3147 else
3148 {
3149 errorArgument("Invalid -biosbootmenu argument '%s'", biosbootmenumode);
3150 rc = E_FAIL;
3151 break;
3152 }
3153
3154 }
3155 for (int curBootDev = 0; curBootDev < 4; curBootDev++)
3156 {
3157 if (bootDeviceChanged[curBootDev])
3158 CHECK_ERROR(machine, SetBootOrder (curBootDev + 1, bootDevice[curBootDev]));
3159 }
3160 if (hdds[0])
3161 {
3162 if (strcmp(hdds[0], "none") == 0)
3163 {
3164 machine->DetachHardDisk(DiskControllerType_IDE0Controller, 0);
3165 }
3166 else
3167 {
3168 /* first guess is that it's a UUID */
3169 Guid uuid(hdds[0]);
3170 ComPtr<IHardDisk> hardDisk;
3171 rc = virtualBox->GetHardDisk(uuid, hardDisk.asOutParam());
3172 /* not successful? Then it must be a filename */
3173 if (!hardDisk)
3174 {
3175 ComPtr<IVirtualDiskImage> vdi;
3176 CHECK_ERROR(virtualBox, OpenVirtualDiskImage(Bstr(hdds[0]), vdi.asOutParam()));
3177 if (SUCCEEDED(rc) && vdi)
3178 {
3179 hardDisk = vdi;
3180 /* first check if it's already registered */
3181 Guid hddUUID;
3182 hardDisk->COMGETTER(Id)(hddUUID.asOutParam());
3183 ComPtr<IHardDisk> registeredHDD;
3184 rc = virtualBox->GetHardDisk(hddUUID, registeredHDD.asOutParam());
3185 if (SUCCEEDED(rc) && registeredHDD)
3186 hardDisk = registeredHDD;
3187 else
3188 {
3189 /* it has to be registered */
3190 CHECK_ERROR(virtualBox, RegisterHardDisk(hardDisk));
3191 if (FAILED(rc))
3192 break;
3193 }
3194 }
3195 }
3196 if (hardDisk)
3197 {
3198 hardDisk->COMGETTER(Id)(uuid.asOutParam());
3199 CHECK_ERROR(machine, AttachHardDisk(uuid, DiskControllerType_IDE0Controller, 0));
3200 }
3201 else
3202 rc = E_FAIL;
3203 if (FAILED(rc))
3204 break;
3205 }
3206 }
3207 if (hdds[1])
3208 {
3209 if (strcmp(hdds[1], "none") == 0)
3210 {
3211 machine->DetachHardDisk(DiskControllerType_IDE0Controller, 1);
3212 }
3213 else
3214 {
3215 /* first guess is that it's a UUID */
3216 Guid uuid(hdds[1]);
3217 ComPtr<IHardDisk> hardDisk;
3218 rc = virtualBox->GetHardDisk(uuid, hardDisk.asOutParam());
3219 /* not successful? Then it must be a filename */
3220 if (!hardDisk)
3221 {
3222 ComPtr<IVirtualDiskImage> vdi;
3223 CHECK_ERROR(virtualBox, OpenVirtualDiskImage(Bstr(hdds[1]), vdi.asOutParam()));
3224 if (SUCCEEDED(rc) && vdi)
3225 {
3226 hardDisk = vdi;
3227 /* first check if it's already registered */
3228 Guid hddUUID;
3229 hardDisk->COMGETTER(Id)(hddUUID.asOutParam());
3230 ComPtr<IHardDisk> registeredHDD;
3231 rc = virtualBox->GetHardDisk(hddUUID, registeredHDD.asOutParam());
3232 if (SUCCEEDED(rc) && registeredHDD)
3233 hardDisk = registeredHDD;
3234 else
3235 {
3236 /* it has to be registered */
3237 CHECK_ERROR(virtualBox, RegisterHardDisk(hardDisk));
3238 if (FAILED(rc))
3239 break;
3240 }
3241 }
3242 }
3243 if (hardDisk)
3244 {
3245 hardDisk->COMGETTER(Id)(uuid.asOutParam());
3246 CHECK_ERROR(machine, AttachHardDisk(uuid, DiskControllerType_IDE0Controller, 1));
3247 }
3248 else
3249 rc = E_FAIL;
3250 if (FAILED(rc))
3251 break;
3252 }
3253 }
3254 if (hdds[2])
3255 {
3256 if (strcmp(hdds[2], "none") == 0)
3257 {
3258 machine->DetachHardDisk(DiskControllerType_IDE1Controller, 1);
3259 }
3260 else
3261 {
3262 /* first guess is that it's a UUID */
3263 Guid uuid(hdds[2]);
3264 ComPtr<IHardDisk> hardDisk;
3265 rc = virtualBox->GetHardDisk(uuid, hardDisk.asOutParam());
3266 /* not successful? Then it must be a filename */
3267 if (!hardDisk)
3268 {
3269 ComPtr<IVirtualDiskImage> vdi;
3270 CHECK_ERROR(virtualBox, OpenVirtualDiskImage(Bstr(hdds[2]), vdi.asOutParam()));
3271 if (SUCCEEDED(rc) && vdi)
3272 {
3273 hardDisk = vdi;
3274 /* first check if it's already registered */
3275 Guid hddUUID;
3276 hardDisk->COMGETTER(Id)(hddUUID.asOutParam());
3277 ComPtr<IHardDisk> registeredHDD;
3278 rc = virtualBox->GetHardDisk(hddUUID, registeredHDD.asOutParam());
3279 if (SUCCEEDED(rc) && registeredHDD)
3280 hardDisk = registeredHDD;
3281 else
3282 {
3283 /* it has to be registered */
3284 CHECK_ERROR(virtualBox, RegisterHardDisk(hardDisk));
3285 if (FAILED(rc))
3286 break;
3287 }
3288 }
3289 }
3290 if (hardDisk)
3291 {
3292 hardDisk->COMGETTER(Id)(uuid.asOutParam());
3293 CHECK_ERROR(machine, AttachHardDisk(uuid, DiskControllerType_IDE1Controller, 1));
3294 }
3295 else
3296 rc = E_FAIL;
3297 if (FAILED(rc))
3298 break;
3299 }
3300 }
3301 if (dvd)
3302 {
3303 ComPtr<IDVDDrive> dvdDrive;
3304 machine->COMGETTER(DVDDrive)(dvdDrive.asOutParam());
3305 ASSERT(dvdDrive);
3306
3307 /* unmount? */
3308 if (strcmp(dvd, "none") == 0)
3309 {
3310 CHECK_ERROR(dvdDrive, Unmount());
3311 }
3312 /* host drive? */
3313 else if (strncmp(dvd, "host:", 5) == 0)
3314 {
3315 ComPtr<IHost> host;
3316 CHECK_ERROR(virtualBox, COMGETTER(Host)(host.asOutParam()));
3317 ComPtr<IHostDVDDriveCollection> hostDVDs;
3318 CHECK_ERROR(host, COMGETTER(DVDDrives)(hostDVDs.asOutParam()));
3319 ComPtr<IHostDVDDrive> hostDVDDrive;
3320 rc = hostDVDs->FindByName(Bstr(dvd + 5), hostDVDDrive.asOutParam());
3321 if (!hostDVDDrive)
3322 {
3323 errorArgument("Invalid host DVD drive name");
3324 rc = E_FAIL;
3325 break;
3326 }
3327 CHECK_ERROR(dvdDrive, CaptureHostDrive(hostDVDDrive));
3328 }
3329 else
3330 {
3331 /* first assume it's a UUID */
3332 Guid uuid(dvd);
3333 ComPtr<IDVDImage> dvdImage;
3334 rc = virtualBox->GetDVDImage(uuid, dvdImage.asOutParam());
3335 if (FAILED(rc) || !dvdImage)
3336 {
3337 /* must be a filename, check if it's in the collection */
3338 ComPtr<IDVDImageCollection> dvdImages;
3339 virtualBox->COMGETTER(DVDImages)(dvdImages.asOutParam());
3340 rc = dvdImages->FindByPath(Bstr(dvd), dvdImage.asOutParam());
3341 /* not registered, do that on the fly */
3342 if (!dvdImage)
3343 {
3344 Guid emptyUUID;
3345 CHECK_ERROR(virtualBox, OpenDVDImage(Bstr(dvd), emptyUUID, dvdImage.asOutParam()));
3346 if (SUCCEEDED(rc) && dvdImage)
3347 {
3348 /* time to register the image */
3349 CHECK_ERROR(virtualBox, RegisterDVDImage(dvdImage));
3350 }
3351 }
3352 }
3353 if (!dvdImage)
3354 {
3355 rc = E_FAIL;
3356 break;
3357 }
3358
3359 dvdImage->COMGETTER(Id)(uuid.asOutParam());
3360 CHECK_ERROR(dvdDrive, MountImage(uuid));
3361 }
3362 }
3363 if (dvdpassthrough)
3364 {
3365 ComPtr<IDVDDrive> dvdDrive;
3366 machine->COMGETTER(DVDDrive)(dvdDrive.asOutParam());
3367 ASSERT(dvdDrive);
3368
3369 CHECK_ERROR(dvdDrive, COMSETTER(Passthrough)(strcmp(dvdpassthrough, "on") == 0));
3370 }
3371 if (floppy)
3372 {
3373 ComPtr<IFloppyDrive> floppyDrive;
3374 machine->COMGETTER(FloppyDrive)(floppyDrive.asOutParam());
3375 ASSERT(floppyDrive);
3376
3377 /* disable? */
3378 if (strcmp(floppy, "disabled") == 0)
3379 {
3380 /* disable the controller */
3381 CHECK_ERROR(floppyDrive, COMSETTER(Enabled)(false));
3382 }
3383 else
3384 {
3385 /* enable the controller */
3386 CHECK_ERROR(floppyDrive, COMSETTER(Enabled)(true));
3387
3388 /* unmount? */
3389 if (strcmp(floppy, "empty") == 0)
3390 {
3391 CHECK_ERROR(floppyDrive, Unmount());
3392 }
3393 /* host drive? */
3394 else if (strncmp(floppy, "host:", 5) == 0)
3395 {
3396 ComPtr<IHost> host;
3397 CHECK_ERROR(virtualBox, COMGETTER(Host)(host.asOutParam()));
3398 ComPtr<IHostFloppyDriveCollection> hostFloppies;
3399 CHECK_ERROR(host, COMGETTER(FloppyDrives)(hostFloppies.asOutParam()));
3400 ComPtr<IHostFloppyDrive> hostFloppyDrive;
3401 rc = hostFloppies->FindByName(Bstr(floppy + 5), hostFloppyDrive.asOutParam());
3402 if (!hostFloppyDrive)
3403 {
3404 errorArgument("Invalid host floppy drive name");
3405 rc = E_FAIL;
3406 break;
3407 }
3408 CHECK_ERROR(floppyDrive, CaptureHostDrive(hostFloppyDrive));
3409 }
3410 else
3411 {
3412 /* first assume it's a UUID */
3413 Guid uuid(floppy);
3414 ComPtr<IFloppyImage> floppyImage;
3415 rc = virtualBox->GetFloppyImage(uuid, floppyImage.asOutParam());
3416 if (FAILED(rc) || !floppyImage)
3417 {
3418 /* must be a filename */
3419 Guid emptyUUID;
3420 CHECK_ERROR(virtualBox, OpenFloppyImage(Bstr(floppy), emptyUUID, floppyImage.asOutParam()));
3421 if (SUCCEEDED(rc) && floppyImage)
3422 {
3423 /** @todo first iterate through the collection and try to find the image */
3424 /* time to register the image */
3425 CHECK_ERROR(virtualBox, RegisterFloppyImage(floppyImage));
3426 }
3427 }
3428 if (!floppyImage)
3429 {
3430 rc = E_FAIL;
3431 break;
3432 }
3433
3434 floppyImage->COMGETTER(Id)(uuid.asOutParam());
3435 CHECK_ERROR(floppyDrive, MountImage(uuid));
3436 }
3437 }
3438 }
3439 if (audio)
3440 {
3441 ComPtr<IAudioAdapter> audioAdapter;
3442 machine->COMGETTER(AudioAdapter)(audioAdapter.asOutParam());
3443 ASSERT(audioAdapter);
3444
3445 /* disable? */
3446 if (strcmp(audio, "none") == 0)
3447 {
3448 CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(false));
3449 }
3450 else if (strcmp(audio, "null") == 0)
3451 {
3452 CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_NullAudioDriver));
3453 CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(true));
3454 }
3455#ifdef __LINUX__
3456 else if (strcmp(audio, "oss") == 0)
3457 {
3458 CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_OSSAudioDriver));
3459 CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(true));
3460 }
3461#ifdef VBOX_WITH_ALSA
3462 else if (strcmp(audio, "alsa") == 0)
3463 {
3464 CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_ALSAAudioDriver));
3465 CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(true));
3466 }
3467#endif
3468#else /* !__LINUX__ */
3469 else if (strcmp(audio, "winmm") == 0)
3470 {
3471 CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_WINMMAudioDriver));
3472 CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(true));
3473 }
3474 else if (strcmp(audio, "dsound") == 0)
3475 {
3476 CHECK_ERROR(audioAdapter, COMSETTER(AudioDriver)(AudioDriverType_DSOUNDAudioDriver));
3477 CHECK_ERROR(audioAdapter, COMSETTER(Enabled)(true));
3478 }
3479#endif /* !__LINUX__ */
3480 else
3481 {
3482 errorArgument("Invalid -audio argument '%s'", audio);
3483 rc = E_FAIL;
3484 break;
3485 }
3486 }
3487 /* iterate through all possible NICs */
3488 for (ULONG n = 0; n < NetworkAdapterCount; n ++)
3489 {
3490 ComPtr<INetworkAdapter> nic;
3491 CHECK_ERROR_RET (machine, GetNetworkAdapter (n, nic.asOutParam()), 1);
3492
3493 ASSERT(nic);
3494
3495 /* something about the NIC? */
3496 if (nics[n])
3497 {
3498 if (strcmp(nics[n], "none") == 0)
3499 {
3500 CHECK_ERROR_RET(nic, COMSETTER(Enabled) (FALSE), 1);
3501 }
3502 else if (strcmp(nics[n], "null") == 0)
3503 {
3504 CHECK_ERROR_RET(nic, COMSETTER(Enabled) (TRUE), 1);
3505 CHECK_ERROR_RET(nic, Detach(), 1);
3506 }
3507 else if (strcmp(nics[n], "nat") == 0)
3508 {
3509 CHECK_ERROR_RET(nic, COMSETTER(Enabled) (TRUE), 1);
3510 CHECK_ERROR_RET(nic, AttachToNAT(), 1);
3511 }
3512 else if (strcmp(nics[n], "hostif") == 0)
3513 {
3514 CHECK_ERROR_RET(nic, COMSETTER(Enabled) (TRUE), 1);
3515 CHECK_ERROR_RET(nic, AttachToHostInterface(), 1);
3516 }
3517 else if (strcmp(nics[n], "intnet") == 0)
3518 {
3519 CHECK_ERROR_RET(nic, COMSETTER(Enabled) (TRUE), 1);
3520 CHECK_ERROR_RET(nic, AttachToInternalNetwork(), 1);
3521 }
3522 else
3523 {
3524 errorArgument("Invalid type '%s' specfied for NIC %lu", nics[n], n + 1);
3525 rc = E_FAIL;
3526 break;
3527 }
3528 }
3529
3530 /* something about the NIC type? */
3531 if (nictype[n])
3532 {
3533 if (strcmp(nictype[n], "Am79C970A") == 0)
3534 {
3535 CHECK_ERROR_RET(nic, COMSETTER(AdapterType)(NetworkAdapterType_NetworkAdapterAm79C970A), 1);
3536 }
3537 else if (strcmp(nictype[n], "Am79C973") == 0)
3538 {
3539 CHECK_ERROR_RET(nic, COMSETTER(AdapterType)(NetworkAdapterType_NetworkAdapterAm79C973), 1);
3540 }
3541 else
3542 {
3543 errorArgument("Invalid NIC type '%s' specified for NIC %lu", nictype[n], n + 1);
3544 rc = E_FAIL;
3545 break;
3546 }
3547 }
3548
3549 /* something about the MAC address? */
3550 if (macs[n])
3551 {
3552 /* generate one? */
3553 if (strcmp(macs[n], "auto") == 0)
3554 {
3555 CHECK_ERROR_RET(nic, COMSETTER(MACAddress)(NULL), 1);
3556 }
3557 else
3558 {
3559 CHECK_ERROR_RET(nic, COMSETTER(MACAddress)(Bstr(macs[n])), 1);
3560 }
3561 }
3562
3563 /* the link status flag? */
3564 if (cableconnected[n])
3565 {
3566 if (strcmp(cableconnected[n], "on") == 0)
3567 {
3568 CHECK_ERROR_RET(nic, COMSETTER(CableConnected)(TRUE), 1);
3569 }
3570 else if (strcmp(cableconnected[n], "off") == 0)
3571 {
3572 CHECK_ERROR_RET(nic, COMSETTER(CableConnected)(FALSE), 1);
3573 }
3574 else
3575 {
3576 errorArgument("Invalid -cableconnected%lu argument '%s'", n + 1, cableconnected[n]);
3577 rc = E_FAIL;
3578 break;
3579 }
3580 }
3581
3582 /* the trace flag? */
3583 if (nictrace[n])
3584 {
3585 if (strcmp(nictrace[n], "on") == 0)
3586 {
3587 CHECK_ERROR_RET(nic, COMSETTER(TraceEnabled)(TRUE), 1);
3588 }
3589 else if (strcmp(nictrace[n], "off") == 0)
3590 {
3591 CHECK_ERROR_RET(nic, COMSETTER(TraceEnabled)(FALSE), 1);
3592 }
3593 else
3594 {
3595 errorArgument("Invalid -nictrace%lu argument '%s'", n + 1, nictrace[n]);
3596 rc = E_FAIL;
3597 break;
3598 }
3599 }
3600
3601 /* the tracefile flag? */
3602 if (nictracefile[n])
3603 {
3604 CHECK_ERROR_RET(nic, COMSETTER(TraceFile)(Bstr(nictracefile[n])), 1);
3605 }
3606
3607 /* the host interface device? */
3608 if (hostifdev[n])
3609 {
3610 /* remove it? */
3611 if (strcmp(hostifdev[n], "none") == 0)
3612 {
3613 CHECK_ERROR_RET(nic, COMSETTER(HostInterface)(NULL), 1);
3614 }
3615 else
3616 {
3617 CHECK_ERROR_RET(nic, COMSETTER(HostInterface)(Bstr(hostifdev[n])), 1);
3618 }
3619 }
3620
3621 /* the internal network name? */
3622 if (intnet[n])
3623 {
3624 /* remove it? */
3625 if (strcmp(intnet[n], "none") == 0)
3626 {
3627 CHECK_ERROR_RET(nic, COMSETTER(InternalNetwork)(NULL), 1);
3628 }
3629 else
3630 {
3631 CHECK_ERROR_RET(nic, COMSETTER(InternalNetwork)(Bstr(intnet[n])), 1);
3632 }
3633 }
3634
3635#ifdef __LINUX__
3636 /* the TAP setup application? */
3637 if (tapsetup[n])
3638 {
3639 /* remove it? */
3640 if (strcmp(tapsetup[n], "none") == 0)
3641 {
3642 CHECK_ERROR_RET(nic, COMSETTER(TAPSetupApplication)(NULL), 1);
3643 }
3644 else
3645 {
3646 CHECK_ERROR_RET(nic, COMSETTER(TAPSetupApplication)(Bstr(tapsetup[n])), 1);
3647 }
3648 }
3649
3650 /* the TAP terminate application? */
3651 if (tapterm[n])
3652 {
3653 /* remove it? */
3654 if (strcmp(tapterm[n], "none") == 0)
3655 {
3656 CHECK_ERROR_RET(nic, COMSETTER(TAPTerminateApplication)(NULL), 1);
3657 }
3658 else
3659 {
3660 CHECK_ERROR_RET(nic, COMSETTER(TAPTerminateApplication)(Bstr(tapterm[n])), 1);
3661 }
3662 }
3663#endif /* __LINUX__ */
3664
3665 }
3666 if (FAILED(rc))
3667 break;
3668#ifdef VBOX_VRDP
3669 if (vrdp || (vrdpport != UINT16_MAX) || vrdpauthtype)
3670 {
3671 ComPtr<IVRDPServer> vrdpServer;
3672 machine->COMGETTER(VRDPServer)(vrdpServer.asOutParam());
3673 ASSERT(vrdpServer);
3674 if (vrdpServer)
3675 {
3676 if (vrdp)
3677 {
3678 if (strcmp(vrdp, "on") == 0)
3679 {
3680 CHECK_ERROR(vrdpServer, COMSETTER(Enabled)(true));
3681 }
3682 else if (strcmp(vrdp, "off") == 0)
3683 {
3684 CHECK_ERROR(vrdpServer, COMSETTER(Enabled)(false));
3685 }
3686 else
3687 {
3688 errorArgument("Invalid -vrdp argument '%s'", vrdp);
3689 rc = E_FAIL;
3690 break;
3691 }
3692 }
3693 if (vrdpport != UINT16_MAX)
3694 {
3695 CHECK_ERROR(vrdpServer, COMSETTER(Port)(vrdpport));
3696 }
3697 if (vrdpauthtype)
3698 {
3699 if (strcmp(vrdpauthtype, "null") == 0)
3700 {
3701 CHECK_ERROR(vrdpServer, COMSETTER(AuthType)(VRDPAuthType_VRDPAuthNull));
3702 }
3703 else if (strcmp(vrdpauthtype, "external") == 0)
3704 {
3705 CHECK_ERROR(vrdpServer, COMSETTER(AuthType)(VRDPAuthType_VRDPAuthExternal));
3706 }
3707 else if (strcmp(vrdpauthtype, "guest") == 0)
3708 {
3709 CHECK_ERROR(vrdpServer, COMSETTER(AuthType)(VRDPAuthType_VRDPAuthGuest));
3710 }
3711 else
3712 {
3713 errorArgument("Invalid -vrdpauthtype argument '%s'", vrdpauthtype);
3714 rc = E_FAIL;
3715 break;
3716 }
3717 }
3718 }
3719 }
3720#endif /* VBOX_VRDP */
3721
3722 /*
3723 * USB enable/disable
3724 */
3725 if (fUsbEnabled != -1)
3726 {
3727 ComPtr<IUSBController> UsbCtl;
3728 CHECK_ERROR(machine, COMGETTER(USBController)(UsbCtl.asOutParam()));
3729 if (SUCCEEDED(rc))
3730 {
3731 CHECK_ERROR(UsbCtl, COMSETTER(Enabled)(!!fUsbEnabled));
3732 }
3733 }
3734
3735 if (snapshotFolder)
3736 {
3737 if (strcmp(snapshotFolder, "default") == 0)
3738 {
3739 CHECK_ERROR(machine, COMSETTER(SnapshotFolder)(NULL));
3740 }
3741 else
3742 {
3743 CHECK_ERROR(machine, COMSETTER(SnapshotFolder)(Bstr(snapshotFolder)));
3744 }
3745 }
3746
3747 /* commit changes */
3748 CHECK_ERROR(machine, SaveSettings());
3749 } while (0);
3750
3751 /* it's important to always close sessions */
3752 session->Close();
3753
3754 return SUCCEEDED(rc) ? 0 : 1;
3755}
3756
3757static int handleStartVM(int argc, char *argv[],
3758 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
3759{
3760 HRESULT rc;
3761
3762 if (argc < 1)
3763 {
3764 return errorSyntax(USAGE_STARTVM, "Not enough parameters");
3765 }
3766
3767 ComPtr<IMachine> machine;
3768 /* assume it's a UUID */
3769 rc = virtualBox->GetMachine(Guid(argv[0]), machine.asOutParam());
3770 if (FAILED(rc) || !machine)
3771 {
3772 /* must be a name */
3773 CHECK_ERROR(virtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam()));
3774 }
3775 if (machine)
3776 {
3777 Guid uuid;
3778 machine->COMGETTER(Id)(uuid.asOutParam());
3779
3780 /* default to GUI session type */
3781 Bstr sessionType = "gui";
3782 /* has a session type been specified? */
3783 if ((argc > 2) && (strcmp(argv[1], "-type") == 0))
3784 {
3785 if (strcmp(argv[2], "gui") == 0)
3786 {
3787 sessionType = "gui";
3788 }
3789 else if (strcmp(argv[2], "vrdp") == 0)
3790 {
3791 sessionType = "vrdp";
3792 }
3793 else if (strcmp(argv[2], "capture") == 0)
3794 {
3795 sessionType = "capture";
3796 }
3797 else
3798 {
3799 return errorArgument("Invalid session type argument '%s'", argv[2]);
3800 }
3801 }
3802
3803 ComPtr<IProgress> progress;
3804 CHECK_ERROR_RET(virtualBox, OpenRemoteSession(session, uuid, sessionType, progress.asOutParam()), rc);
3805 RTPrintf("Waiting for the remote session to open...\n");
3806 CHECK_ERROR_RET(progress, WaitForCompletion (-1), 1);
3807
3808 BOOL completed;
3809 CHECK_ERROR_RET(progress, COMGETTER(Completed)(&completed), rc);
3810 ASSERT(completed);
3811
3812 HRESULT resultCode;
3813 CHECK_ERROR_RET(progress, COMGETTER(ResultCode)(&resultCode), rc);
3814 if (FAILED(resultCode))
3815 {
3816 ComPtr <IVirtualBoxErrorInfo> errorInfo;
3817 CHECK_ERROR_RET(progress, COMGETTER(ErrorInfo)(errorInfo.asOutParam()), 1);
3818 ErrorInfo info (errorInfo);
3819 PRINT_ERROR_INFO(info);
3820 }
3821 else
3822 {
3823 RTPrintf("Remote session has been successfully opened.\n");
3824 }
3825 }
3826
3827 /* it's important to always close sessions */
3828 session->Close();
3829
3830 return SUCCEEDED(rc) ? 0 : 1;
3831}
3832
3833static int handleControlVM(int argc, char *argv[],
3834 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
3835{
3836 HRESULT rc;
3837
3838 if (argc < 2)
3839 {
3840 return errorSyntax(USAGE_CONTROLVM, "Not enough parameters");
3841 }
3842
3843 /* try to find the given machine */
3844 ComPtr <IMachine> machine;
3845 Guid uuid (argv[0]);
3846 if (!uuid.isEmpty())
3847 {
3848 CHECK_ERROR (virtualBox, GetMachine (uuid, machine.asOutParam()));
3849 }
3850 else
3851 {
3852 CHECK_ERROR (virtualBox, FindMachine (Bstr(argv[0]), machine.asOutParam()));
3853 if (SUCCEEDED (rc))
3854 machine->COMGETTER(Id) (uuid.asOutParam());
3855 }
3856 if (FAILED (rc))
3857 return 1;
3858
3859 /* open a session for the VM */
3860 CHECK_ERROR_RET (virtualBox, OpenExistingSession (session, uuid), 1);
3861
3862 do
3863 {
3864 /* get the associated console */
3865 ComPtr<IConsole> console;
3866 CHECK_ERROR_BREAK (session, COMGETTER(Console)(console.asOutParam()));
3867 /* ... and session machine */
3868 ComPtr<IMachine> sessionMachine;
3869 CHECK_ERROR_BREAK (session, COMGETTER(Machine)(sessionMachine.asOutParam()));
3870
3871 /* which command? */
3872 if (strcmp(argv[1], "pause") == 0)
3873 {
3874 CHECK_ERROR_BREAK (console, Pause());
3875 }
3876 else if (strcmp(argv[1], "resume") == 0)
3877 {
3878 CHECK_ERROR_BREAK (console, Resume());
3879 }
3880 else if (strcmp(argv[1], "reset") == 0)
3881 {
3882 CHECK_ERROR_BREAK (console, Reset());
3883 }
3884 else if (strcmp(argv[1], "poweroff") == 0)
3885 {
3886 CHECK_ERROR_BREAK (console, PowerDown());
3887 }
3888 else if (strcmp(argv[1], "savestate") == 0)
3889 {
3890 ComPtr<IProgress> progress;
3891 CHECK_ERROR_BREAK (console, SaveState(progress.asOutParam()));
3892
3893 showProgress(progress);
3894
3895 progress->COMGETTER(ResultCode)(&rc);
3896 if (FAILED(rc))
3897 {
3898 com::ProgressErrorInfo info(progress);
3899 if (info.isBasicAvailable())
3900 {
3901 RTPrintf("Error: failed to save machine state. Error message: %lS\n", info.getText().raw());
3902 }
3903 else
3904 {
3905 RTPrintf("Error: failed to save machine state. No error message available!\n");
3906 }
3907 }
3908 }
3909 else if (strcmp(argv[1], "acpipowerbutton") == 0)
3910 {
3911 CHECK_ERROR_BREAK (console, PowerButton());
3912 }
3913 else if (strncmp(argv[1], "setlinkstate", 12) == 0)
3914 {
3915 /* Get the number of network adapters */
3916 ULONG NetworkAdapterCount = 0;
3917 ComPtr <ISystemProperties> info;
3918 CHECK_ERROR_BREAK (virtualBox, COMGETTER(SystemProperties) (info.asOutParam()));
3919 CHECK_ERROR_BREAK (info, COMGETTER(NetworkAdapterCount) (&NetworkAdapterCount));
3920
3921 unsigned n = parseNicNum(&argv[1][12], NetworkAdapterCount);
3922 if (!n)
3923 {
3924 rc = E_FAIL;
3925 break;
3926 }
3927 if (argc <= 1 + 1)
3928 {
3929 errorArgument("Missing argument to '%s'", argv[1]);
3930 rc = E_FAIL;
3931 break;
3932 }
3933 /* get the corresponding network adapter */
3934 ComPtr<INetworkAdapter> adapter;
3935 CHECK_ERROR_BREAK (sessionMachine, GetNetworkAdapter(n - 1, adapter.asOutParam()));
3936 if (adapter)
3937 {
3938 if (strcmp(argv[2], "on") == 0)
3939 {
3940 CHECK_ERROR_BREAK (adapter, COMSETTER(CableConnected)(TRUE));
3941 }
3942 else if (strcmp(argv[2], "off") == 0)
3943 {
3944 CHECK_ERROR_BREAK (adapter, COMSETTER(CableConnected)(FALSE));
3945 }
3946 else
3947 {
3948 errorArgument("Invalid link state '%s'", Utf8Str(argv[2]).raw());
3949 rc = E_FAIL;
3950 break;
3951 }
3952 }
3953 }
3954 else if (strcmp (argv[1], "usbattach") == 0 ||
3955 strcmp (argv[1], "usbdetach") == 0)
3956 {
3957 if (argc < 3)
3958 {
3959 errorSyntax(USAGE_CONTROLVM, "Not enough parameters");
3960 rc = E_FAIL;
3961 break;
3962 }
3963
3964 bool attach = strcmp (argv[1], "usbattach") == 0;
3965
3966 Guid usbId = argv [2];
3967 if (usbId.isEmpty())
3968 {
3969 // assume address
3970 if (attach)
3971 {
3972 ComPtr <IHost> host;
3973 CHECK_ERROR_BREAK (virtualBox, COMGETTER(Host) (host.asOutParam()));
3974 ComPtr <IHostUSBDeviceCollection> coll;
3975 CHECK_ERROR_BREAK (host, COMGETTER(USBDevices) (coll.asOutParam()));
3976 ComPtr <IHostUSBDevice> dev;
3977 CHECK_ERROR_BREAK (coll, FindByAddress (Bstr (argv [2]), dev.asOutParam()));
3978 CHECK_ERROR_BREAK (dev, COMGETTER(Id) (usbId.asOutParam()));
3979 }
3980 else
3981 {
3982 ComPtr <IUSBDeviceCollection> coll;
3983 CHECK_ERROR_BREAK (console, COMGETTER(USBDevices)(coll.asOutParam()));
3984 ComPtr <IUSBDevice> dev;
3985 CHECK_ERROR_BREAK (coll, FindByAddress (Bstr (argv [2]), dev.asOutParam()));
3986 CHECK_ERROR_BREAK (dev, COMGETTER(Id) (usbId.asOutParam()));
3987 }
3988 }
3989
3990 if (attach)
3991 CHECK_ERROR_BREAK (console, AttachUSBDevice (usbId));
3992 else
3993 {
3994 ComPtr <IUSBDevice> dev;
3995 CHECK_ERROR_BREAK (console, DetachUSBDevice (usbId, dev.asOutParam()));
3996 }
3997 }
3998 else if (strcmp(argv[1], "setvideomodehint") == 0)
3999 {
4000 if (argc != 5)
4001 {
4002 errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");
4003 rc = E_FAIL;
4004 break;
4005 }
4006 uint32_t xres = atoi(argv[2]);
4007 uint32_t yres = atoi(argv[3]);
4008 uint32_t bpp = atoi(argv[4]);
4009
4010 ComPtr<IDisplay> display;
4011 CHECK_ERROR_BREAK(console, COMGETTER(Display)(display.asOutParam()));
4012 CHECK_ERROR_BREAK(display, SetVideoModeHint(xres, yres, bpp));
4013 }
4014 else if (strcmp(argv[1], "setcredentials") == 0)
4015 {
4016 bool fAllowLocalLogon = true;
4017 if (argc == 7)
4018 {
4019 if (strcmp(argv[5], "-allowlocallogon") != 0)
4020 {
4021 errorArgument("Invalid parameter '%s'", argv[5]);
4022 rc = E_FAIL;
4023 break;
4024 }
4025 if (strcmp(argv[6], "no") == 0)
4026 fAllowLocalLogon = false;
4027 }
4028 else if (argc != 5)
4029 {
4030 errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");
4031 rc = E_FAIL;
4032 break;
4033 }
4034
4035 ComPtr<IGuest> guest;
4036 CHECK_ERROR_BREAK(console, COMGETTER(Guest)(guest.asOutParam()));
4037 CHECK_ERROR_BREAK(guest, SetCredentials(Bstr(argv[2]), Bstr(argv[3]), Bstr(argv[4]), fAllowLocalLogon));
4038 }
4039 else if (strcmp(argv[1], "dvdattach") == 0)
4040 {
4041 if (argc != 3)
4042 {
4043 errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");
4044 rc = E_FAIL;
4045 break;
4046 }
4047 ComPtr<IDVDDrive> dvdDrive;
4048 sessionMachine->COMGETTER(DVDDrive)(dvdDrive.asOutParam());
4049 ASSERT(dvdDrive);
4050
4051 /* unmount? */
4052 if (strcmp(argv[2], "none") == 0)
4053 {
4054 CHECK_ERROR(dvdDrive, Unmount());
4055 }
4056 /* host drive? */
4057 else if (strncmp(argv[2], "host:", 5) == 0)
4058 {
4059 ComPtr<IHost> host;
4060 CHECK_ERROR(virtualBox, COMGETTER(Host)(host.asOutParam()));
4061 ComPtr<IHostDVDDriveCollection> hostDVDs;
4062 CHECK_ERROR(host, COMGETTER(DVDDrives)(hostDVDs.asOutParam()));
4063 ComPtr<IHostDVDDrive> hostDVDDrive;
4064 rc = hostDVDs->FindByName(Bstr(argv[2] + 5), hostDVDDrive.asOutParam());
4065 if (!hostDVDDrive)
4066 {
4067 errorArgument("Invalid host DVD drive name");
4068 rc = E_FAIL;
4069 break;
4070 }
4071 CHECK_ERROR(dvdDrive, CaptureHostDrive(hostDVDDrive));
4072 }
4073 else
4074 {
4075 /* first assume it's a UUID */
4076 Guid uuid(argv[2]);
4077 ComPtr<IDVDImage> dvdImage;
4078 rc = virtualBox->GetDVDImage(uuid, dvdImage.asOutParam());
4079 if (FAILED(rc) || !dvdImage)
4080 {
4081 /* must be a filename, check if it's in the collection */
4082 ComPtr<IDVDImageCollection> dvdImages;
4083 virtualBox->COMGETTER(DVDImages)(dvdImages.asOutParam());
4084 rc = dvdImages->FindByPath(Bstr(argv[2]), dvdImage.asOutParam());
4085 /* not registered, do that on the fly */
4086 if (!dvdImage)
4087 {
4088 Guid emptyUUID;
4089 CHECK_ERROR(virtualBox, OpenDVDImage(Bstr(argv[2]), emptyUUID, dvdImage.asOutParam()));
4090 if (SUCCEEDED(rc) && dvdImage)
4091 {
4092 /* time to register the image */
4093 CHECK_ERROR(virtualBox, RegisterDVDImage(dvdImage));
4094 }
4095 }
4096 }
4097 if (!dvdImage)
4098 {
4099 rc = E_FAIL;
4100 break;
4101 }
4102 dvdImage->COMGETTER(Id)(uuid.asOutParam());
4103 CHECK_ERROR(dvdDrive, MountImage(uuid));
4104 }
4105 }
4106 else if (strcmp(argv[1], "floppyattach") == 0)
4107 {
4108 if (argc != 3)
4109 {
4110 errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");
4111 rc = E_FAIL;
4112 break;
4113 }
4114
4115 ComPtr<IFloppyDrive> floppyDrive;
4116 sessionMachine->COMGETTER(FloppyDrive)(floppyDrive.asOutParam());
4117 ASSERT(floppyDrive);
4118
4119 /* unmount? */
4120 if (strcmp(argv[2], "none") == 0)
4121 {
4122 CHECK_ERROR(floppyDrive, Unmount());
4123 }
4124 /* host drive? */
4125 else if (strncmp(argv[2], "host:", 5) == 0)
4126 {
4127 ComPtr<IHost> host;
4128 CHECK_ERROR(virtualBox, COMGETTER(Host)(host.asOutParam()));
4129 ComPtr<IHostFloppyDriveCollection> hostFloppies;
4130 CHECK_ERROR(host, COMGETTER(FloppyDrives)(hostFloppies.asOutParam()));
4131 ComPtr<IHostFloppyDrive> hostFloppyDrive;
4132 rc = hostFloppies->FindByName(Bstr(argv[2] + 5), hostFloppyDrive.asOutParam());
4133 if (!hostFloppyDrive)
4134 {
4135 errorArgument("Invalid host floppy drive name");
4136 rc = E_FAIL;
4137 break;
4138 }
4139 CHECK_ERROR(floppyDrive, CaptureHostDrive(hostFloppyDrive));
4140 }
4141 else
4142 {
4143 /* first assume it's a UUID */
4144 Guid uuid(argv[2]);
4145 ComPtr<IFloppyImage> floppyImage;
4146 rc = virtualBox->GetFloppyImage(uuid, floppyImage.asOutParam());
4147 if (FAILED(rc) || !floppyImage)
4148 {
4149 /* must be a filename */
4150 Guid emptyUUID;
4151 CHECK_ERROR(virtualBox, OpenFloppyImage(Bstr(argv[2]), emptyUUID, floppyImage.asOutParam()));
4152 if (SUCCEEDED(rc) && floppyImage)
4153 {
4154 /** @todo first iterate through the collection and try to find the image */
4155 /* time to register the image */
4156 CHECK_ERROR(virtualBox, RegisterFloppyImage(floppyImage));
4157 }
4158 }
4159 if (!floppyImage)
4160 {
4161 rc = E_FAIL;
4162 break;
4163 }
4164 floppyImage->COMGETTER(Id)(uuid.asOutParam());
4165 CHECK_ERROR(floppyDrive, MountImage(uuid));
4166 }
4167 }
4168 else
4169 {
4170 errorSyntax(USAGE_CONTROLVM, "Invalid parameter '%s'", Utf8Str(argv[1]).raw());
4171 rc = E_FAIL;
4172 }
4173 }
4174 while (0);
4175
4176 session->Close();
4177
4178 return SUCCEEDED (rc) ? 0 : 1;
4179}
4180
4181static int handleDiscardState(int argc, char *argv[],
4182 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
4183{
4184 HRESULT rc;
4185
4186 if (argc != 1)
4187 {
4188 return errorSyntax(USAGE_DISCARDSTATE, "Incorrect number of parameters");
4189 }
4190
4191 ComPtr<IMachine> machine;
4192 /* assume it's a UUID */
4193 rc = virtualBox->GetMachine(Guid(argv[0]), machine.asOutParam());
4194 if (FAILED(rc) || !machine)
4195 {
4196 /* must be a name */
4197 CHECK_ERROR(virtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam()));
4198 }
4199 if (machine)
4200 {
4201 do
4202 {
4203 /* we have to open a session for this task */
4204 Guid guid;
4205 machine->COMGETTER(Id)(guid.asOutParam());
4206 CHECK_ERROR_BREAK(virtualBox, OpenSession(session, guid));
4207 ComPtr<IConsole> console;
4208 CHECK_ERROR_BREAK(session, COMGETTER(Console)(console.asOutParam()));
4209 CHECK_ERROR_BREAK(console, DiscardSavedState());
4210 CHECK_ERROR_BREAK(session, Close());
4211 } while (0);
4212 }
4213
4214 return SUCCEEDED(rc) ? 0 : 1;
4215}
4216
4217static int handleSnapshot(int argc, char *argv[],
4218 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
4219{
4220 HRESULT rc;
4221
4222 /* we need at least a VM and a command */
4223 if (argc < 2)
4224 {
4225 return errorSyntax(USAGE_SNAPSHOT, "Not enough parameters");
4226 }
4227
4228 /* the first argument must be the VM */
4229 ComPtr<IMachine> machine;
4230 /* assume it's a UUID */
4231 rc = virtualBox->GetMachine(Guid(argv[0]), machine.asOutParam());
4232 if (FAILED(rc) || !machine)
4233 {
4234 /* must be a name */
4235 CHECK_ERROR(virtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam()));
4236 }
4237 if (!machine)
4238 return 1;
4239 Guid guid;
4240 machine->COMGETTER(Id)(guid.asOutParam());
4241
4242 do
4243 {
4244 /* we have to open a session for this task. First try an existing session */
4245 rc = virtualBox->OpenExistingSession(session, guid);
4246 if (FAILED(rc))
4247 CHECK_ERROR_BREAK(virtualBox, OpenSession(session, guid));
4248 ComPtr<IConsole> console;
4249 CHECK_ERROR_BREAK(session, COMGETTER(Console)(console.asOutParam()));
4250
4251 /* switch based on the command */
4252 if (strcmp(argv[1], "take") == 0)
4253 {
4254 /* there must be a name */
4255 if (argc < 3)
4256 {
4257 errorSyntax(USAGE_SNAPSHOT, "Missing snapshot name");
4258 rc = E_FAIL;
4259 break;
4260 }
4261 Bstr name(argv[2]);
4262 if ((argc > 3) && ((argc != 5) || (strcmp(argv[3], "-desc") != 0)))
4263 {
4264 errorSyntax(USAGE_SNAPSHOT, "Incorrect description format");
4265 rc = E_FAIL;
4266 break;
4267 }
4268 Bstr desc;
4269 if (argc == 5)
4270 desc = argv[4];
4271 ComPtr<IProgress> progress;
4272 CHECK_ERROR_BREAK(console, TakeSnapshot(name, desc, progress.asOutParam()));
4273
4274 showProgress(progress);
4275 progress->COMGETTER(ResultCode)(&rc);
4276 if (FAILED(rc))
4277 {
4278 com::ProgressErrorInfo info(progress);
4279 if (info.isBasicAvailable())
4280 {
4281 RTPrintf("Error: failed to take snapshot. Error message: %lS\n", info.getText().raw());
4282 }
4283 else
4284 {
4285 RTPrintf("Error: failed to take snapshot. No error message available!\n");
4286 }
4287 }
4288 }
4289 else if (strcmp(argv[1], "discard") == 0)
4290 {
4291 /* exactly one parameter: snapshot name */
4292 if (argc != 3)
4293 {
4294 errorSyntax(USAGE_SNAPSHOT, "Expecting snapshot name only");
4295 rc = E_FAIL;
4296 break;
4297 }
4298
4299 ComPtr<ISnapshot> snapshot;
4300
4301 /* assume it's a UUID */
4302 Guid guid(argv[2]);
4303 if (!guid.isEmpty())
4304 {
4305 CHECK_ERROR_BREAK(machine, GetSnapshot(guid, snapshot.asOutParam()));
4306 }
4307 else
4308 {
4309 /* then it must be a name */
4310 CHECK_ERROR_BREAK(machine, FindSnapshot(Bstr(argv[2]), snapshot.asOutParam()));
4311 }
4312
4313 snapshot->COMGETTER(Id)(guid.asOutParam());
4314
4315 ComPtr<IProgress> progress;
4316 CHECK_ERROR_BREAK(console, DiscardSnapshot(guid, progress.asOutParam()));
4317
4318 showProgress(progress);
4319 progress->COMGETTER(ResultCode)(&rc);
4320 if (FAILED(rc))
4321 {
4322 com::ProgressErrorInfo info(progress);
4323 if (info.isBasicAvailable())
4324 {
4325 RTPrintf("Error: failed to discard snapshot. Error message: %lS\n", info.getText().raw());
4326 }
4327 else
4328 {
4329 RTPrintf("Error: failed to discard snapshot. No error message available!\n");
4330 }
4331 }
4332 }
4333 else if (strcmp(argv[1], "discardcurrent") == 0)
4334 {
4335 if ( (argc != 3)
4336 || ( (strcmp(argv[2], "-state") != 0)
4337 && (strcmp(argv[2], "-all") != 0)))
4338 {
4339 errorSyntax(USAGE_SNAPSHOT, "Invalid parameter '%s'", Utf8Str(argv[2]).raw());
4340 rc = E_FAIL;
4341 break;
4342 }
4343 bool fAll = false;
4344 if (strcmp(argv[2], "-all") == 0)
4345 fAll = true;
4346
4347 ComPtr<IProgress> progress;
4348
4349 if (fAll)
4350 {
4351 CHECK_ERROR_BREAK(console, DiscardCurrentSnapshotAndState(progress.asOutParam()));
4352 }
4353 else
4354 {
4355 CHECK_ERROR_BREAK(console, DiscardCurrentState(progress.asOutParam()));
4356 }
4357
4358 showProgress(progress);
4359 progress->COMGETTER(ResultCode)(&rc);
4360 if (FAILED(rc))
4361 {
4362 com::ProgressErrorInfo info(progress);
4363 if (info.isBasicAvailable())
4364 {
4365 RTPrintf("Error: failed to discard. Error message: %lS\n", info.getText().raw());
4366 }
4367 else
4368 {
4369 RTPrintf("Error: failed to discard. No error message available!\n");
4370 }
4371 }
4372
4373 }
4374 else if (strcmp(argv[1], "edit") == 0)
4375 {
4376 if (argc < 3)
4377 {
4378 errorSyntax(USAGE_SNAPSHOT, "Missing snapshot name");
4379 rc = E_FAIL;
4380 break;
4381 }
4382
4383 ComPtr<ISnapshot> snapshot;
4384
4385 if (strcmp(argv[2], "-current") == 0)
4386 {
4387 CHECK_ERROR_BREAK(machine, COMGETTER(CurrentSnapshot)(snapshot.asOutParam()));
4388 }
4389 else
4390 {
4391 /* assume it's a UUID */
4392 Guid guid(argv[2]);
4393 if (!guid.isEmpty())
4394 {
4395 CHECK_ERROR_BREAK(machine, GetSnapshot(guid, snapshot.asOutParam()));
4396 }
4397 else
4398 {
4399 /* then it must be a name */
4400 CHECK_ERROR_BREAK(machine, FindSnapshot(Bstr(argv[2]), snapshot.asOutParam()));
4401 }
4402 }
4403
4404 /* parse options */
4405 for (int i = 3; i < argc; i++)
4406 {
4407 if (strcmp(argv[i], "-newname") == 0)
4408 {
4409 if (argc <= i + 1)
4410 {
4411 errorArgument("Missing argument to '%s'", argv[i]);
4412 rc = E_FAIL;
4413 break;
4414 }
4415 i++;
4416 snapshot->COMSETTER(Name)(Bstr(argv[i]));
4417 }
4418 else if (strcmp(argv[i], "-newdesc") == 0)
4419 {
4420 if (argc <= i + 1)
4421 {
4422 errorArgument("Missing argument to '%s'", argv[i]);
4423 rc = E_FAIL;
4424 break;
4425 }
4426 i++;
4427 snapshot->COMSETTER(Description)(Bstr(argv[i]));
4428 }
4429 else
4430 {
4431 errorSyntax(USAGE_SNAPSHOT, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());
4432 rc = E_FAIL;
4433 break;
4434 }
4435 }
4436
4437 }
4438 else if (strcmp(argv[1], "showvminfo") == 0)
4439 {
4440 /* exactly one parameter: snapshot name */
4441 if (argc != 3)
4442 {
4443 errorSyntax(USAGE_SNAPSHOT, "Expecting snapshot name only");
4444 rc = E_FAIL;
4445 break;
4446 }
4447
4448 ComPtr<ISnapshot> snapshot;
4449
4450 /* assume it's a UUID */
4451 Guid guid(argv[2]);
4452 if (!guid.isEmpty())
4453 {
4454 CHECK_ERROR_BREAK(machine, GetSnapshot(guid, snapshot.asOutParam()));
4455 }
4456 else
4457 {
4458 /* then it must be a name */
4459 CHECK_ERROR_BREAK(machine, FindSnapshot(Bstr(argv[2]), snapshot.asOutParam()));
4460 }
4461
4462 /* get the machine of the given snapshot */
4463 ComPtr<IMachine> machine;
4464 snapshot->COMGETTER(Machine)(machine.asOutParam());
4465 showVMInfo(virtualBox, machine, console);
4466 }
4467 else
4468 {
4469 errorSyntax(USAGE_SNAPSHOT, "Invalid parameter '%s'", Utf8Str(argv[1]).raw());
4470 rc = E_FAIL;
4471 }
4472 } while (0);
4473
4474 session->Close();
4475
4476 return SUCCEEDED(rc) ? 0 : 1;
4477}
4478
4479static int handleShowVDIInfo(int argc, char *argv[],
4480 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
4481{
4482 HRESULT rc;
4483
4484 if (argc != 1)
4485 {
4486 return errorSyntax(USAGE_SHOWVDIINFO, "Incorrect number of parameters");
4487 }
4488
4489 ComPtr<IHardDisk> hardDisk;
4490 ComPtr<IVirtualDiskImage> vdi;
4491 Bstr filepath;
4492
4493 bool registered = true;
4494
4495 /* first guess is that it's a UUID */
4496 Guid uuid(argv[0]);
4497 rc = virtualBox->GetHardDisk(uuid, hardDisk.asOutParam());
4498 /* no? then it must be a filename */
4499 if (FAILED (rc))
4500 {
4501 filepath = argv[0];
4502 rc = virtualBox->FindVirtualDiskImage(filepath, vdi.asOutParam());
4503 /* no? well, then it's an unregistered image */
4504 if (FAILED (rc))
4505 {
4506 registered = false;
4507 CHECK_ERROR(virtualBox, OpenVirtualDiskImage(filepath, vdi.asOutParam()));
4508 }
4509 if (SUCCEEDED (rc))
4510 hardDisk = vdi;
4511 }
4512 else
4513 {
4514 vdi = hardDisk;
4515 }
4516 if (SUCCEEDED(rc) && hardDisk)
4517 {
4518 hardDisk->COMGETTER(Id)(uuid.asOutParam());
4519 RTPrintf("UUID: %s\n", uuid.toString().raw());
4520
4521 RTPrintf("Registered: %s\n", registered ? "yes" : "no");
4522
4523 /* check for accessibility */
4524 BOOL accessible = FALSE;
4525 CHECK_ERROR_RET (hardDisk, COMGETTER(Accessible)(&accessible), 1);
4526 RTPrintf("Accessible: %s\n", accessible ? "yes" : "no");
4527
4528 if (accessible)
4529 {
4530 Bstr description;
4531 hardDisk->COMGETTER(Description)(description.asOutParam());
4532 if (description)
4533 {
4534 RTPrintf("Description: %lS\n", description.raw());
4535 }
4536
4537 ULONG64 size;
4538 hardDisk->COMGETTER(Size)(&size);
4539 RTPrintf("Size: %llu MBytes\n", size);
4540 ULONG64 actualSize;
4541 hardDisk->COMGETTER(ActualSize)(&actualSize);
4542 RTPrintf("Current size on disk: %llu MBytes\n", actualSize >> 20);
4543 }
4544 else
4545 {
4546 Bstr err;
4547 CHECK_ERROR_RET (hardDisk, COMGETTER(LastAccessError)(err.asOutParam()), 1);
4548 RTPrintf("Access Error: %lS\n", err.raw());
4549 }
4550
4551 HardDiskType_T type;
4552 hardDisk->COMGETTER(Type)(&type);
4553 char *typeStr = "unknown";
4554 switch (type)
4555 {
4556 case HardDiskType_NormalHardDisk:
4557 typeStr = "standard";
4558 break;
4559 case HardDiskType_ImmutableHardDisk:
4560 typeStr = "immutable";
4561 break;
4562 case HardDiskType_WritethroughHardDisk:
4563 typeStr = "writethrough";
4564 break;
4565 }
4566 RTPrintf("Type: %s\n", typeStr);
4567
4568 HardDiskStorageType_T storageType;
4569 char *storageTypeStr = "unknown";
4570 hardDisk->COMGETTER(StorageType)(&storageType);
4571 switch (storageType)
4572 {
4573 case HardDiskStorageType_VirtualDiskImage:
4574 storageTypeStr = "Virtual Disk Image (VDI)";
4575 break;
4576 case HardDiskStorageType_ISCSIHardDisk:
4577 storageTypeStr = "iSCSI target";
4578 break;
4579 }
4580 RTPrintf("Storage type: %s\n", storageTypeStr);
4581
4582 if (registered)
4583 {
4584 hardDisk->COMGETTER(MachineId)(uuid.asOutParam());
4585 RTPrintf("In use by VM: %s\n", uuid ? uuid.toString().raw() : "<none>");
4586 }
4587
4588 if (vdi)
4589 {
4590 /* VDI specific information */
4591 vdi->COMGETTER(FilePath)(filepath.asOutParam());
4592 RTPrintf("Path: %lS\n", filepath.raw());
4593
4594 }
4595 else
4596 {
4597 /* Generic location information */
4598 Bstr loc;
4599 hardDisk->COMGETTER(Location)(loc.asOutParam());
4600 RTPrintf("Location: %lS\n", loc.raw());
4601 }
4602 }
4603 return SUCCEEDED(rc) ? 0 : 1;
4604}
4605
4606static int handleRegisterImage(int argc, char *argv[],
4607 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
4608{
4609 HRESULT rc;
4610
4611 if (argc < 2)
4612 {
4613 return errorSyntax(USAGE_REGISTERIMAGE, "Not enough parameters");
4614 }
4615
4616 Bstr filepath(argv[1]);
4617
4618 if (strcmp(argv[0], "disk") == 0)
4619 {
4620 char *type = "normal";
4621 /* there can be a type parameter */
4622 if ((argc > 2) && (argc != 4))
4623 {
4624 return errorSyntax(USAGE_REGISTERIMAGE, "Incorrect number of parameters");
4625 }
4626 if (argc == 4)
4627 {
4628 if (strcmp(argv[2], "-type") != 0)
4629 {
4630 return errorSyntax(USAGE_REGISTERIMAGE, "Invalid parameter '%s'", Utf8Str(argv[2]).raw());
4631 }
4632 if ( (strcmp(argv[3], "normal") != 0)
4633 && (strcmp(argv[3], "immutable") != 0)
4634 && (strcmp(argv[3], "writethrough") != 0))
4635 {
4636 return errorArgument("Invalid VDI type '%s' specified", Utf8Str(argv[3]).raw());
4637 }
4638 type = argv[3];
4639 }
4640
4641 ComPtr<IVirtualDiskImage> vdi;
4642
4643 CHECK_ERROR(virtualBox, OpenVirtualDiskImage(filepath, vdi.asOutParam()));
4644 if (SUCCEEDED(rc) && vdi)
4645 {
4646 ComPtr<IHardDisk> hardDisk = vdi;
4647 /* change the type if requested */
4648 if (strcmp(type, "normal") == 0)
4649 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_NormalHardDisk));
4650 else if (strcmp(type, "immutable") == 0)
4651 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_ImmutableHardDisk));
4652 else if (strcmp(type, "writethrough") == 0)
4653 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_WritethroughHardDisk));
4654 CHECK_ERROR(virtualBox, RegisterHardDisk(hardDisk));
4655 }
4656 }
4657 else if (strcmp(argv[0], "dvd") == 0)
4658 {
4659 ComPtr<IDVDImage> dvdImage;
4660 CHECK_ERROR(virtualBox, OpenDVDImage(filepath, Guid(), dvdImage.asOutParam()));
4661 if (SUCCEEDED(rc) && dvdImage)
4662 {
4663 CHECK_ERROR(virtualBox, RegisterDVDImage(dvdImage));
4664 }
4665 }
4666 else if (strcmp(argv[0], "floppy") == 0)
4667 {
4668 ComPtr<IFloppyImage> floppyImage;
4669 CHECK_ERROR(virtualBox, OpenFloppyImage(filepath, Guid(), floppyImage.asOutParam()));
4670 if (SUCCEEDED(rc) && floppyImage)
4671 {
4672 CHECK_ERROR(virtualBox, RegisterFloppyImage(floppyImage));
4673 }
4674 }
4675 else
4676 {
4677 return errorSyntax(USAGE_REGISTERIMAGE, "Invalid parameter '%s'", Utf8Str(argv[1]).raw());
4678 }
4679 return SUCCEEDED(rc) ? 0 : 1;
4680}
4681
4682static int handleUnregisterImage(int argc, char *argv[],
4683 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
4684{
4685 HRESULT rc;
4686
4687 if (argc != 2)
4688 {
4689 return errorSyntax(USAGE_UNREGISTERIMAGE, "Incorrect number of parameters");
4690 }
4691
4692 /* first guess is that it's a UUID */
4693 Guid uuid(argv[1]);
4694
4695 if (strcmp(argv[0], "disk") == 0)
4696 {
4697 ComPtr<IHardDisk> hardDisk;
4698 rc = virtualBox->GetHardDisk(uuid, hardDisk.asOutParam());
4699 /* not a UUID or not registered? Then it must be a filename */
4700 if (!hardDisk)
4701 {
4702 ComPtr<IVirtualDiskImage> vdi;
4703 CHECK_ERROR(virtualBox, FindVirtualDiskImage(Bstr(argv[1]), vdi.asOutParam()));
4704 hardDisk = vdi;
4705 }
4706 if (SUCCEEDED(rc) && hardDisk)
4707 {
4708 hardDisk->COMGETTER(Id)(uuid.asOutParam());
4709 CHECK_ERROR(virtualBox, UnregisterHardDisk(uuid, hardDisk.asOutParam()));
4710 }
4711 }
4712 else
4713 if (strcmp(argv[0], "dvd") == 0)
4714 {
4715 ComPtr<IDVDImage> dvdImage;
4716 rc = virtualBox->GetDVDImage(uuid, dvdImage.asOutParam());
4717 /* not a UUID or not registered? Then it must be a filename */
4718 if (!dvdImage)
4719 {
4720 ComPtr<IDVDImageCollection> dvdColl;
4721 virtualBox->COMGETTER(DVDImages)(dvdColl.asOutParam());
4722 CHECK_ERROR(dvdColl, FindByPath(Bstr(argv[1]), dvdImage.asOutParam()));
4723 }
4724 if (SUCCEEDED(rc) && dvdImage)
4725 {
4726 dvdImage->COMGETTER(Id)(uuid.asOutParam());
4727 CHECK_ERROR(virtualBox, UnregisterDVDImage(uuid, dvdImage.asOutParam()));
4728 }
4729 }
4730 else
4731 if (strcmp(argv[0], "floppy") == 0)
4732 {
4733 ComPtr<IFloppyImage> floppyImage;
4734 rc = virtualBox->GetFloppyImage(uuid, floppyImage.asOutParam());
4735 /* not a UUID or not registered? Then it must be a filename */
4736 if (!floppyImage)
4737 {
4738 ComPtr<IFloppyImageCollection> floppyColl;
4739 virtualBox->COMGETTER(FloppyImages)(floppyColl.asOutParam());
4740 CHECK_ERROR(floppyColl, FindByPath(Bstr(argv[1]), floppyImage.asOutParam()));
4741 }
4742 if (SUCCEEDED(rc) && floppyImage)
4743 {
4744 floppyImage->COMGETTER(Id)(uuid.asOutParam());
4745 CHECK_ERROR(virtualBox, UnregisterFloppyImage(uuid, floppyImage.asOutParam()));
4746 }
4747 }
4748 else
4749 {
4750 return errorSyntax(USAGE_UNREGISTERIMAGE, "Invalid parameter '%s'", Utf8Str(argv[1]).raw());
4751 }
4752 return SUCCEEDED(rc) ? 0 : 1;
4753}
4754
4755#ifdef __WIN__
4756static int handleCreateHostIF(int argc, char *argv[],
4757 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
4758{
4759 if (argc != 1)
4760 {
4761 return errorSyntax(USAGE_CREATEHOSTIF, "Incorrect number of parameters");
4762 }
4763
4764 HRESULT rc = S_OK;
4765
4766 do
4767 {
4768 ComPtr<IHost> host;
4769 CHECK_ERROR_BREAK(virtualBox, COMGETTER(Host)(host.asOutParam()));
4770
4771 ComPtr<IHostNetworkInterface> hostif;
4772 ComPtr<IProgress> progress;
4773 CHECK_ERROR_BREAK(host,
4774 CreateHostNetworkInterface(Bstr(argv[0]),
4775 hostif.asOutParam(),
4776 progress.asOutParam()));
4777
4778 showProgress(progress);
4779 HRESULT result;
4780 CHECK_ERROR_BREAK(progress, COMGETTER(ResultCode)(&result));
4781 if (FAILED(result))
4782 {
4783 com::ProgressErrorInfo info(progress);
4784 PRINT_ERROR_INFO(info);
4785 rc = result;
4786 }
4787 }
4788 while (0);
4789
4790 return SUCCEEDED(rc) ? 0 : 1;
4791}
4792
4793static int handleRemoveHostIF(int argc, char *argv[],
4794 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
4795{
4796 if (argc != 1)
4797 {
4798 return errorSyntax(USAGE_REMOVEHOSTIF, "Incorrect number of parameters");
4799 }
4800
4801 HRESULT rc = S_OK;
4802
4803 do
4804 {
4805 ComPtr<IHost> host;
4806 CHECK_ERROR_BREAK(virtualBox, COMGETTER(Host)(host.asOutParam()));
4807
4808 ComPtr<IHostNetworkInterface> hostif;
4809
4810 /* first guess is that it's a UUID */
4811 Guid uuid(argv[0]);
4812 if (uuid.isEmpty())
4813 {
4814 /* not a valid UUID, search for it */
4815 ComPtr<IHostNetworkInterfaceCollection> coll;
4816 CHECK_ERROR_BREAK(host, COMGETTER(NetworkInterfaces)(coll.asOutParam()));
4817 CHECK_ERROR_BREAK(coll, FindByName(Bstr(argv[0]), hostif.asOutParam()));
4818 CHECK_ERROR_BREAK(hostif, COMGETTER(Id)(uuid.asOutParam()));
4819 }
4820
4821 ComPtr<IProgress> progress;
4822 CHECK_ERROR_BREAK(host,
4823 RemoveHostNetworkInterface(uuid,
4824 hostif.asOutParam(),
4825 progress.asOutParam()));
4826
4827 showProgress(progress);
4828 HRESULT result;
4829 CHECK_ERROR_BREAK(progress, COMGETTER(ResultCode)(&result));
4830 if (FAILED(result))
4831 {
4832 com::ProgressErrorInfo info(progress);
4833 PRINT_ERROR_INFO(info);
4834 rc = result;
4835 }
4836 }
4837 while (0);
4838
4839 return SUCCEEDED(rc) ? 0 : 1;
4840}
4841#endif /* __WIN__ */
4842
4843static int handleGetExtraData(int argc, char *argv[],
4844 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
4845{
4846 HRESULT rc = S_OK;
4847
4848 if (argc != 2)
4849 {
4850 return errorSyntax(USAGE_GETEXTRADATA, "Incorrect number of parameters");
4851 }
4852 /* global data? */
4853 if (strcmp(argv[0], "global") == 0)
4854 {
4855 /* enumeration? */
4856 if (strcmp(argv[1], "enumerate") == 0)
4857 {
4858 Bstr extraDataKey;
4859
4860 do
4861 {
4862 Bstr nextExtraDataKey;
4863 Bstr nextExtraDataValue;
4864 HRESULT rcEnum = virtualBox->GetNextExtraDataKey(extraDataKey, nextExtraDataKey.asOutParam(),
4865 nextExtraDataValue.asOutParam());
4866 extraDataKey = nextExtraDataKey;
4867
4868 if (SUCCEEDED(rcEnum) && extraDataKey)
4869 {
4870 RTPrintf("Key: %lS, Value: %lS\n", nextExtraDataKey.raw(), nextExtraDataValue.raw());
4871 }
4872 } while (extraDataKey);
4873 }
4874 else
4875 {
4876 Bstr value;
4877 CHECK_ERROR(virtualBox, GetExtraData(Bstr(argv[1]), value.asOutParam()));
4878 if (value)
4879 RTPrintf("Value: %lS\n", value.raw());
4880 else
4881 RTPrintf("No value set!\n");
4882 }
4883 }
4884 else
4885 {
4886 ComPtr<IMachine> machine;
4887 /* assume it's a UUID */
4888 rc = virtualBox->GetMachine(Guid(argv[0]), machine.asOutParam());
4889 if (FAILED(rc) || !machine)
4890 {
4891 /* must be a name */
4892 CHECK_ERROR(virtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam()));
4893 }
4894 if (machine)
4895 {
4896 /* enumeration? */
4897 if (strcmp(argv[1], "enumerate") == 0)
4898 {
4899 Bstr extraDataKey;
4900
4901 do
4902 {
4903 Bstr nextExtraDataKey;
4904 Bstr nextExtraDataValue;
4905 HRESULT rcEnum = machine->GetNextExtraDataKey(extraDataKey, nextExtraDataKey.asOutParam(),
4906 nextExtraDataValue.asOutParam());
4907 extraDataKey = nextExtraDataKey;
4908
4909 if (SUCCEEDED(rcEnum) && extraDataKey)
4910 {
4911 RTPrintf("Key: %lS, Value: %lS\n", nextExtraDataKey.raw(), nextExtraDataValue.raw());
4912 }
4913 } while (extraDataKey);
4914 }
4915 else
4916 {
4917 Bstr value;
4918 CHECK_ERROR(machine, GetExtraData(Bstr(argv[1]), value.asOutParam()));
4919 if (value)
4920 RTPrintf("Value: %lS\n", value.raw());
4921 else
4922 RTPrintf("No value set!\n");
4923 }
4924 }
4925 }
4926 return SUCCEEDED(rc) ? 0 : 1;
4927}
4928
4929static int handleSetExtraData(int argc, char *argv[],
4930 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
4931{
4932 HRESULT rc = S_OK;
4933
4934 if (argc < 2)
4935 {
4936 return errorSyntax(USAGE_SETEXTRADATA, "Not enough parameters");
4937 }
4938 /* global data? */
4939 if (strcmp(argv[0], "global") == 0)
4940 {
4941 if (argc < 3)
4942 CHECK_ERROR(virtualBox, SetExtraData(Bstr(argv[1]), NULL));
4943 else if (argc == 3)
4944 CHECK_ERROR(virtualBox, SetExtraData(Bstr(argv[1]), Bstr(argv[2])));
4945 else
4946 return errorSyntax(USAGE_SETEXTRADATA, "Too many parameters");
4947 }
4948 else
4949 {
4950 ComPtr<IMachine> machine;
4951 /* assume it's a UUID */
4952 rc = virtualBox->GetMachine(Guid(argv[0]), machine.asOutParam());
4953 if (FAILED(rc) || !machine)
4954 {
4955 /* must be a name */
4956 CHECK_ERROR(virtualBox, FindMachine(Bstr(argv[0]), machine.asOutParam()));
4957 }
4958 if (machine)
4959 {
4960 if (argc < 3)
4961 CHECK_ERROR(machine, SetExtraData(Bstr(argv[1]), NULL));
4962 else if (argc == 3)
4963 CHECK_ERROR(machine, SetExtraData(Bstr(argv[1]), Bstr(argv[2])));
4964 else
4965 return errorSyntax(USAGE_SETEXTRADATA, "Too many parameters");
4966 }
4967 }
4968 return SUCCEEDED(rc) ? 0 : 1;
4969}
4970
4971static int handleSetProperty(int argc, char *argv[],
4972 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
4973{
4974 HRESULT rc;
4975
4976 /* there must be two arguments: property name and value */
4977 if (argc != 2)
4978 {
4979 return errorSyntax(USAGE_SETPROPERTY, "Incorrect number of parameters");
4980 }
4981 ComPtr<ISystemProperties> systemProperties;
4982 virtualBox->COMGETTER(SystemProperties)(systemProperties.asOutParam());
4983
4984 if (strcmp(argv[0], "vdifolder") == 0)
4985 {
4986 /* reset to default? */
4987 if (strcmp(argv[1], "default") == 0)
4988 {
4989 CHECK_ERROR(systemProperties, COMSETTER(DefaultVDIFolder)(NULL));
4990 }
4991 else
4992 {
4993 CHECK_ERROR(systemProperties, COMSETTER(DefaultVDIFolder)(Bstr(argv[1])));
4994 }
4995 }
4996 else if (strcmp(argv[0], "machinefolder") == 0)
4997 {
4998 /* reset to default? */
4999 if (strcmp(argv[1], "default") == 0)
5000 {
5001 CHECK_ERROR(systemProperties, COMSETTER(DefaultMachineFolder)(NULL));
5002 }
5003 else
5004 {
5005 CHECK_ERROR(systemProperties, COMSETTER(DefaultMachineFolder)(Bstr(argv[1])));
5006 }
5007 }
5008 else if (strcmp(argv[0], "vrdpauthlibrary") == 0)
5009 {
5010 /* reset to default? */
5011 if (strcmp(argv[1], "default") == 0)
5012 {
5013 CHECK_ERROR(systemProperties, COMSETTER(RemoteDisplayAuthLibrary)(NULL));
5014 }
5015 else
5016 {
5017 CHECK_ERROR(systemProperties, COMSETTER(RemoteDisplayAuthLibrary)(Bstr(argv[1])));
5018 }
5019 }
5020 else if (strcmp(argv[0], "hwvirtexenabled") == 0)
5021 {
5022 if (strcmp(argv[1], "yes") == 0)
5023 CHECK_ERROR(systemProperties, COMSETTER(HWVirtExEnabled)(TRUE));
5024 else if (strcmp(argv[1], "no") == 0)
5025 CHECK_ERROR(systemProperties, COMSETTER(HWVirtExEnabled)(FALSE));
5026 else
5027 return errorArgument("Invalid value '%s' for hardware virtualization extension flag", argv[1]);
5028 }
5029 else
5030 {
5031 return errorSyntax(USAGE_SETPROPERTY, "Invalid parameter '%s'", Utf8Str(argv[0]).raw());
5032 }
5033
5034 return SUCCEEDED(rc) ? 0 : 1;
5035}
5036
5037static int handleUSBFilter (int argc, char *argv[],
5038 ComPtr <IVirtualBox> aVirtualBox, ComPtr<ISession> aSession)
5039{
5040 HRESULT rc = S_OK;
5041 USBFilterCmd cmd;
5042
5043 /* at least: 0: command, 1: index, 2: -target, 3: <target value> */
5044 if (argc < 4)
5045 {
5046 return errorSyntax(USAGE_USBFILTER, "Not enough parameters");
5047 }
5048
5049 /* which command? */
5050 cmd.mAction = USBFilterCmd::Invalid;
5051 if (strcmp (argv [0], "add") == 0) cmd.mAction = USBFilterCmd::Add;
5052 else if (strcmp (argv [0], "modify") == 0) cmd.mAction = USBFilterCmd::Modify;
5053 else if (strcmp (argv [0], "remove") == 0) cmd.mAction = USBFilterCmd::Remove;
5054
5055 if (cmd.mAction == USBFilterCmd::Invalid)
5056 {
5057 return errorSyntax(USAGE_USBFILTER, "Invalid parameter '%s'", Utf8Str(argv[0]).raw());
5058 }
5059
5060 /* which index? */
5061 char *endptr = NULL;
5062 cmd.mIndex = strtoul (argv[1], &endptr, 10);
5063 if (!endptr || *endptr)
5064 {
5065 return errorSyntax(USAGE_USBFILTER, "Invalid index '%s'", argv[1]);
5066 }
5067
5068 switch (cmd.mAction)
5069 {
5070 case USBFilterCmd::Add:
5071 case USBFilterCmd::Modify:
5072 {
5073 /* at least: 0: command, 1: index, 2: -target, 3: <target value>, 4: -name, 5: <name value> */
5074 if (argc < 6)
5075 {
5076 if (cmd.mAction == USBFilterCmd::Add)
5077 {
5078 return errorSyntax(USAGE_USBFILTER_ADD, "Not enough parameters");
5079 }
5080 else
5081 {
5082 return errorSyntax(USAGE_USBFILTER_MODIFY, "Not enough parameters");
5083 }
5084 }
5085
5086 // set Active to true by default
5087 // (assuming that the user sets up all necessary attributes
5088 // at once and wants the filter to be active immediately)
5089 if (cmd.mAction == USBFilterCmd::Add)
5090 cmd.mFilter.mActive = true;
5091
5092 for (int i = 2; i < argc; i++)
5093 {
5094 if (strcmp(argv [i], "-target") == 0)
5095 {
5096 if (argc <= i + 1 || !*argv[i+1])
5097 {
5098 return errorArgument("Missing argument to '%s'", argv[i]);
5099 }
5100 i++;
5101 if (strcmp (argv [i], "global") == 0)
5102 cmd.mGlobal = true;
5103 else
5104 {
5105 /* assume it's a UUID of a machine */
5106 rc = aVirtualBox->GetMachine(Guid(argv[i]), cmd.mMachine.asOutParam());
5107 if (FAILED(rc) || !cmd.mMachine)
5108 {
5109 /* must be a name */
5110 CHECK_ERROR_RET(aVirtualBox, FindMachine(Bstr(argv[i]), cmd.mMachine.asOutParam()), 1);
5111 }
5112 }
5113 }
5114 else if (strcmp(argv [i], "-name") == 0)
5115 {
5116 if (argc <= i + 1 || !*argv[i+1])
5117 {
5118 return errorArgument("Missing argument to '%s'", argv[i]);
5119 }
5120 i++;
5121 cmd.mFilter.mName = argv [i];
5122 }
5123 else if (strcmp(argv [i], "-active") == 0)
5124 {
5125 if (argc <= i + 1)
5126 {
5127 return errorArgument("Missing argument to '%s'", argv[i]);
5128 }
5129 i++;
5130 if (strcmp (argv [i], "yes") == 0)
5131 cmd.mFilter.mActive = true;
5132 else if (strcmp (argv [i], "no") == 0)
5133 cmd.mFilter.mActive = false;
5134 else
5135 {
5136 return errorArgument("Invalid -active argument '%s'", Utf8Str(argv[i]).raw());
5137 }
5138 }
5139 else if (strcmp(argv [i], "-vendorid") == 0)
5140 {
5141 if (argc <= i + 1)
5142 {
5143 return errorArgument("Missing argument to '%s'", argv[i]);
5144 }
5145 i++;
5146 cmd.mFilter.mVendorId = argv [i];
5147 }
5148 else if (strcmp(argv [i], "-productid") == 0)
5149 {
5150 if (argc <= i + 1)
5151 {
5152 return errorArgument("Missing argument to '%s'", argv[i]);
5153 }
5154 i++;
5155 cmd.mFilter.mProductId = argv [i];
5156 }
5157 else if (strcmp(argv [i], "-revision") == 0)
5158 {
5159 if (argc <= i + 1)
5160 {
5161 return errorArgument("Missing argument to '%s'", argv[i]);
5162 }
5163 i++;
5164 cmd.mFilter.mRevision = argv [i];
5165 }
5166 else if (strcmp(argv [i], "-manufacturer") == 0)
5167 {
5168 if (argc <= i + 1)
5169 {
5170 return errorArgument("Missing argument to '%s'", argv[i]);
5171 }
5172 i++;
5173 cmd.mFilter.mManufacturer = argv [i];
5174 }
5175 else if (strcmp(argv [i], "-product") == 0)
5176 {
5177 if (argc <= i + 1)
5178 {
5179 return errorArgument("Missing argument to '%s'", argv[i]);
5180 }
5181 i++;
5182 cmd.mFilter.mProduct = argv [i];
5183 }
5184 else if (strcmp(argv [i], "-remote") == 0)
5185 {
5186 if (argc <= i + 1)
5187 {
5188 return errorArgument("Missing argument to '%s'", argv[i]);
5189 }
5190 i++;
5191 cmd.mFilter.mRemote = argv[i];
5192 }
5193 else if (strcmp(argv [i], "-serialnumber") == 0)
5194 {
5195 if (argc <= i + 1)
5196 {
5197 return errorArgument("Missing argument to '%s'", argv[i]);
5198 }
5199 i++;
5200 cmd.mFilter.mSerialNumber = argv [i];
5201 }
5202 else if (strcmp(argv [i], "-action") == 0)
5203 {
5204 if (argc <= i + 1)
5205 {
5206 return errorArgument("Missing argument to '%s'", argv[i]);
5207 }
5208 i++;
5209 if (strcmp (argv [i], "ignore") == 0)
5210 cmd.mFilter.mAction = USBDeviceFilterAction_USBDeviceFilterIgnore;
5211 else if (strcmp (argv [i], "hold") == 0)
5212 cmd.mFilter.mAction = USBDeviceFilterAction_USBDeviceFilterHold;
5213 else
5214 {
5215 return errorArgument("Invalid USB filter action '%s'", Utf8Str(argv[i]).raw());
5216 }
5217 }
5218
5219 }
5220
5221 if (cmd.mAction == USBFilterCmd::Add)
5222 {
5223 // mandatory/forbidden options
5224 if ( cmd.mFilter.mName.isEmpty()
5225 ||
5226 ( cmd.mGlobal
5227 && cmd.mFilter.mAction == USBDeviceFilterAction_InvalidUSBDeviceFilterAction
5228 )
5229 || ( !cmd.mGlobal
5230 && !cmd.mMachine)
5231 || ( cmd.mGlobal
5232 && cmd.mFilter.mRemote)
5233 )
5234 {
5235 return errorSyntax(USAGE_USBFILTER_ADD, "Mandatory options not supplied");
5236 }
5237 }
5238 break;
5239 }
5240
5241 case USBFilterCmd::Remove:
5242 {
5243 /* at least: 0: command, 1: index, 2: -target, 3: <target value> */
5244 if (argc < 4)
5245 {
5246 return errorSyntax(USAGE_USBFILTER_REMOVE, "Not enough parameters");
5247 }
5248
5249 for (int i = 2; i < argc; i++)
5250 {
5251 if (strcmp(argv [i], "-target") == 0)
5252 {
5253 if (argc <= i + 1 || !*argv[i+1])
5254 {
5255 return errorArgument("Missing argument to '%s'", argv[i]);
5256 }
5257 i++;
5258 if (strcmp (argv [i], "global") == 0)
5259 cmd.mGlobal = true;
5260 else
5261 {
5262 /* assume it's a UUID of a machine */
5263 rc = aVirtualBox->GetMachine(Guid(argv[i]), cmd.mMachine.asOutParam());
5264 if (FAILED(rc) || !cmd.mMachine)
5265 {
5266 /* must be a name */
5267 CHECK_ERROR_RET(aVirtualBox, FindMachine(Bstr(argv[i]), cmd.mMachine.asOutParam()), 1);
5268 }
5269 }
5270 }
5271 }
5272
5273 // mandatory options
5274 if (!cmd.mGlobal && !cmd.mMachine)
5275 {
5276 return errorSyntax(USAGE_USBFILTER_REMOVE, "Mandatory options not supplied");
5277 }
5278
5279 break;
5280 }
5281
5282 default: break;
5283 }
5284
5285 USBFilterCmd::USBFilter &f = cmd.mFilter;
5286
5287 ComPtr <IHost> host;
5288 ComPtr <IUSBController> ctl;
5289 if (cmd.mGlobal)
5290 CHECK_ERROR_RET (aVirtualBox, COMGETTER(Host) (host.asOutParam()), 1);
5291 else
5292 {
5293 Guid uuid;
5294 cmd.mMachine->COMGETTER(Id)(uuid.asOutParam());
5295 /* open a session for the VM */
5296 CHECK_ERROR_RET (aVirtualBox, OpenSession(aSession, uuid), 1);
5297 /* get the mutable session machine */
5298 aSession->COMGETTER(Machine)(cmd.mMachine.asOutParam());
5299 /* and get the USB controller */
5300 CHECK_ERROR_RET (cmd.mMachine, COMGETTER(USBController) (ctl.asOutParam()), 1);
5301 }
5302
5303 switch (cmd.mAction)
5304 {
5305 case USBFilterCmd::Add:
5306 {
5307 if (cmd.mGlobal)
5308 {
5309 ComPtr <IHostUSBDeviceFilter> flt;
5310 CHECK_ERROR_BREAK (host, CreateUSBDeviceFilter (f.mName, flt.asOutParam()));
5311
5312 if (!f.mActive.isNull())
5313 CHECK_ERROR_BREAK (flt, COMSETTER(Active) (f.mActive));
5314 if (!f.mVendorId.isNull())
5315 CHECK_ERROR_BREAK (flt, COMSETTER(VendorId) (f.mVendorId.setNullIfEmpty()));
5316 if (!f.mProductId.isNull())
5317 CHECK_ERROR_BREAK (flt, COMSETTER(ProductId) (f.mProductId.setNullIfEmpty()));
5318 if (!f.mRevision.isNull())
5319 CHECK_ERROR_BREAK (flt, COMSETTER(Revision) (f.mRevision.setNullIfEmpty()));
5320 if (!f.mManufacturer.isNull())
5321 CHECK_ERROR_BREAK (flt, COMSETTER(Manufacturer) (f.mManufacturer.setNullIfEmpty()));
5322 if (!f.mSerialNumber.isNull())
5323 CHECK_ERROR_BREAK (flt, COMSETTER(SerialNumber) (f.mSerialNumber.setNullIfEmpty()));
5324
5325 if (f.mAction != USBDeviceFilterAction_InvalidUSBDeviceFilterAction)
5326 CHECK_ERROR_BREAK (flt, COMSETTER(Action) (f.mAction));
5327
5328 CHECK_ERROR_BREAK (host, InsertUSBDeviceFilter (cmd.mIndex, flt));
5329 }
5330 else
5331 {
5332 ComPtr <IUSBDeviceFilter> flt;
5333 CHECK_ERROR_BREAK (ctl, CreateDeviceFilter (f.mName, flt.asOutParam()));
5334
5335 if (!f.mActive.isNull())
5336 CHECK_ERROR_BREAK (flt, COMSETTER(Active) (f.mActive));
5337 if (!f.mVendorId.isNull())
5338 CHECK_ERROR_BREAK (flt, COMSETTER(VendorId) (f.mVendorId.setNullIfEmpty()));
5339 if (!f.mProductId.isNull())
5340 CHECK_ERROR_BREAK (flt, COMSETTER(ProductId) (f.mProductId.setNullIfEmpty()));
5341 if (!f.mRevision.isNull())
5342 CHECK_ERROR_BREAK (flt, COMSETTER(Revision) (f.mRevision.setNullIfEmpty()));
5343 if (!f.mManufacturer.isNull())
5344 CHECK_ERROR_BREAK (flt, COMSETTER(Manufacturer) (f.mManufacturer.setNullIfEmpty()));
5345 if (!f.mRemote.isNull())
5346 CHECK_ERROR_BREAK (flt, COMSETTER(Remote) (f.mRemote.setNullIfEmpty()));
5347 if (!f.mSerialNumber.isNull())
5348 CHECK_ERROR_BREAK (flt, COMSETTER(SerialNumber) (f.mSerialNumber.setNullIfEmpty()));
5349
5350 CHECK_ERROR_BREAK (ctl, InsertDeviceFilter (cmd.mIndex, flt));
5351 }
5352 break;
5353 }
5354 case USBFilterCmd::Modify:
5355 {
5356 if (cmd.mGlobal)
5357 {
5358 ComPtr <IHostUSBDeviceFilterCollection> coll;
5359 CHECK_ERROR_BREAK (host, COMGETTER(USBDeviceFilters) (coll.asOutParam()));
5360 ComPtr <IHostUSBDeviceFilter> flt;
5361 CHECK_ERROR_BREAK (coll, GetItemAt (cmd.mIndex, flt.asOutParam()));
5362
5363 if (!f.mName.isNull())
5364 CHECK_ERROR_BREAK (flt, COMSETTER(Name) (f.mName.setNullIfEmpty()));
5365 if (!f.mActive.isNull())
5366 CHECK_ERROR_BREAK (flt, COMSETTER(Active) (f.mActive));
5367 if (!f.mVendorId.isNull())
5368 CHECK_ERROR_BREAK (flt, COMSETTER(VendorId) (f.mVendorId.setNullIfEmpty()));
5369 if (!f.mProductId.isNull())
5370 CHECK_ERROR_BREAK (flt, COMSETTER(ProductId) (f.mProductId.setNullIfEmpty()));
5371 if (!f.mRevision.isNull())
5372 CHECK_ERROR_BREAK (flt, COMSETTER(Revision) (f.mRevision.setNullIfEmpty()));
5373 if (!f.mManufacturer.isNull())
5374 CHECK_ERROR_BREAK (flt, COMSETTER(Manufacturer) (f.mManufacturer.setNullIfEmpty()));
5375 if (!f.mSerialNumber.isNull())
5376 CHECK_ERROR_BREAK (flt, COMSETTER(SerialNumber) (f.mSerialNumber.setNullIfEmpty()));
5377
5378 if (f.mAction != USBDeviceFilterAction_InvalidUSBDeviceFilterAction)
5379 CHECK_ERROR_BREAK (flt, COMSETTER(Action) (f.mAction));
5380 }
5381 else
5382 {
5383 ComPtr <IUSBDeviceFilterCollection> coll;
5384 CHECK_ERROR_BREAK (ctl, COMGETTER(DeviceFilters) (coll.asOutParam()));
5385
5386 ComPtr <IUSBDeviceFilter> flt;
5387 CHECK_ERROR_BREAK (coll, GetItemAt (cmd.mIndex, flt.asOutParam()));
5388
5389 if (!f.mName.isNull())
5390 CHECK_ERROR_BREAK (flt, COMSETTER(Name) (f.mName.setNullIfEmpty()));
5391 if (!f.mActive.isNull())
5392 CHECK_ERROR_BREAK (flt, COMSETTER(Active) (f.mActive));
5393 if (!f.mVendorId.isNull())
5394 CHECK_ERROR_BREAK (flt, COMSETTER(VendorId) (f.mVendorId.setNullIfEmpty()));
5395 if (!f.mProductId.isNull())
5396 CHECK_ERROR_BREAK (flt, COMSETTER(ProductId) (f.mProductId.setNullIfEmpty()));
5397 if (!f.mRevision.isNull())
5398 CHECK_ERROR_BREAK (flt, COMSETTER(Revision) (f.mRevision.setNullIfEmpty()));
5399 if (!f.mManufacturer.isNull())
5400 CHECK_ERROR_BREAK (flt, COMSETTER(Manufacturer) (f.mManufacturer.setNullIfEmpty()));
5401 if (!f.mRemote.isNull())
5402 CHECK_ERROR_BREAK (flt, COMSETTER(Remote) (f.mRemote.setNullIfEmpty()));
5403 if (!f.mSerialNumber.isNull())
5404 CHECK_ERROR_BREAK (flt, COMSETTER(SerialNumber) (f.mSerialNumber.setNullIfEmpty()));
5405 }
5406 break;
5407 }
5408 case USBFilterCmd::Remove:
5409 {
5410 if (cmd.mGlobal)
5411 {
5412 ComPtr <IHostUSBDeviceFilter> flt;
5413 CHECK_ERROR_BREAK (host, RemoveUSBDeviceFilter (cmd.mIndex, flt.asOutParam()));
5414 }
5415 else
5416 {
5417 ComPtr <IUSBDeviceFilter> flt;
5418 CHECK_ERROR_BREAK (ctl, RemoveDeviceFilter (cmd.mIndex, flt.asOutParam()));
5419 }
5420 break;
5421 }
5422 default:
5423 break;
5424 }
5425
5426 if (cmd.mMachine)
5427 {
5428 /* commit and close the session */
5429 CHECK_ERROR(cmd.mMachine, SaveSettings());
5430 aSession->Close();
5431 }
5432
5433 return SUCCEEDED (rc) ? 0 : 1;
5434}
5435
5436static int handleSharedFolder (int argc, char *argv[],
5437 ComPtr <IVirtualBox> aVirtualBox, ComPtr<ISession> aSession)
5438{
5439 HRESULT rc;
5440
5441 /* we need at least a command and target */
5442 if (argc < 2)
5443 {
5444 return errorSyntax(USAGE_SHAREDFOLDER, "Not enough parameters");
5445 }
5446
5447 ComPtr<IMachine> machine;
5448 /* assume it's a UUID */
5449 rc = aVirtualBox->GetMachine(Guid(argv[1]), machine.asOutParam());
5450 if (FAILED(rc) || !machine)
5451 {
5452 /* must be a name */
5453 CHECK_ERROR(aVirtualBox, FindMachine(Bstr(argv[1]), machine.asOutParam()));
5454 }
5455 if (!machine)
5456 return 1;
5457 Guid uuid;
5458 machine->COMGETTER(Id)(uuid.asOutParam());
5459
5460 if (strcmp(argv[0], "add") == 0)
5461 {
5462 /* we need at least four more parameters */
5463 if (argc < 5)
5464 {
5465 return errorSyntax(USAGE_SHAREDFOLDER_ADD, "Not enough parameters");
5466 }
5467
5468 char *name = NULL;
5469 char *hostpath = NULL;
5470 bool fTransient = false;
5471
5472 for (int i = 2; i < argc; i++)
5473 {
5474 if (strcmp(argv[i], "-name") == 0)
5475 {
5476 if (argc <= i + 1 || !*argv[i+1])
5477 {
5478 return errorArgument("Missing argument to '%s'", argv[i]);
5479 }
5480 i++;
5481 name = argv[i];
5482 }
5483 else if (strcmp(argv[i], "-hostpath") == 0)
5484 {
5485 if (argc <= i + 1 || !*argv[i+1])
5486 {
5487 return errorArgument("Missing argument to '%s'", argv[i]);
5488 }
5489 i++;
5490 hostpath = argv[i];
5491
5492 }
5493 else if (strcmp(argv[i], "-transient") == 0)
5494 {
5495 fTransient = true;
5496 }
5497 else
5498 {
5499 return errorSyntax(USAGE_SHAREDFOLDER_ADD, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());
5500 }
5501 }
5502
5503 /* required arguments */
5504 if (!name || !hostpath)
5505 {
5506 return errorSyntax(USAGE_SHAREDFOLDER_ADD, "Parameters -name and -hostpath are required");
5507 }
5508
5509 if (fTransient)
5510 {
5511 ComPtr <IConsole> console;
5512
5513 /* open an existing session for the VM */
5514 CHECK_ERROR_RET(aVirtualBox, OpenExistingSession (aSession, uuid), 1);
5515 /* get the session machine */
5516 CHECK_ERROR_RET(aSession, COMGETTER(Machine)(machine.asOutParam()), 1);
5517 /* get the session console */
5518 CHECK_ERROR_RET(aSession, COMGETTER(Console)(console.asOutParam()), 1);
5519
5520 CHECK_ERROR(console, CreateSharedFolder(Bstr(name), Bstr(hostpath)));
5521
5522 if (console)
5523 aSession->Close();
5524 }
5525 else
5526 {
5527 /* open a session for the VM */
5528 CHECK_ERROR_RET (aVirtualBox, OpenSession(aSession, uuid), 1);
5529
5530 /* get the mutable session machine */
5531 aSession->COMGETTER(Machine)(machine.asOutParam());
5532
5533 CHECK_ERROR(machine, CreateSharedFolder(Bstr(name), Bstr(hostpath)));
5534
5535 if (SUCCEEDED(rc))
5536 CHECK_ERROR(machine, SaveSettings());
5537
5538 aSession->Close();
5539 }
5540 }
5541 else if (strcmp(argv[0], "remove") == 0)
5542 {
5543 /* we need at least two more parameters */
5544 if (argc < 3)
5545 {
5546 return errorSyntax(USAGE_SHAREDFOLDER_REMOVE, "Not enough parameters");
5547 }
5548
5549 char *name = NULL;
5550 bool fTransient = false;
5551
5552 for (int i = 2; i < argc; i++)
5553 {
5554 if (strcmp(argv[i], "-name") == 0)
5555 {
5556 if (argc <= i + 1 || !*argv[i+1])
5557 {
5558 return errorArgument("Missing argument to '%s'", argv[i]);
5559 }
5560 i++;
5561 name = argv[i];
5562 }
5563 else if (strcmp(argv[i], "-transient") == 0)
5564 {
5565 fTransient = true;
5566 }
5567 else
5568 {
5569 return errorSyntax(USAGE_SHAREDFOLDER_REMOVE, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());
5570 }
5571 }
5572
5573 /* required arguments */
5574 if (!name)
5575 {
5576 return errorSyntax(USAGE_SHAREDFOLDER_REMOVE, "Parameter -name is required");
5577 }
5578
5579 if (fTransient)
5580 {
5581 ComPtr <IConsole> console;
5582
5583 /* open an existing session for the VM */
5584 CHECK_ERROR_RET(aVirtualBox, OpenExistingSession (aSession, uuid), 1);
5585 /* get the session machine */
5586 CHECK_ERROR_RET(aSession, COMGETTER(Machine)(machine.asOutParam()), 1);
5587 /* get the session console */
5588 CHECK_ERROR_RET(aSession, COMGETTER(Console)(console.asOutParam()), 1);
5589
5590 CHECK_ERROR(console, RemoveSharedFolder(Bstr(name)));
5591
5592 if (console)
5593 aSession->Close();
5594 }
5595 else
5596 {
5597 /* open a session for the VM */
5598 CHECK_ERROR_RET (aVirtualBox, OpenSession(aSession, uuid), 1);
5599
5600 /* get the mutable session machine */
5601 aSession->COMGETTER(Machine)(machine.asOutParam());
5602
5603 CHECK_ERROR(machine, RemoveSharedFolder(Bstr(name)));
5604
5605 /* commit and close the session */
5606 CHECK_ERROR(machine, SaveSettings());
5607 aSession->Close();
5608 }
5609 }
5610 else
5611 {
5612 return errorSyntax(USAGE_SETPROPERTY, "Invalid parameter '%s'", Utf8Str(argv[0]).raw());
5613 }
5614 return 0;
5615}
5616
5617enum HUSPD { HUSPD_DryRun, HUSPD_Apply, HUSPD_ApplyNoBackup };
5618
5619static int handleUpdateSettings_processFile (const char *filePath, HUSPD mode)
5620{
5621 RTPrintf ("%s\n", filePath);
5622
5623 CFGHANDLE config = 0;
5624 char *errMsg = NULL;
5625
5626 int vrc = CFGLDRLoad (&config, filePath, NIL_RTFILE,
5627 NULL, false, NULL, //cfgLdrEntityResolver,
5628 &errMsg);
5629 if (VBOX_SUCCESS (vrc))
5630 {
5631 CFGNODE vbox = 0;
5632 CFGLDRGetNode (config, "VirtualBox", 0, &vbox);
5633 Bstr version;
5634 CFGLDRQueryBSTR (vbox, "version", version.asOutParam());
5635 CFGLDRReleaseNode (vbox);
5636
5637 RTPrintf (" current version : %ls\n", version.raw());
5638
5639 /// @todo (dmik) use cfgLdrEntityResolver later
5640 vrc = CFGLDRTransform (config, "SettingsConverter.xsl", NULL, &errMsg);
5641 if (VBOX_SUCCESS (vrc))
5642 {
5643 CFGLDRGetNode (config, "VirtualBox", 0, &vbox);
5644 CFGLDRQueryBSTR (vbox, "version", version.asOutParam());
5645 CFGLDRReleaseNode (vbox);
5646
5647 RTPrintf (" new version : %ls\n\n", version.raw());
5648
5649 if (mode != HUSPD_DryRun)
5650 {
5651 if (mode != HUSPD_ApplyNoBackup)
5652 {
5653 Utf8StrFmt filePathBak ("%s.bak", filePath);
5654 vrc = RTFileCopy (filePath, filePathBak);
5655 if (VBOX_FAILURE (vrc))
5656 {
5657 RTPrintf ("Error copying '%s' to '%s' (%Vrc)\n",
5658 filePath, filePathBak.raw(), vrc);
5659 }
5660 }
5661
5662 if (VBOX_SUCCESS (vrc))
5663 {
5664 vrc = CFGLDRSave (config, &errMsg);
5665 if (VBOX_FAILURE (vrc))
5666 {
5667 RTPrintf ("Error saving the settings file '%s' (%Vrc)%s%s\n",
5668 filePath, vrc,
5669 errMsg ? "\n" : "", errMsg ? errMsg : "");
5670 }
5671 }
5672 }
5673 }
5674 else
5675 {
5676 RTPrintf ("Could not convert the settings file '%s' (%Vrc)%s%s\n",
5677 filePath, vrc, errMsg ? "\n" : "", errMsg ? errMsg : "");
5678 }
5679
5680 CFGLDRFree (config);
5681 }
5682 else
5683 {
5684 RTPrintf ("Error loading the settings file '%s' (%Vrc)%s%s\n",
5685 filePath, vrc, errMsg ? "\n" : "", errMsg ? errMsg : "");
5686 }
5687
5688 if (errMsg)
5689 RTStrFree (errMsg);
5690
5691 return vrc;
5692}
5693
5694static int handleUpdateSettings_processDir (const char *dirPath, HUSPD mode,
5695 bool skipInvalid)
5696{
5697 PRTDIR dir;
5698 int vrc = RTDirOpen (&dir, dirPath);
5699 if (VBOX_FAILURE (vrc))
5700 {
5701 return vrc;
5702 }
5703
5704 RTDIRENTRYEX entry;
5705 while (VBOX_SUCCESS (vrc))
5706 {
5707 vrc = RTDirReadEx (dir, &entry, NULL, RTFSOBJATTRADD_UNIX);
5708 if (VBOX_FAILURE (vrc))
5709 {
5710 if (vrc == VERR_NO_MORE_FILES)
5711 vrc = VINF_SUCCESS;
5712 else
5713 RTPrintf ("Error reading directory '%s' (%Vrc)\n", dirPath, vrc);
5714 break;
5715 }
5716
5717 if (RTFS_IS_DIRECTORY (entry.Info.Attr.fMode))
5718 {
5719 if (entry.szName[0] == '.' &&
5720 (entry.szName[1] == 0 ||
5721 (entry.szName[1] == '.' && entry.szName[2] == 0)))
5722 continue;
5723
5724 vrc = handleUpdateSettings_processDir (
5725 Utf8StrFmt ("%s%c%s", dirPath, RTPATH_DELIMITER, entry.szName),
5726 mode, skipInvalid);
5727 if (VBOX_FAILURE (vrc))
5728 break;
5729
5730 continue;
5731 }
5732 else if (RTFS_IS_FILE (entry.Info.Attr.fMode))
5733 {
5734 const char *ext = RTPathExt (entry.szName);
5735 if (!ext || strcmp (ext, ".xml") != 0)
5736 continue;
5737 }
5738 else
5739 continue;
5740
5741 Utf8Str filePath = Utf8StrFmt ("%s%c%s", dirPath, RTPATH_DELIMITER,
5742 entry.szName);
5743
5744 vrc = handleUpdateSettings_processFile (filePath, mode);
5745
5746 if (skipInvalid)
5747 vrc = VINF_SUCCESS;
5748 }
5749
5750 RTDirClose (dir);
5751
5752 return vrc;
5753}
5754
5755static int handleUpdateSettings (int argc, char *argv[])
5756{
5757 const char *dirOrFilePath = NULL;
5758 bool apply = false;
5759 bool nobackup = false;
5760 bool skipinvalid = false;
5761
5762 for (int i = 0; i < argc; i++)
5763 {
5764 if (i == 0 && argv[i][0] != '-')
5765 {
5766 dirOrFilePath = argv[i];
5767 }
5768 else if (argv[i][0] == '-')
5769 {
5770 if (strcmp (&argv[i][1], "apply") == 0)
5771 apply = true;
5772 else if (strcmp (&argv[i][1], "nobackup") == 0)
5773 nobackup = true;
5774 else if (strcmp (&argv[i][1], "skipinvalid") == 0)
5775 skipinvalid = true;
5776 else
5777 {
5778 return errorSyntax(USAGE_SETPROPERTY, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());
5779 }
5780 }
5781 else
5782 {
5783 return errorSyntax(USAGE_SETPROPERTY, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());
5784 }
5785 }
5786
5787 HUSPD mode = HUSPD_DryRun;
5788 if (apply)
5789 mode = nobackup ? HUSPD_ApplyNoBackup : HUSPD_Apply;
5790
5791 int vrc = CFGLDRInitialize();
5792 if (VBOX_FAILURE (vrc))
5793 {
5794 RTPrintf ("Could not initialize XML subsystem (%Vrc)\n", vrc);
5795 return 1;
5796 }
5797
5798 if (dirOrFilePath)
5799 {
5800 if (RTDirExists (dirOrFilePath))
5801 {
5802 char fullPath [RTPATH_MAX];
5803 vrc = RTPathReal (dirOrFilePath, fullPath, RTPATH_MAX);
5804 if (VBOX_FAILURE (vrc))
5805 {
5806 RTPrintf ("Invalid directory path '%s' (%Vrc)\n", dirOrFilePath, vrc);
5807 return 1;
5808 }
5809
5810 RTPrintf ("Updating settings files in the following directory:\n"
5811 "\n %s\n\n", fullPath);
5812
5813 vrc = handleUpdateSettings_processDir (dirOrFilePath, mode, skipinvalid);
5814 }
5815 else
5816 {
5817 vrc = handleUpdateSettings_processFile (dirOrFilePath, mode);
5818 }
5819 }
5820 else
5821 {
5822 // check if an alternative VBox Home directory is set
5823 Utf8Str homeDir = getenv ("VBOX_USER_HOME");
5824 if (!homeDir)
5825 {
5826 // compose the config directory (full path)
5827 char home [RTPATH_MAX];
5828 RTPathUserHome (home, RTPATH_MAX);
5829 homeDir = Utf8StrFmt ("%s%c%s", home, RTPATH_DELIMITER, ".VirtualBox");
5830 }
5831
5832 RTPrintf ("Updating settings files in the following VirtualBox Home Directory:\n"
5833 "\n %s\n\n", homeDir.raw());
5834
5835 vrc = handleUpdateSettings_processDir (homeDir, mode, skipinvalid);
5836 }
5837
5838 if (mode == HUSPD_DryRun)
5839 {
5840 RTPrintf ("NOTE: No actual changes to the setting files were made.\n"
5841 " Repeat the command with the -apply option supplied.\n");
5842 }
5843
5844 CFGLDRShutdown();
5845
5846 return VBOX_SUCCESS (vrc) ? 0 : 1;
5847}
5848
5849// main
5850///////////////////////////////////////////////////////////////////////////////
5851
5852int main(int argc, char *argv[])
5853{
5854 /*
5855 * Before we do anything, init the runtime without loading
5856 * the support driver.
5857 */
5858 RTR3Init(false);
5859
5860 RTPrintf("VirtualBox Command Line Management Interface Version %d.%d.%d\n"
5861 "(C) 2005-2007 InnoTek Systemberatung GmbH\n"
5862 "All rights reserved.\n"
5863 "\n",
5864 VBOX_VERSION_MAJOR, VBOX_VERSION_MINOR, VBOX_VERSION_BUILD);
5865
5866 /* shortcut for no parameters or help */
5867 if ( (argc < 2)
5868 || (strcmp(argv[1], "help") == 0)
5869 || (strcmp(argv[1], "-?") == 0)
5870 || (strcmp(argv[1], "-h") == 0)
5871 || (strcmp(argv[1], "-help") == 0)
5872 || (strcmp(argv[1], "--help") == 0))
5873 {
5874 printUsage(USAGE_ALL);
5875 return 0;
5876 }
5877
5878 /* Special option to dump really all commands, even the ones not
5879 * understood on this platform. */
5880 if (argc == 2 && strcmp(argv[1], "-dumpopts") == 0)
5881 {
5882 printUsage(USAGE_DUMPOPTS);
5883 return 0;
5884 }
5885
5886 HRESULT rc;
5887
5888 CHECK_RC_RET (com::Initialize());
5889
5890 /*
5891 * The input is in the host OS'es codepage (NT guarantees ACP).
5892 * For VBox we use UTF-8 and convert to UCS-2 when calling (XP)COM APIs.
5893 * For simplicity, just convert the argv[] array here.
5894 */
5895 for (int i = 2; i < argc; i++)
5896 {
5897 char *converted;
5898 RTStrCurrentCPToUtf8(&converted, argv[i]);
5899 argv[i] = converted;
5900 }
5901
5902 do
5903 {
5904 // scopes all the stuff till shutdown
5905 ////////////////////////////////////////////////////////////////////////////
5906
5907 /* update settings command (no VirtualBox instantiation!)*/
5908 if (argc >= 2 && (strcmp(argv[1], "updatesettings") == 0))
5909 {
5910 rc = handleUpdateSettings(argc - 2 , argv + 2);
5911 break;
5912 }
5913
5914 ComPtr <IVirtualBox> virtualBox;
5915 ComPtr <ISession> session;
5916
5917 rc = virtualBox.createLocalObject (CLSID_VirtualBox,
5918 "VirtualBoxServer");
5919 if (FAILED(rc))
5920 {
5921 RTPrintf ("[!] Failed to create the VirtualBox object!\n");
5922 PRINT_RC_MESSAGE (rc);
5923
5924 com::ErrorInfo info;
5925 if (!info.isFullAvailable() && !info.isBasicAvailable())
5926 RTPrintf ("[!] Most likely, the VirtualBox COM server is not running "
5927 "or failed to start.\n");
5928 else
5929 PRINT_ERROR_INFO (info);
5930 break;
5931 }
5932
5933 CHECK_RC_BREAK (session.createInprocObject (CLSID_Session));
5934
5935 /* create the event queue
5936 * (here it is necessary only to process remaining XPCOM/IPC events
5937 * after the session is closed) */
5938 EventQueue eventQ;
5939
5940 /*
5941 * All registered command handlers
5942 */
5943 struct
5944 {
5945 char *command;
5946 PFNHANDLER handler;
5947 } commandHandlers[] =
5948 {
5949 { "internalcommands", handleInternalCommands },
5950 { "list", handleList },
5951 { "showvminfo", handleShowVMInfo },
5952 { "registervm", handleRegisterVM },
5953 { "unregistervm", handleUnregisterVM },
5954 { "createvdi", handleCreateVDI },
5955 { "modifyvdi", handleModifyVDI },
5956 { "addiscsidisk", handleAddiSCSIDisk },
5957 { "createvm", handleCreateVM },
5958 { "modifyvm", handleModifyVM },
5959 { "clonevdi", handleCloneVDI },
5960 { "startvm", handleStartVM },
5961 { "controlvm", handleControlVM },
5962 { "discardstate", handleDiscardState },
5963 { "snapshot", handleSnapshot },
5964 { "registerimage", handleRegisterImage },
5965 { "unregisterimage", handleUnregisterImage },
5966 { "showvdiinfo", handleShowVDIInfo },
5967#ifdef __WIN__
5968 { "createhostif", handleCreateHostIF },
5969 { "removehostif", handleRemoveHostIF },
5970#endif
5971 { "getextradata", handleGetExtraData },
5972 { "setextradata", handleSetExtraData },
5973 { "setproperty", handleSetProperty },
5974 { "usbfilter", handleUSBFilter },
5975 { "sharedfolder", handleSharedFolder },
5976 { NULL, NULL }
5977 };
5978
5979 int commandIndex;
5980 for (commandIndex = 0; commandHandlers[commandIndex].command != NULL; commandIndex++)
5981 {
5982 if (strcmp(commandHandlers[commandIndex].command, argv[1]) == 0)
5983 {
5984 rc = commandHandlers[commandIndex].handler(argc - 2, &argv[2], virtualBox, session);
5985 break;
5986 }
5987 }
5988 if (!commandHandlers[commandIndex].command)
5989 {
5990 rc = errorSyntax(USAGE_ALL, "Invalid command '%s'", Utf8Str(argv[1]).raw());
5991 }
5992
5993
5994 // end "all-stuff" scope
5995 ////////////////////////////////////////////////////////////////////////////
5996 }
5997 while (0);
5998
5999 com::Shutdown();
6000
6001 /*
6002 * Free converted argument vector
6003 */
6004 for (int i = 2; i < argc; i++)
6005 {
6006 RTStrFree(argv[i]);
6007 }
6008
6009 return rc;
6010}
Note: See TracBrowser for help on using the repository browser.

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