VirtualBox

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

Last change on this file since 86663 was 85780, checked in by vboxsync, 4 years ago

VBoxManage/checkupdate: machine readable output. bugref:7983

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 115.7 KB
Line 
1/* $Id: VBoxManageInfo.cpp 85780 2020-08-14 21:29:46Z vboxsync $ */
2/** @file
3 * VBoxManage - The 'showvminfo' command and helper routines.
4 */
5
6/*
7 * Copyright (C) 2006-2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifndef VBOX_ONLY_DOCS
19
20
21/*********************************************************************************************************************************
22* Header Files *
23*********************************************************************************************************************************/
24#include <VBox/com/com.h>
25#include <VBox/com/string.h>
26#include <VBox/com/Guid.h>
27#include <VBox/com/array.h>
28#include <VBox/com/ErrorInfo.h>
29#include <VBox/com/errorprint.h>
30
31#include <VBox/com/VirtualBox.h>
32
33#ifdef VBOX_WITH_PCI_PASSTHROUGH
34#include <VBox/pci.h>
35#endif
36
37#include <VBox/log.h>
38#include <VBox/version.h>
39#include <iprt/stream.h>
40#include <iprt/time.h>
41#include <iprt/string.h>
42#include <iprt/getopt.h>
43#include <iprt/ctype.h>
44
45#include "VBoxManage.h"
46using namespace com;
47
48
49// funcs
50///////////////////////////////////////////////////////////////////////////////
51
52/**
53 * Helper for formatting an indexed name or some such thing.
54 */
55static const char *FmtNm(char psz[80], const char *pszFormat, ...)
56{
57 va_list va;
58 va_start(va, pszFormat);
59 RTStrPrintfV(psz, 80, pszFormat, va);
60 va_end(va);
61 return psz;
62}
63
64HRESULT showSnapshots(ComPtr<ISnapshot> &rootSnapshot,
65 ComPtr<ISnapshot> &currentSnapshot,
66 VMINFO_DETAILS details,
67 const Utf8Str &prefix /* = ""*/,
68 int level /*= 0*/)
69{
70 /* start with the root */
71 Bstr name;
72 Bstr uuid;
73 Bstr description;
74 CHECK_ERROR2I_RET(rootSnapshot, COMGETTER(Name)(name.asOutParam()), hrcCheck);
75 CHECK_ERROR2I_RET(rootSnapshot, COMGETTER(Id)(uuid.asOutParam()), hrcCheck);
76 CHECK_ERROR2I_RET(rootSnapshot, COMGETTER(Description)(description.asOutParam()), hrcCheck);
77 bool fCurrent = (rootSnapshot == currentSnapshot);
78 if (details == VMINFO_MACHINEREADABLE)
79 {
80 /* print with hierarchical numbering */
81 RTPrintf("SnapshotName%s=\"%ls\"\n", prefix.c_str(), name.raw());
82 RTPrintf("SnapshotUUID%s=\"%s\"\n", prefix.c_str(), Utf8Str(uuid).c_str());
83 if (!description.isEmpty())
84 RTPrintf("SnapshotDescription%s=\"%ls\"\n", prefix.c_str(), description.raw());
85 if (fCurrent)
86 {
87 RTPrintf("CurrentSnapshotName=\"%ls\"\n", name.raw());
88 RTPrintf("CurrentSnapshotUUID=\"%s\"\n", Utf8Str(uuid).c_str());
89 RTPrintf("CurrentSnapshotNode=\"SnapshotName%s\"\n", prefix.c_str());
90 }
91 }
92 else
93 {
94 /* print with indentation */
95 RTPrintf(" %sName: %ls (UUID: %s)%s\n",
96 prefix.c_str(),
97 name.raw(),
98 Utf8Str(uuid).c_str(),
99 (fCurrent) ? " *" : "");
100 if (!description.isEmpty())
101 RTPrintf(" %sDescription:\n%ls\n", prefix.c_str(), description.raw());
102 }
103
104 /* get the children */
105 HRESULT hrc = S_OK;
106 SafeIfaceArray <ISnapshot> coll;
107 CHECK_ERROR2I_RET(rootSnapshot,COMGETTER(Children)(ComSafeArrayAsOutParam(coll)), hrcCheck);
108 if (!coll.isNull())
109 {
110 for (size_t index = 0; index < coll.size(); ++index)
111 {
112 ComPtr<ISnapshot> snapshot = coll[index];
113 if (snapshot)
114 {
115 Utf8Str newPrefix;
116 if (details == VMINFO_MACHINEREADABLE)
117 newPrefix.printf("%s-%d", prefix.c_str(), index + 1);
118 else
119 newPrefix.printf("%s ", prefix.c_str());
120
121 /* recursive call */
122 HRESULT hrc2 = showSnapshots(snapshot, currentSnapshot, details, newPrefix, level + 1);
123 if (FAILED(hrc2))
124 hrc = hrc2;
125 }
126 }
127 }
128 return hrc;
129}
130
131static void makeTimeStr(char *s, int cb, int64_t millies)
132{
133 RTTIME t;
134 RTTIMESPEC ts;
135
136 RTTimeSpecSetMilli(&ts, millies);
137
138 RTTimeExplode(&t, &ts);
139
140 RTStrPrintf(s, cb, "%04d/%02d/%02d %02d:%02d:%02d UTC",
141 t.i32Year, t.u8Month, t.u8MonthDay,
142 t.u8Hour, t.u8Minute, t.u8Second);
143}
144
145const char *machineStateToName(MachineState_T machineState, bool fShort)
146{
147 switch (machineState)
148 {
149 case MachineState_PoweredOff:
150 return fShort ? "poweroff" : "powered off";
151 case MachineState_Saved:
152 return "saved";
153 case MachineState_Teleported:
154 return "teleported";
155 case MachineState_Aborted:
156 return "aborted";
157 case MachineState_Running:
158 return "running";
159 case MachineState_Paused:
160 return "paused";
161 case MachineState_Stuck:
162 return fShort ? "gurumeditation" : "guru meditation";
163 case MachineState_Teleporting:
164 return "teleporting";
165 case MachineState_LiveSnapshotting:
166 return fShort ? "livesnapshotting" : "live snapshotting";
167 case MachineState_Starting:
168 return "starting";
169 case MachineState_Stopping:
170 return "stopping";
171 case MachineState_Saving:
172 return "saving";
173 case MachineState_Restoring:
174 return "restoring";
175 case MachineState_TeleportingPausedVM:
176 return fShort ? "teleportingpausedvm" : "teleporting paused vm";
177 case MachineState_TeleportingIn:
178 return fShort ? "teleportingin" : "teleporting (incoming)";
179 case MachineState_DeletingSnapshotOnline:
180 return fShort ? "deletingsnapshotlive" : "deleting snapshot live";
181 case MachineState_DeletingSnapshotPaused:
182 return fShort ? "deletingsnapshotlivepaused" : "deleting snapshot live paused";
183 case MachineState_OnlineSnapshotting:
184 return fShort ? "onlinesnapshotting" : "online snapshotting";
185 case MachineState_RestoringSnapshot:
186 return fShort ? "restoringsnapshot" : "restoring snapshot";
187 case MachineState_DeletingSnapshot:
188 return fShort ? "deletingsnapshot" : "deleting snapshot";
189 case MachineState_SettingUp:
190 return fShort ? "settingup" : "setting up";
191 case MachineState_Snapshotting:
192 return fShort ? "snapshotting" : "offline snapshotting";
193 default:
194 break;
195 }
196 return "unknown";
197}
198
199const char *facilityStateToName(AdditionsFacilityStatus_T faStatus, bool fShort)
200{
201 switch (faStatus)
202 {
203 case AdditionsFacilityStatus_Inactive:
204 return fShort ? "inactive" : "not active";
205 case AdditionsFacilityStatus_Paused:
206 return "paused";
207 case AdditionsFacilityStatus_PreInit:
208 return fShort ? "preinit" : "pre-initializing";
209 case AdditionsFacilityStatus_Init:
210 return fShort ? "init" : "initializing";
211 case AdditionsFacilityStatus_Active:
212 return fShort ? "active" : "active/running";
213 case AdditionsFacilityStatus_Terminating:
214 return "terminating";
215 case AdditionsFacilityStatus_Terminated:
216 return "terminated";
217 case AdditionsFacilityStatus_Failed:
218 return "failed";
219 case AdditionsFacilityStatus_Unknown:
220 default:
221 break;
222 }
223 return "unknown";
224}
225
226/**
227 * This takes care of escaping double quotes and slashes that the string might
228 * contain.
229 *
230 * @param pszName The variable name.
231 * @param pszValue The value.
232 */
233void outputMachineReadableString(const char *pszName, const char *pszValue)
234{
235 Assert(strpbrk(pszName, "\"\\") == NULL);
236
237 if ( !pszValue
238 || !*pszValue
239 || ( strchr(pszValue, '"') == NULL
240 && strchr(pszValue, '\\') == NULL) )
241 RTPrintf("%s=\"%s\"\n", pszName, pszValue);
242 else
243 {
244 /* The value needs escaping. */
245 RTPrintf("%s=\"", pszName);
246 const char *psz = pszValue;
247 for (;;)
248 {
249 const char *pszNext = strpbrk(psz, "\"\\");
250 if (!pszNext)
251 {
252 RTPrintf("%s", psz);
253 break;
254 }
255 RTPrintf("%.*s\\%c", pszNext - psz, psz, *pszNext);
256 psz = pszNext + 1;
257 }
258 RTPrintf("\"\n");
259 }
260}
261
262
263/**
264 * This takes care of escaping double quotes and slashes that the string might
265 * contain.
266 *
267 * @param pszName The variable name.
268 * @param pbstrValue The value.
269 */
270void outputMachineReadableString(const char *pszName, Bstr const *pbstrValue)
271{
272 com::Utf8Str strValue(*pbstrValue);
273 outputMachineReadableString(pszName, strValue.c_str());
274}
275
276
277/**
278 * Machine readable outputting of a boolean value.
279 */
280void outputMachineReadableBool(const char *pszName, BOOL const *pfValue)
281{
282 RTPrintf("%s=\"%s\"\n", pszName, *pfValue ? "on" : "off");
283}
284
285
286/**
287 * Machine readable outputting of a boolean value.
288 */
289void outputMachineReadableBool(const char *pszName, bool const *pfValue)
290{
291 RTPrintf("%s=\"%s\"\n", pszName, *pfValue ? "on" : "off");
292}
293
294
295/**
296 * Machine readable outputting of a ULONG value.
297 */
298void outputMachineReadableULong(const char *pszName, ULONG *puValue)
299{
300 RTPrintf("%s=\"%u\"\n", pszName, *puValue);
301}
302
303
304/**
305 * Machine readable outputting of a LONG64 value.
306 */
307void outputMachineReadableLong64(const char *pszName, LONG64 *puValue)
308{
309 RTPrintf("%s=\"%llu\"\n", pszName, *puValue);
310}
311
312
313/**
314 * Converts bandwidth group type to a string.
315 * @returns String representation.
316 * @param enmType Bandwidth control group type.
317 */
318static const char * bwGroupTypeToString(BandwidthGroupType_T enmType)
319{
320 switch (enmType)
321 {
322 case BandwidthGroupType_Null: return "Null";
323 case BandwidthGroupType_Disk: return "Disk";
324 case BandwidthGroupType_Network: return "Network";
325#ifdef VBOX_WITH_XPCOM_CPP_ENUM_HACK
326 case BandwidthGroupType_32BitHack: break; /* Shut up compiler warnings. */
327#endif
328 }
329 return "unknown";
330}
331
332HRESULT showBandwidthGroups(ComPtr<IBandwidthControl> &bwCtrl,
333 VMINFO_DETAILS details)
334{
335 int rc = S_OK;
336 SafeIfaceArray<IBandwidthGroup> bwGroups;
337
338 CHECK_ERROR_RET(bwCtrl, GetAllBandwidthGroups(ComSafeArrayAsOutParam(bwGroups)), rc);
339
340 if (bwGroups.size() && details != VMINFO_MACHINEREADABLE)
341 RTPrintf("\n\n");
342 for (size_t i = 0; i < bwGroups.size(); i++)
343 {
344 Bstr strName;
345 LONG64 cMaxBytesPerSec;
346 BandwidthGroupType_T enmType;
347
348 CHECK_ERROR_RET(bwGroups[i], COMGETTER(Name)(strName.asOutParam()), rc);
349 CHECK_ERROR_RET(bwGroups[i], COMGETTER(Type)(&enmType), rc);
350 CHECK_ERROR_RET(bwGroups[i], COMGETTER(MaxBytesPerSec)(&cMaxBytesPerSec), rc);
351
352 const char *pszType = bwGroupTypeToString(enmType);
353 if (details == VMINFO_MACHINEREADABLE)
354 RTPrintf("BandwidthGroup%zu=%ls,%s,%lld\n", i, strName.raw(), pszType, cMaxBytesPerSec);
355 else
356 {
357 const char *pszUnits = "";
358 LONG64 cBytes = cMaxBytesPerSec;
359 if (cBytes == 0)
360 {
361 RTPrintf("Name: '%ls', Type: %s, Limit: none (disabled)\n", strName.raw(), pszType);
362 continue;
363 }
364 else if (!(cBytes % _1G))
365 {
366 pszUnits = "G";
367 cBytes /= _1G;
368 }
369 else if (!(cBytes % _1M))
370 {
371 pszUnits = "M";
372 cBytes /= _1M;
373 }
374 else if (!(cBytes % _1K))
375 {
376 pszUnits = "K";
377 cBytes /= _1K;
378 }
379 const char *pszNetUnits = NULL;
380 if (enmType == BandwidthGroupType_Network)
381 {
382 /*
383 * We want to report network rate limit in bits/s, not bytes.
384 * Only if it cannot be express it in kilobits we will fall
385 * back to reporting it in bytes.
386 */
387 LONG64 cBits = cMaxBytesPerSec;
388 if (!(cBits % 125))
389 {
390 cBits /= 125;
391 pszNetUnits = "k";
392 if (!(cBits % 1000000))
393 {
394 cBits /= 1000000;
395 pszNetUnits = "g";
396 }
397 else if (!(cBits % 1000))
398 {
399 cBits /= 1000;
400 pszNetUnits = "m";
401 }
402 RTPrintf("Name: '%ls', Type: %s, Limit: %lld %sbits/sec (%lld %sbytes/sec)\n", strName.raw(), pszType, cBits, pszNetUnits, cBytes, pszUnits);
403 }
404 }
405 if (!pszNetUnits)
406 RTPrintf("Name: '%ls', Type: %s, Limit: %lld %sbytes/sec\n", strName.raw(), pszType, cBytes, pszUnits);
407 }
408 }
409 if (details != VMINFO_MACHINEREADABLE)
410 RTPrintf(bwGroups.size() != 0 ? "\n" : "<none>\n\n");
411
412 return rc;
413}
414
415/** Shows a shared folder. */
416static HRESULT showSharedFolder(ComPtr<ISharedFolder> &sf, VMINFO_DETAILS details, const char *pszDesc,
417 const char *pszMrInfix, size_t idxMr, bool fFirst)
418{
419 Bstr name, hostPath, bstrAutoMountPoint;
420 BOOL writable = FALSE, fAutoMount = FALSE;
421 CHECK_ERROR2I_RET(sf, COMGETTER(Name)(name.asOutParam()), hrcCheck);
422 CHECK_ERROR2I_RET(sf, COMGETTER(HostPath)(hostPath.asOutParam()), hrcCheck);
423 CHECK_ERROR2I_RET(sf, COMGETTER(Writable)(&writable), hrcCheck);
424 CHECK_ERROR2I_RET(sf, COMGETTER(AutoMount)(&fAutoMount), hrcCheck);
425 CHECK_ERROR2I_RET(sf, COMGETTER(AutoMountPoint)(bstrAutoMountPoint.asOutParam()), hrcCheck);
426
427 if (fFirst && details != VMINFO_MACHINEREADABLE)
428 RTPrintf("\n\n");
429 if (details == VMINFO_MACHINEREADABLE)
430 {
431 char szNm[80];
432 outputMachineReadableString(FmtNm(szNm, "SharedFolderName%s%zu", pszMrInfix, idxMr), &name);
433 outputMachineReadableString(FmtNm(szNm, "SharedFolderPath%s%zu", pszMrInfix, idxMr), &hostPath);
434 }
435 else
436 {
437 RTPrintf("Name: '%ls', Host path: '%ls' (%s), %s%s",
438 name.raw(), hostPath.raw(), pszDesc, writable ? "writable" : "readonly", fAutoMount ? ", auto-mount" : "");
439 if (bstrAutoMountPoint.isNotEmpty())
440 RTPrintf(", mount-point: '%ls'\n", bstrAutoMountPoint.raw());
441 else
442 RTPrintf("\n");
443 }
444 return S_OK;
445}
446
447
448static const char *paravirtProviderToString(ParavirtProvider_T provider, VMINFO_DETAILS details)
449{
450 switch (provider)
451 {
452 case ParavirtProvider_None:
453 if (details == VMINFO_MACHINEREADABLE)
454 return "none";
455 return "None";
456
457 case ParavirtProvider_Default:
458 if (details == VMINFO_MACHINEREADABLE)
459 return "default";
460 return "Default";
461
462 case ParavirtProvider_Legacy:
463 if (details == VMINFO_MACHINEREADABLE)
464 return "legacy";
465 return "Legacy";
466
467 case ParavirtProvider_Minimal:
468 if (details == VMINFO_MACHINEREADABLE)
469 return "minimal";
470 return "Minimal";
471
472 case ParavirtProvider_HyperV:
473 if (details == VMINFO_MACHINEREADABLE)
474 return "hyperv";
475 return "HyperV";
476
477 case ParavirtProvider_KVM:
478 if (details == VMINFO_MACHINEREADABLE)
479 return "kvm";
480 return "KVM";
481
482 default:
483 if (details == VMINFO_MACHINEREADABLE)
484 return "unknown";
485 return "Unknown";
486 }
487}
488
489
490/* Disable global optimizations for MSC 8.0/64 to make it compile in reasonable
491 time. MSC 7.1/32 doesn't have quite as much trouble with it, but still
492 sufficient to qualify for this hack as well since this code isn't performance
493 critical and probably won't gain much from the extra optimizing in real life. */
494#if defined(_MSC_VER)
495# pragma optimize("g", off)
496# pragma warning(push)
497# if _MSC_VER < RT_MSC_VER_VC120
498# pragma warning(disable: 4748)
499# endif
500#endif
501
502HRESULT showVMInfo(ComPtr<IVirtualBox> pVirtualBox,
503 ComPtr<IMachine> machine,
504 ComPtr<ISession> pSession,
505 VMINFO_DETAILS details /*= VMINFO_NONE*/)
506{
507 HRESULT rc;
508 ComPtr<IConsole> pConsole;
509 if (pSession)
510 pSession->COMGETTER(Console)(pConsole.asOutParam());
511
512 char szNm[80];
513 char szValue[256];
514
515#define SHOW_UTF8_STRING(a_pszMachine, a_pszHuman, a_szValue) \
516 do \
517 { \
518 Assert(a_pszHuman[strlen(a_pszHuman) - 1] == ':'); \
519 if (details == VMINFO_MACHINEREADABLE) \
520 outputMachineReadableString(a_pszMachine, a_szValue); \
521 else \
522 RTPrintf("%-28s %s\n", a_pszHuman, a_szValue); \
523 } while (0)
524
525#define SHOW_BSTR_STRING(a_pszMachine, a_pszHuman, a_bstrValue) \
526 do \
527 { \
528 Assert(a_pszHuman[strlen(a_pszHuman) - 1] == ':'); \
529 if (details == VMINFO_MACHINEREADABLE) \
530 outputMachineReadableString(a_pszMachine, &a_bstrValue); \
531 else \
532 RTPrintf("%-28s %ls\n", a_pszHuman, a_bstrValue.raw()); \
533 } while (0)
534
535#define SHOW_BOOL_VALUE_EX(a_pszMachine, a_pszHuman, a_fValue, a_szTrue, a_szFalse) \
536 do \
537 { \
538 if (details == VMINFO_MACHINEREADABLE) \
539 outputMachineReadableString(a_pszMachine, a_fValue ? "on" : "off"); \
540 else \
541 RTPrintf("%-28s %s\n", a_pszHuman, a_fValue ? a_szTrue: a_szFalse); \
542 } while (0)
543
544#define SHOW_BOOL_VALUE(a_pszMachine, a_pszHuman, a_fValue) \
545 SHOW_BOOL_VALUE_EX(a_pszMachine, a_pszHuman, a_fValue, "enabled", "disabled")
546
547#define SHOW_ULONG_VALUE(a_pszMachine, a_pszHuman, a_uValue, a_pszUnit) \
548 do \
549 { \
550 if (details == VMINFO_MACHINEREADABLE) \
551 RTPrintf("%s=%u\n", a_pszMachine, a_uValue); \
552 else \
553 RTPrintf("%-28s %u%s\n", a_pszHuman, a_uValue, a_pszUnit); \
554 } while (0)
555
556#define SHOW_LONG64_VALUE(a_pszMachine, a_pszHuman, a_llValue, a_pszUnit) \
557 do \
558 { \
559 if (details == VMINFO_MACHINEREADABLE) \
560 RTPrintf("%s=%lld\n", a_pszMachine, a_llValue); \
561 else \
562 RTPrintf("%-28s %lld%s\n", a_pszHuman, a_llValue, a_pszUnit); \
563 } while (0)
564
565#define SHOW_BOOLEAN_PROP(a_pObj, a_Prop, a_pszMachine, a_pszHuman) \
566 SHOW_BOOLEAN_PROP_EX(a_pObj, a_Prop, a_pszMachine, a_pszHuman, "enabled", "disabled")
567
568#define SHOW_BOOLEAN_PROP_EX(a_pObj, a_Prop, a_pszMachine, a_pszHuman, a_szTrue, a_szFalse) \
569 do \
570 { \
571 BOOL f; \
572 CHECK_ERROR2I_RET(a_pObj, COMGETTER(a_Prop)(&f), hrcCheck); \
573 if (details == VMINFO_MACHINEREADABLE) \
574 outputMachineReadableString(a_pszMachine, f ? "on" : "off"); \
575 else \
576 RTPrintf("%-28s %s\n", a_pszHuman, f ? a_szTrue : a_szFalse); \
577 } while (0)
578
579#define SHOW_BOOLEAN_METHOD(a_pObj, a_Invocation, a_pszMachine, a_pszHuman) \
580 do \
581 { \
582 BOOL f; \
583 CHECK_ERROR2I_RET(a_pObj, a_Invocation, hrcCheck); \
584 if (details == VMINFO_MACHINEREADABLE) \
585 outputMachineReadableString(a_pszMachine, f ? "on" : "off"); \
586 else \
587 RTPrintf("%-28s %s\n", a_pszHuman, f ? "enabled" : "disabled"); \
588 } while (0)
589
590#define SHOW_STRING_PROP(a_pObj, a_Prop, a_pszMachine, a_pszHuman) \
591 do \
592 { \
593 Bstr bstr; \
594 CHECK_ERROR2I_RET(a_pObj, COMGETTER(a_Prop)(bstr.asOutParam()), hrcCheck); \
595 if (details == VMINFO_MACHINEREADABLE) \
596 outputMachineReadableString(a_pszMachine, &bstr); \
597 else \
598 RTPrintf("%-28s %ls\n", a_pszHuman, bstr.raw()); \
599 } while (0)
600
601#define SHOW_STRING_PROP_NOT_EMPTY(a_pObj, a_Prop, a_pszMachine, a_pszHuman) \
602 do \
603 { \
604 Bstr bstr; \
605 CHECK_ERROR2I_RET(a_pObj, COMGETTER(a_Prop)(bstr.asOutParam()), hrcCheck); \
606 if (bstr.isNotEmpty()) \
607 { \
608 if (details == VMINFO_MACHINEREADABLE) \
609 outputMachineReadableString(a_pszMachine, &bstr); \
610 else \
611 RTPrintf("%-28s %ls\n", a_pszHuman, bstr.raw()); \
612 } \
613 } while (0)
614
615 /** @def SHOW_STRING_PROP_MAJ
616 * For not breaking the output in a dot release we don't show default values. */
617#define SHOW_STRING_PROP_MAJ(a_pObj, a_Prop, a_pszMachine, a_pszHuman, a_pszUnless, a_uMajorVer) \
618 do \
619 { \
620 Bstr bstr; \
621 CHECK_ERROR2I_RET(a_pObj, COMGETTER(a_Prop)(bstr.asOutParam()), hrcCheck); \
622 if ((a_uMajorVer) <= VBOX_VERSION_MAJOR || !bstr.equals(a_pszUnless)) \
623 { \
624 if (details == VMINFO_MACHINEREADABLE)\
625 outputMachineReadableString(a_pszMachine, &bstr); \
626 else \
627 RTPrintf("%-28s %ls\n", a_pszHuman, bstr.raw()); \
628 } \
629 } while (0)
630
631#define SHOW_STRINGARRAY_PROP(a_pObj, a_Prop, a_pszMachine, a_pszHuman) \
632 do \
633 { \
634 SafeArray<BSTR> array; \
635 CHECK_ERROR2I_RET(a_pObj, COMGETTER(a_Prop)(ComSafeArrayAsOutParam(array)), hrcCheck); \
636 Utf8Str str; \
637 for (size_t i = 0; i < array.size(); i++) \
638 { \
639 if (i != 0) \
640 str.append(","); \
641 str.append(Utf8Str(array[i]).c_str()); \
642 } \
643 Bstr bstr(str); \
644 if (details == VMINFO_MACHINEREADABLE) \
645 outputMachineReadableString(a_pszMachine, &bstr); \
646 else \
647 RTPrintf("%-28s %ls\n", a_pszHuman, bstr.raw()); \
648 } while (0)
649
650#define SHOW_UUID_PROP(a_pObj, a_Prop, a_pszMachine, a_pszHuman) \
651 SHOW_STRING_PROP(a_pObj, a_Prop, a_pszMachine, a_pszHuman)
652
653#define SHOW_USHORT_PROP_EX2(a_pObj, a_Prop, a_pszMachine, a_pszHuman, a_pszUnit, a_szFmtMachine, a_szFmtHuman) \
654 do \
655 { \
656 USHORT u16 = 0; \
657 CHECK_ERROR2I_RET(a_pObj, COMGETTER(a_Prop)(&u16), hrcCheck); \
658 if (details == VMINFO_MACHINEREADABLE) \
659 RTPrintf("%s=" a_szFmtMachine "\n", a_pszMachine, u16); \
660 else \
661 RTPrintf("%-28s " a_szFmtHuman "%s\n", a_pszHuman, u16, u16, a_pszUnit); \
662 } while (0)
663
664#define SHOW_ULONG_PROP(a_pObj, a_Prop, a_pszMachine, a_pszHuman, a_pszUnit) \
665 do \
666 { \
667 ULONG u32 = 0; \
668 CHECK_ERROR2I_RET(a_pObj, COMGETTER(a_Prop)(&u32), hrcCheck); \
669 if (details == VMINFO_MACHINEREADABLE) \
670 RTPrintf("%s=%u\n", a_pszMachine, u32); \
671 else \
672 RTPrintf("%-28s %u%s\n", a_pszHuman, u32, a_pszUnit); \
673 } while (0)
674
675#define SHOW_LONG64_PROP(a_pObj, a_Prop, a_pszMachine, a_pszHuman, a_pszUnit) \
676 do \
677 { \
678 LONG64 i64 = 0; \
679 CHECK_ERROR2I_RET(a_pObj, COMGETTER(a_Prop)(&i64), hrcCheck); \
680 if (details == VMINFO_MACHINEREADABLE) \
681 RTPrintf("%s=%lld\n", a_pszMachine, i64); \
682 else \
683 RTPrintf("%-28s %'lld%s\n", a_pszHuman, i64, a_pszUnit); \
684 } while (0)
685
686 /*
687 * The rules for output in -argdump format:
688 * 1) the key part (the [0-9a-zA-Z_\-]+ string before the '=' delimiter)
689 * is all lowercase for "VBoxManage modifyvm" parameters. Any
690 * other values printed are in CamelCase.
691 * 2) strings (anything non-decimal) are printed surrounded by
692 * double quotes '"'. If the strings themselves contain double
693 * quotes, these characters are escaped by '\'. Any '\' character
694 * in the original string is also escaped by '\'.
695 * 3) numbers (containing just [0-9\-]) are written out unchanged.
696 */
697
698 BOOL fAccessible;
699 CHECK_ERROR2I_RET(machine, COMGETTER(Accessible)(&fAccessible), hrcCheck);
700 if (!fAccessible)
701 {
702 Bstr uuid;
703 machine->COMGETTER(Id)(uuid.asOutParam());
704 if (details == VMINFO_COMPACT)
705 RTPrintf("\"<inaccessible>\" {%s}\n", Utf8Str(uuid).c_str());
706 else
707 {
708 if (details == VMINFO_MACHINEREADABLE)
709 RTPrintf("name=\"<inaccessible>\"\n");
710 else
711 RTPrintf("Name: <inaccessible!>\n");
712 if (details == VMINFO_MACHINEREADABLE)
713 RTPrintf("UUID=\"%s\"\n", Utf8Str(uuid).c_str());
714 else
715 RTPrintf("UUID: %s\n", Utf8Str(uuid).c_str());
716 if (details != VMINFO_MACHINEREADABLE)
717 {
718 Bstr settingsFilePath;
719 rc = machine->COMGETTER(SettingsFilePath)(settingsFilePath.asOutParam());
720 RTPrintf("Config file: %ls\n", settingsFilePath.raw());
721 ComPtr<IVirtualBoxErrorInfo> accessError;
722 rc = machine->COMGETTER(AccessError)(accessError.asOutParam());
723 RTPrintf("Access error details:\n");
724 ErrorInfo ei(accessError);
725 GluePrintErrorInfo(ei);
726 RTPrintf("\n");
727 }
728 }
729 return S_OK;
730 }
731
732 if (details == VMINFO_COMPACT)
733 {
734 Bstr machineName;
735 machine->COMGETTER(Name)(machineName.asOutParam());
736 Bstr uuid;
737 machine->COMGETTER(Id)(uuid.asOutParam());
738
739 RTPrintf("\"%ls\" {%s}\n", machineName.raw(), Utf8Str(uuid).c_str());
740 return S_OK;
741 }
742
743 SHOW_STRING_PROP( machine, Name, "name", "Name:");
744 SHOW_STRINGARRAY_PROP( machine, Groups, "groups", "Groups:");
745 Bstr osTypeId;
746 CHECK_ERROR2I_RET(machine, COMGETTER(OSTypeId)(osTypeId.asOutParam()), hrcCheck);
747 ComPtr<IGuestOSType> osType;
748 pVirtualBox->GetGuestOSType(osTypeId.raw(), osType.asOutParam());
749 if (!osType.isNull())
750 SHOW_STRING_PROP( osType, Description, "ostype", "Guest OS:");
751 else
752 SHOW_STRING_PROP( machine, OSTypeId, "ostype", "Guest OS:");
753 SHOW_UUID_PROP( machine, Id, "UUID", "UUID:");
754 SHOW_STRING_PROP( machine, SettingsFilePath, "CfgFile", "Config file:");
755 SHOW_STRING_PROP( machine, SnapshotFolder, "SnapFldr", "Snapshot folder:");
756 SHOW_STRING_PROP( machine, LogFolder, "LogFldr", "Log folder:");
757 SHOW_UUID_PROP( machine, HardwareUUID, "hardwareuuid", "Hardware UUID:");
758 SHOW_ULONG_PROP( machine, MemorySize, "memory", "Memory size", "MB");
759 SHOW_BOOLEAN_PROP( machine, PageFusionEnabled, "pagefusion", "Page Fusion:");
760 ComPtr<IGraphicsAdapter> pGraphicsAdapter;
761 machine->COMGETTER(GraphicsAdapter)(pGraphicsAdapter.asOutParam());
762 SHOW_ULONG_PROP(pGraphicsAdapter, VRAMSize, "vram", "VRAM size:", "MB");
763 SHOW_ULONG_PROP( machine, CPUExecutionCap, "cpuexecutioncap", "CPU exec cap:", "%");
764 SHOW_BOOLEAN_PROP( machine, HPETEnabled, "hpet", "HPET:");
765 SHOW_STRING_PROP_MAJ( machine, CPUProfile, "cpu-profile", "CPUProfile:", "host", 6);
766
767 ChipsetType_T chipsetType;
768 CHECK_ERROR2I_RET(machine, COMGETTER(ChipsetType)(&chipsetType), hrcCheck);
769 const char *pszChipsetType;
770 switch (chipsetType)
771 {
772 case ChipsetType_Null: pszChipsetType = "invalid"; break;
773 case ChipsetType_PIIX3: pszChipsetType = "piix3"; break;
774 case ChipsetType_ICH9: pszChipsetType = "ich9"; break;
775 default: AssertFailed(); pszChipsetType = "unknown"; break;
776 }
777 SHOW_UTF8_STRING("chipset", "Chipset:", pszChipsetType);
778
779 FirmwareType_T firmwareType;
780 CHECK_ERROR2I_RET(machine, COMGETTER(FirmwareType)(&firmwareType), hrcCheck);
781 const char *pszFirmwareType;
782 switch (firmwareType)
783 {
784 case FirmwareType_BIOS: pszFirmwareType = "BIOS"; break;
785 case FirmwareType_EFI: pszFirmwareType = "EFI"; break;
786 case FirmwareType_EFI32: pszFirmwareType = "EFI32"; break;
787 case FirmwareType_EFI64: pszFirmwareType = "EFI64"; break;
788 case FirmwareType_EFIDUAL: pszFirmwareType = "EFIDUAL"; break;
789 default: AssertFailed(); pszFirmwareType = "unknown"; break;
790 }
791 SHOW_UTF8_STRING("firmware", "Firmware:", pszFirmwareType);
792
793 SHOW_ULONG_PROP( machine, CPUCount, "cpus", "Number of CPUs:", "");
794 SHOW_BOOLEAN_METHOD( machine, GetCPUProperty(CPUPropertyType_PAE, &f), "pae", "PAE:");
795 SHOW_BOOLEAN_METHOD( machine, GetCPUProperty(CPUPropertyType_LongMode, &f), "longmode", "Long Mode:");
796 SHOW_BOOLEAN_METHOD( machine, GetCPUProperty(CPUPropertyType_TripleFaultReset, &f), "triplefaultreset", "Triple Fault Reset:");
797 SHOW_BOOLEAN_METHOD( machine, GetCPUProperty(CPUPropertyType_APIC, &f), "apic", "APIC:");
798 SHOW_BOOLEAN_METHOD( machine, GetCPUProperty(CPUPropertyType_X2APIC, &f), "x2apic", "X2APIC:");
799 SHOW_BOOLEAN_METHOD( machine, GetCPUProperty(CPUPropertyType_HWVirt, &f), "nested-hw-virt", "Nested VT-x/AMD-V:");
800 SHOW_ULONG_PROP( machine, CPUIDPortabilityLevel, "cpuid-portability-level", "CPUID Portability Level:", "");
801
802 if (details != VMINFO_MACHINEREADABLE)
803 RTPrintf("%-28s ", "CPUID overrides:");
804 ULONG uOrdinal = 0;
805 for (uOrdinal = 0; uOrdinal < _4K; uOrdinal++)
806 {
807 ULONG uLeaf, uSubLeaf, uEAX, uEBX, uECX, uEDX;
808 rc = machine->GetCPUIDLeafByOrdinal(uOrdinal, &uLeaf, &uSubLeaf, &uEAX, &uEBX, &uECX, &uEDX);
809 if (SUCCEEDED(rc))
810 {
811 if (details == VMINFO_MACHINEREADABLE)
812 RTPrintf("cpuid=%08x,%08x,%08x,%08x,%08x,%08x", uLeaf, uSubLeaf, uEAX, uEBX, uECX, uEDX);
813 else
814 {
815 if (!uOrdinal)
816 RTPrintf("Leaf no. EAX EBX ECX EDX\n");
817 RTPrintf("%-28s %08x/%03x %08x %08x %08x %08x\n", "", uLeaf, uSubLeaf, uEAX, uEBX, uECX, uEDX);
818 }
819 }
820 else
821 {
822 if (rc != E_INVALIDARG)
823 com::GlueHandleComError(machine, "GetCPUIDLeaf", rc, __FILE__, __LINE__);
824 break;
825 }
826 }
827 if (!uOrdinal && details != VMINFO_MACHINEREADABLE)
828 RTPrintf("None\n");
829
830 ComPtr<IBIOSSettings> biosSettings;
831 CHECK_ERROR2I_RET(machine, COMGETTER(BIOSSettings)(biosSettings.asOutParam()), hrcCheck);
832
833 BIOSBootMenuMode_T bootMenuMode;
834 CHECK_ERROR2I_RET(biosSettings, COMGETTER(BootMenuMode)(&bootMenuMode), hrcCheck);
835 const char *pszBootMenu;
836 switch (bootMenuMode)
837 {
838 case BIOSBootMenuMode_Disabled:
839 pszBootMenu = "disabled";
840 break;
841 case BIOSBootMenuMode_MenuOnly:
842 if (details == VMINFO_MACHINEREADABLE)
843 pszBootMenu = "menuonly";
844 else
845 pszBootMenu = "menu only";
846 break;
847 default:
848 if (details == VMINFO_MACHINEREADABLE)
849 pszBootMenu = "messageandmenu";
850 else
851 pszBootMenu = "message and menu";
852 }
853 SHOW_UTF8_STRING("bootmenu", "Boot menu mode:", pszBootMenu);
854
855 ComPtr<ISystemProperties> systemProperties;
856 CHECK_ERROR2I_RET(pVirtualBox, COMGETTER(SystemProperties)(systemProperties.asOutParam()), hrcCheck);
857 ULONG maxBootPosition = 0;
858 CHECK_ERROR2I_RET(systemProperties, COMGETTER(MaxBootPosition)(&maxBootPosition), hrcCheck);
859 for (ULONG i = 1; i <= maxBootPosition; i++)
860 {
861 DeviceType_T bootOrder;
862 CHECK_ERROR2I_RET(machine, GetBootOrder(i, &bootOrder), hrcCheck);
863 const char *pszDevice;
864 if (bootOrder == DeviceType_Floppy)
865 pszDevice = details == VMINFO_MACHINEREADABLE ? "floppy" : "Floppy";
866 else if (bootOrder == DeviceType_DVD)
867 pszDevice = details == VMINFO_MACHINEREADABLE ? "dvd" : "DVD";
868 else if (bootOrder == DeviceType_HardDisk)
869 pszDevice = details == VMINFO_MACHINEREADABLE ? "disk" : "HardDisk";
870 else if (bootOrder == DeviceType_Network)
871 pszDevice = details == VMINFO_MACHINEREADABLE ? "net" : "Network";
872 else if (bootOrder == DeviceType_USB)
873 pszDevice = details == VMINFO_MACHINEREADABLE ? "usb" : "USB";
874 else if (bootOrder == DeviceType_SharedFolder)
875 pszDevice = details == VMINFO_MACHINEREADABLE ? "sharedfolder" : "Shared Folder";
876 else
877 pszDevice = details == VMINFO_MACHINEREADABLE ? "none" : "Not Assigned";
878 SHOW_UTF8_STRING(FmtNm(szNm, "boot%u", i), FmtNm(szNm, "Boot Device %u:", i), pszDevice);
879 }
880
881 SHOW_BOOLEAN_PROP(biosSettings, ACPIEnabled, "acpi", "ACPI:");
882 SHOW_BOOLEAN_PROP(biosSettings, IOAPICEnabled, "ioapic", "IOAPIC:");
883
884 APICMode_T apicMode;
885 CHECK_ERROR2I_RET(biosSettings, COMGETTER(APICMode)(&apicMode), hrcCheck);
886 const char *pszAPIC;
887 switch (apicMode)
888 {
889 case APICMode_Disabled:
890 pszAPIC = "disabled";
891 break;
892 case APICMode_APIC:
893 default:
894 if (details == VMINFO_MACHINEREADABLE)
895 pszAPIC = "apic";
896 else
897 pszAPIC = "APIC";
898 break;
899 case APICMode_X2APIC:
900 if (details == VMINFO_MACHINEREADABLE)
901 pszAPIC = "x2apic";
902 else
903 pszAPIC = "x2APIC";
904 break;
905 }
906 SHOW_UTF8_STRING("biosapic", "BIOS APIC mode:", pszAPIC);
907
908 SHOW_LONG64_PROP(biosSettings, TimeOffset, "biossystemtimeoffset", "Time offset:", "ms");
909 Bstr bstrNVRAMFile;
910 CHECK_ERROR2I_RET(biosSettings, COMGETTER(NonVolatileStorageFile)(bstrNVRAMFile.asOutParam()), hrcCheck);
911 if (bstrNVRAMFile.isNotEmpty())
912 SHOW_BSTR_STRING("BIOS NVRAM File", "BIOS NVRAM File:", bstrNVRAMFile);
913 SHOW_BOOLEAN_PROP_EX(machine, RTCUseUTC, "rtcuseutc", "RTC:", "UTC", "local time");
914 SHOW_BOOLEAN_METHOD(machine, GetHWVirtExProperty(HWVirtExPropertyType_Enabled, &f), "hwvirtex", "Hardware Virtualization:");
915 SHOW_BOOLEAN_METHOD(machine, GetHWVirtExProperty(HWVirtExPropertyType_NestedPaging, &f),"nestedpaging", "Nested Paging:");
916 SHOW_BOOLEAN_METHOD(machine, GetHWVirtExProperty(HWVirtExPropertyType_LargePages, &f), "largepages", "Large Pages:");
917 SHOW_BOOLEAN_METHOD(machine, GetHWVirtExProperty(HWVirtExPropertyType_VPID, &f), "vtxvpid", "VT-x VPID:");
918 SHOW_BOOLEAN_METHOD(machine, GetHWVirtExProperty(HWVirtExPropertyType_UnrestrictedExecution, &f), "vtxux", "VT-x Unrestricted Exec.:");
919 SHOW_BOOLEAN_METHOD(machine, GetHWVirtExProperty(HWVirtExPropertyType_VirtVmsaveVmload, &f), "virtvmsavevmload", "AMD-V Virt. Vmsave/Vmload:");
920
921 ParavirtProvider_T paravirtProvider;
922 CHECK_ERROR2I_RET(machine, COMGETTER(ParavirtProvider)(&paravirtProvider), hrcCheck);
923 const char *pszParavirtProvider = paravirtProviderToString(paravirtProvider, details);
924 SHOW_UTF8_STRING("paravirtprovider", "Paravirt. Provider:", pszParavirtProvider);
925
926 ParavirtProvider_T effParavirtProvider;
927 CHECK_ERROR2I_RET(machine, GetEffectiveParavirtProvider(&effParavirtProvider), hrcCheck);
928 const char *pszEffParavirtProvider = paravirtProviderToString(effParavirtProvider, details);
929 SHOW_UTF8_STRING("effparavirtprovider", "Effective Paravirt. Prov.:", pszEffParavirtProvider);
930
931 Bstr paravirtDebug;
932 CHECK_ERROR2I_RET(machine, COMGETTER(ParavirtDebug)(paravirtDebug.asOutParam()), hrcCheck);
933 if (paravirtDebug.isNotEmpty())
934 SHOW_BSTR_STRING("paravirtdebug", "Paravirt. Debug:", paravirtDebug);
935
936 MachineState_T machineState;
937 CHECK_ERROR2I_RET(machine, COMGETTER(State)(&machineState), hrcCheck);
938 const char *pszState = machineStateToName(machineState, details == VMINFO_MACHINEREADABLE /*=fShort*/);
939
940 LONG64 stateSince;
941 machine->COMGETTER(LastStateChange)(&stateSince);
942 RTTIMESPEC timeSpec;
943 RTTimeSpecSetMilli(&timeSpec, stateSince);
944 char pszTime[30] = {0};
945 RTTimeSpecToString(&timeSpec, pszTime, sizeof(pszTime));
946 if (details == VMINFO_MACHINEREADABLE)
947 {
948 RTPrintf("VMState=\"%s\"\n", pszState);
949 RTPrintf("VMStateChangeTime=\"%s\"\n", pszTime);
950
951 Bstr stateFile;
952 machine->COMGETTER(StateFilePath)(stateFile.asOutParam());
953 if (!stateFile.isEmpty())
954 RTPrintf("VMStateFile=\"%ls\"\n", stateFile.raw());
955 }
956 else
957 RTPrintf("%-28s %s (since %s)\n", "State:", pszState, pszTime);
958
959 GraphicsControllerType_T enmGraphics;
960 rc = pGraphicsAdapter->COMGETTER(GraphicsControllerType)(&enmGraphics);
961 if (SUCCEEDED(rc))
962 {
963 const char *pszCtrl = "Unknown";
964 switch (enmGraphics)
965 {
966 case GraphicsControllerType_Null:
967 if (details == VMINFO_MACHINEREADABLE)
968 pszCtrl = "null";
969 else
970 pszCtrl = "Null";
971 break;
972 case GraphicsControllerType_VBoxVGA:
973 if (details == VMINFO_MACHINEREADABLE)
974 pszCtrl = "vboxvga";
975 else
976 pszCtrl = "VBoxVGA";
977 break;
978 case GraphicsControllerType_VMSVGA:
979 if (details == VMINFO_MACHINEREADABLE)
980 pszCtrl = "vmsvga";
981 else
982 pszCtrl = "VMSVGA";
983 break;
984 case GraphicsControllerType_VBoxSVGA:
985 if (details == VMINFO_MACHINEREADABLE)
986 pszCtrl = "vboxsvga";
987 else
988 pszCtrl = "VBoxSVGA";
989 break;
990 default:
991 if (details == VMINFO_MACHINEREADABLE)
992 pszCtrl = "unknown";
993 break;
994 }
995
996 if (details == VMINFO_MACHINEREADABLE)
997 RTPrintf("graphicscontroller=\"%s\"\n", pszCtrl);
998 else
999 RTPrintf("%-28s %s\n", "Graphics Controller:", pszCtrl);
1000 }
1001
1002 SHOW_ULONG_PROP(pGraphicsAdapter, MonitorCount, "monitorcount", "Monitor count:", "");
1003 SHOW_BOOLEAN_PROP(pGraphicsAdapter, Accelerate3DEnabled, "accelerate3d", "3D Acceleration:");
1004#ifdef VBOX_WITH_VIDEOHWACCEL
1005 SHOW_BOOLEAN_PROP(pGraphicsAdapter, Accelerate2DVideoEnabled, "accelerate2dvideo", "2D Video Acceleration:");
1006#endif
1007 SHOW_BOOLEAN_PROP( machine, TeleporterEnabled, "teleporterenabled", "Teleporter Enabled:");
1008 SHOW_ULONG_PROP( machine, TeleporterPort, "teleporterport", "Teleporter Port:", "");
1009 SHOW_STRING_PROP( machine, TeleporterAddress, "teleporteraddress", "Teleporter Address:");
1010 SHOW_STRING_PROP( machine, TeleporterPassword, "teleporterpassword", "Teleporter Password:");
1011 SHOW_BOOLEAN_PROP( machine, TracingEnabled, "tracing-enabled", "Tracing Enabled:");
1012 SHOW_BOOLEAN_PROP( machine, AllowTracingToAccessVM, "tracing-allow-vm-access", "Allow Tracing to Access VM:");
1013 SHOW_STRING_PROP( machine, TracingConfig, "tracing-config", "Tracing Configuration:");
1014 SHOW_BOOLEAN_PROP( machine, AutostartEnabled, "autostart-enabled", "Autostart Enabled:");
1015 SHOW_ULONG_PROP( machine, AutostartDelay, "autostart-delay", "Autostart Delay:", "");
1016 SHOW_STRING_PROP( machine, DefaultFrontend, "defaultfrontend", "Default Frontend:");
1017
1018 VMProcPriority_T enmVMProcPriority;
1019 CHECK_ERROR2I_RET(machine, COMGETTER(VMProcessPriority)(&enmVMProcPriority), hrcCheck);
1020 const char *pszVMProcPriority;
1021 switch (enmVMProcPriority)
1022 {
1023 case VMProcPriority_Flat:
1024 pszVMProcPriority = "flat";
1025 break;
1026 case VMProcPriority_Low:
1027 pszVMProcPriority = "low";
1028 break;
1029 case VMProcPriority_Normal:
1030 pszVMProcPriority = "normal";
1031 break;
1032 case VMProcPriority_High:
1033 pszVMProcPriority = "high";
1034 break;
1035 default:
1036 pszVMProcPriority = "default";
1037 break;
1038 }
1039 SHOW_UTF8_STRING("vmprocpriority", "VM process priority:", pszVMProcPriority);
1040
1041/** @todo Convert the remainder of the function to SHOW_XXX macros and add error
1042 * checking where missing. */
1043 /*
1044 * Storage Controllers and their attached Mediums.
1045 */
1046 com::SafeIfaceArray<IStorageController> storageCtls;
1047 CHECK_ERROR(machine, COMGETTER(StorageControllers)(ComSafeArrayAsOutParam(storageCtls)));
1048 for (size_t i = 0; i < storageCtls.size(); ++ i)
1049 {
1050 ComPtr<IStorageController> storageCtl = storageCtls[i];
1051 StorageControllerType_T enmCtlType = StorageControllerType_Null;
1052 const char *pszCtl = NULL;
1053 ULONG ulValue = 0;
1054 BOOL fBootable = FALSE;
1055 Bstr storageCtlName;
1056
1057 storageCtl->COMGETTER(Name)(storageCtlName.asOutParam());
1058 if (details == VMINFO_MACHINEREADABLE)
1059 RTPrintf("storagecontrollername%u=\"%ls\"\n", i, storageCtlName.raw());
1060 else
1061 RTPrintf("Storage Controller Name (%u): %ls\n", i, storageCtlName.raw());
1062
1063 storageCtl->COMGETTER(ControllerType)(&enmCtlType);
1064 switch (enmCtlType)
1065 {
1066 case StorageControllerType_LsiLogic:
1067 pszCtl = "LsiLogic";
1068 break;
1069 case StorageControllerType_LsiLogicSas:
1070 pszCtl = "LsiLogicSas";
1071 break;
1072 case StorageControllerType_BusLogic:
1073 pszCtl = "BusLogic";
1074 break;
1075 case StorageControllerType_IntelAhci:
1076 pszCtl = "IntelAhci";
1077 break;
1078 case StorageControllerType_PIIX3:
1079 pszCtl = "PIIX3";
1080 break;
1081 case StorageControllerType_PIIX4:
1082 pszCtl = "PIIX4";
1083 break;
1084 case StorageControllerType_ICH6:
1085 pszCtl = "ICH6";
1086 break;
1087 case StorageControllerType_I82078:
1088 pszCtl = "I82078";
1089 break;
1090 case StorageControllerType_USB:
1091 pszCtl = "USB";
1092 break;
1093
1094 default:
1095 pszCtl = "unknown";
1096 }
1097 if (details == VMINFO_MACHINEREADABLE)
1098 RTPrintf("storagecontrollertype%u=\"%s\"\n", i, pszCtl);
1099 else
1100 RTPrintf("Storage Controller Type (%u): %s\n", i, pszCtl);
1101
1102 storageCtl->COMGETTER(Instance)(&ulValue);
1103 if (details == VMINFO_MACHINEREADABLE)
1104 RTPrintf("storagecontrollerinstance%u=\"%lu\"\n", i, ulValue);
1105 else
1106 RTPrintf("Storage Controller Instance Number (%u): %lu\n", i, ulValue);
1107
1108 storageCtl->COMGETTER(MaxPortCount)(&ulValue);
1109 if (details == VMINFO_MACHINEREADABLE)
1110 RTPrintf("storagecontrollermaxportcount%u=\"%lu\"\n", i, ulValue);
1111 else
1112 RTPrintf("Storage Controller Max Port Count (%u): %lu\n", i, ulValue);
1113
1114 storageCtl->COMGETTER(PortCount)(&ulValue);
1115 if (details == VMINFO_MACHINEREADABLE)
1116 RTPrintf("storagecontrollerportcount%u=\"%lu\"\n", i, ulValue);
1117 else
1118 RTPrintf("Storage Controller Port Count (%u): %lu\n", i, ulValue);
1119
1120 storageCtl->COMGETTER(Bootable)(&fBootable);
1121 if (details == VMINFO_MACHINEREADABLE)
1122 RTPrintf("storagecontrollerbootable%u=\"%s\"\n", i, fBootable ? "on" : "off");
1123 else
1124 RTPrintf("Storage Controller Bootable (%u): %s\n", i, fBootable ? "on" : "off");
1125 }
1126
1127 for (size_t j = 0; j < storageCtls.size(); ++ j)
1128 {
1129 ComPtr<IStorageController> storageCtl = storageCtls[j];
1130 ComPtr<IMedium> medium;
1131 Bstr storageCtlName;
1132 Bstr filePath;
1133 ULONG cDevices;
1134 ULONG cPorts;
1135
1136 storageCtl->COMGETTER(Name)(storageCtlName.asOutParam());
1137 storageCtl->COMGETTER(MaxDevicesPerPortCount)(&cDevices);
1138 storageCtl->COMGETTER(PortCount)(&cPorts);
1139
1140 for (ULONG i = 0; i < cPorts; ++ i)
1141 {
1142 for (ULONG k = 0; k < cDevices; ++ k)
1143 {
1144 ComPtr<IMediumAttachment> mediumAttach;
1145 machine->GetMediumAttachment(storageCtlName.raw(),
1146 i, k,
1147 mediumAttach.asOutParam());
1148 BOOL fIsEjected = FALSE;
1149 BOOL fTempEject = FALSE;
1150 DeviceType_T devType = DeviceType_Null;
1151 if (mediumAttach)
1152 {
1153 mediumAttach->COMGETTER(TemporaryEject)(&fTempEject);
1154 mediumAttach->COMGETTER(IsEjected)(&fIsEjected);
1155 mediumAttach->COMGETTER(Type)(&devType);
1156 }
1157 rc = machine->GetMedium(storageCtlName.raw(), i, k,
1158 medium.asOutParam());
1159 if (SUCCEEDED(rc) && medium)
1160 {
1161 BOOL fPassthrough = FALSE;
1162
1163 if (mediumAttach)
1164 mediumAttach->COMGETTER(Passthrough)(&fPassthrough);
1165
1166 medium->COMGETTER(Location)(filePath.asOutParam());
1167 Bstr uuid;
1168 medium->COMGETTER(Id)(uuid.asOutParam());
1169
1170 if (details == VMINFO_MACHINEREADABLE)
1171 {
1172 RTPrintf("\"%ls-%d-%d\"=\"%ls\"\n", storageCtlName.raw(),
1173 i, k, filePath.raw());
1174 RTPrintf("\"%ls-ImageUUID-%d-%d\"=\"%s\"\n",
1175 storageCtlName.raw(), i, k, Utf8Str(uuid).c_str());
1176 if (fPassthrough)
1177 RTPrintf("\"%ls-dvdpassthrough\"=\"%s\"\n", storageCtlName.raw(),
1178 fPassthrough ? "on" : "off");
1179 if (devType == DeviceType_DVD)
1180 {
1181 RTPrintf("\"%ls-tempeject\"=\"%s\"\n", storageCtlName.raw(),
1182 fTempEject ? "on" : "off");
1183 RTPrintf("\"%ls-IsEjected\"=\"%s\"\n", storageCtlName.raw(),
1184 fIsEjected ? "on" : "off");
1185 }
1186 }
1187 else
1188 {
1189 RTPrintf("%ls (%d, %d): %ls (UUID: %s)",
1190 storageCtlName.raw(), i, k, filePath.raw(),
1191 Utf8Str(uuid).c_str());
1192 if (fPassthrough)
1193 RTPrintf(" (passthrough enabled)");
1194 if (fTempEject)
1195 RTPrintf(" (temp eject)");
1196 if (fIsEjected)
1197 RTPrintf(" (ejected)");
1198 RTPrintf("\n");
1199 }
1200 }
1201 else if (SUCCEEDED(rc))
1202 {
1203 if (details == VMINFO_MACHINEREADABLE)
1204 {
1205 RTPrintf("\"%ls-%d-%d\"=\"emptydrive\"\n", storageCtlName.raw(), i, k);
1206 if (devType == DeviceType_DVD)
1207 RTPrintf("\"%ls-IsEjected\"=\"%s\"\n", storageCtlName.raw(),
1208 fIsEjected ? "on" : "off");
1209 }
1210 else
1211 {
1212 RTPrintf("%ls (%d, %d): Empty", storageCtlName.raw(), i, k);
1213 if (fTempEject)
1214 RTPrintf(" (temp eject)");
1215 if (fIsEjected)
1216 RTPrintf(" (ejected)");
1217 RTPrintf("\n");
1218 }
1219 }
1220 else
1221 {
1222 if (details == VMINFO_MACHINEREADABLE)
1223 RTPrintf("\"%ls-%d-%d\"=\"none\"\n", storageCtlName.raw(), i, k);
1224 }
1225 }
1226 }
1227 }
1228
1229 /* get the maximum amount of NICS */
1230 ULONG maxNICs = getMaxNics(pVirtualBox, machine);
1231
1232 for (ULONG currentNIC = 0; currentNIC < maxNICs; currentNIC++)
1233 {
1234 ComPtr<INetworkAdapter> nic;
1235 rc = machine->GetNetworkAdapter(currentNIC, nic.asOutParam());
1236 if (SUCCEEDED(rc) && nic)
1237 {
1238 FmtNm(szNm, details == VMINFO_MACHINEREADABLE ? "nic%u" : "NIC %u:", currentNIC + 1);
1239
1240 BOOL fEnabled;
1241 nic->COMGETTER(Enabled)(&fEnabled);
1242 if (!fEnabled)
1243 {
1244 if (details == VMINFO_MACHINEREADABLE)
1245 RTPrintf("%s=\"none\"\n", szNm);
1246 else
1247 RTPrintf("%-28s disabled\n", szNm);
1248 }
1249 else
1250 {
1251 Bstr strMACAddress;
1252 nic->COMGETTER(MACAddress)(strMACAddress.asOutParam());
1253 Utf8Str strAttachment;
1254 Utf8Str strNatSettings;
1255 Utf8Str strNatForwardings;
1256 NetworkAttachmentType_T attachment;
1257 nic->COMGETTER(AttachmentType)(&attachment);
1258 switch (attachment)
1259 {
1260 case NetworkAttachmentType_Null:
1261 if (details == VMINFO_MACHINEREADABLE)
1262 strAttachment = "null";
1263 else
1264 strAttachment = "none";
1265 break;
1266
1267 case NetworkAttachmentType_NAT:
1268 {
1269 Bstr strNetwork;
1270 ComPtr<INATEngine> engine;
1271 nic->COMGETTER(NATEngine)(engine.asOutParam());
1272 engine->COMGETTER(Network)(strNetwork.asOutParam());
1273 com::SafeArray<BSTR> forwardings;
1274 engine->COMGETTER(Redirects)(ComSafeArrayAsOutParam(forwardings));
1275 strNatForwardings = "";
1276 for (size_t i = 0; i < forwardings.size(); ++i)
1277 {
1278 bool fSkip = false;
1279 BSTR r = forwardings[i];
1280 Utf8Str utf = Utf8Str(r);
1281 Utf8Str strName;
1282 Utf8Str strProto;
1283 Utf8Str strHostPort;
1284 Utf8Str strHostIP;
1285 Utf8Str strGuestPort;
1286 Utf8Str strGuestIP;
1287 size_t pos, ppos;
1288 pos = ppos = 0;
1289#define ITERATE_TO_NEXT_TERM(res, str, pos, ppos) \
1290 do { \
1291 pos = str.find(",", ppos); \
1292 if (pos == Utf8Str::npos) \
1293 { \
1294 Log(( #res " extracting from %s is failed\n", str.c_str())); \
1295 fSkip = true; \
1296 } \
1297 res = str.substr(ppos, pos - ppos); \
1298 Log2((#res " %s pos:%d, ppos:%d\n", res.c_str(), pos, ppos)); \
1299 ppos = pos + 1; \
1300 } while (0)
1301 ITERATE_TO_NEXT_TERM(strName, utf, pos, ppos);
1302 if (fSkip) continue;
1303 ITERATE_TO_NEXT_TERM(strProto, utf, pos, ppos);
1304 if (fSkip) continue;
1305 ITERATE_TO_NEXT_TERM(strHostIP, utf, pos, ppos);
1306 if (fSkip) continue;
1307 ITERATE_TO_NEXT_TERM(strHostPort, utf, pos, ppos);
1308 if (fSkip) continue;
1309 ITERATE_TO_NEXT_TERM(strGuestIP, utf, pos, ppos);
1310 if (fSkip) continue;
1311 strGuestPort = utf.substr(ppos, utf.length() - ppos);
1312#undef ITERATE_TO_NEXT_TERM
1313 switch (strProto.toUInt32())
1314 {
1315 case NATProtocol_TCP:
1316 strProto = "tcp";
1317 break;
1318 case NATProtocol_UDP:
1319 strProto = "udp";
1320 break;
1321 default:
1322 strProto = "unk";
1323 break;
1324 }
1325 if (details == VMINFO_MACHINEREADABLE)
1326 /** @todo r=bird: This probably isn't good enough wrt escaping. */
1327 strNatForwardings.printf("%sForwarding(%d)=\"%s,%s,%s,%s,%s,%s\"\n",
1328 strNatForwardings.c_str(), i, strName.c_str(), strProto.c_str(),
1329 strHostIP.c_str(), strHostPort.c_str(),
1330 strGuestIP.c_str(), strGuestPort.c_str());
1331 else
1332 strNatForwardings.printf("%sNIC %d Rule(%d): name = %s, protocol = %s, host ip = %s, host port = %s, guest ip = %s, guest port = %s\n",
1333 strNatForwardings.c_str(), currentNIC + 1, i, strName.c_str(),
1334 strProto.c_str(), strHostIP.c_str(), strHostPort.c_str(),
1335 strGuestIP.c_str(), strGuestPort.c_str());
1336 }
1337 ULONG mtu = 0;
1338 ULONG sockSnd = 0;
1339 ULONG sockRcv = 0;
1340 ULONG tcpSnd = 0;
1341 ULONG tcpRcv = 0;
1342 engine->GetNetworkSettings(&mtu, &sockSnd, &sockRcv, &tcpSnd, &tcpRcv);
1343
1344/** @todo r=klaus dnsproxy etc needs to be dumped, too */
1345 if (details == VMINFO_MACHINEREADABLE)
1346 {
1347 RTPrintf("natnet%d=\"%ls\"\n", currentNIC + 1, strNetwork.length() ? strNetwork.raw(): Bstr("nat").raw());
1348 strAttachment = "nat";
1349 strNatSettings.printf("mtu=\"%d\"\nsockSnd=\"%d\"\nsockRcv=\"%d\"\ntcpWndSnd=\"%d\"\ntcpWndRcv=\"%d\"\n",
1350 mtu, sockSnd ? sockSnd : 64, sockRcv ? sockRcv : 64, tcpSnd ? tcpSnd : 64, tcpRcv ? tcpRcv : 64);
1351 }
1352 else
1353 {
1354 strAttachment = "NAT";
1355 strNatSettings.printf("NIC %d Settings: MTU: %d, Socket (send: %d, receive: %d), TCP Window (send:%d, receive: %d)\n",
1356 currentNIC + 1, mtu, sockSnd ? sockSnd : 64, sockRcv ? sockRcv : 64, tcpSnd ? tcpSnd : 64, tcpRcv ? tcpRcv : 64);
1357 }
1358 break;
1359 }
1360
1361 case NetworkAttachmentType_Bridged:
1362 {
1363 Bstr strBridgeAdp;
1364 nic->COMGETTER(BridgedInterface)(strBridgeAdp.asOutParam());
1365 if (details == VMINFO_MACHINEREADABLE)
1366 {
1367 RTPrintf("bridgeadapter%d=\"%ls\"\n", currentNIC + 1, strBridgeAdp.raw());
1368 strAttachment = "bridged";
1369 }
1370 else
1371 strAttachment.printf("Bridged Interface '%ls'", strBridgeAdp.raw());
1372 break;
1373 }
1374
1375 case NetworkAttachmentType_Internal:
1376 {
1377 Bstr strNetwork;
1378 nic->COMGETTER(InternalNetwork)(strNetwork.asOutParam());
1379 if (details == VMINFO_MACHINEREADABLE)
1380 {
1381 RTPrintf("intnet%d=\"%ls\"\n", currentNIC + 1, strNetwork.raw());
1382 strAttachment = "intnet";
1383 }
1384 else
1385 strAttachment.printf("Internal Network '%s'", Utf8Str(strNetwork).c_str());
1386 break;
1387 }
1388
1389 case NetworkAttachmentType_HostOnly:
1390 {
1391 Bstr strHostonlyAdp;
1392 nic->COMGETTER(HostOnlyInterface)(strHostonlyAdp.asOutParam());
1393 if (details == VMINFO_MACHINEREADABLE)
1394 {
1395 RTPrintf("hostonlyadapter%d=\"%ls\"\n", currentNIC + 1, strHostonlyAdp.raw());
1396 strAttachment = "hostonly";
1397 }
1398 else
1399 strAttachment.printf("Host-only Interface '%ls'", strHostonlyAdp.raw());
1400 break;
1401 }
1402
1403 case NetworkAttachmentType_Generic:
1404 {
1405 Bstr strGenericDriver;
1406 nic->COMGETTER(GenericDriver)(strGenericDriver.asOutParam());
1407 if (details == VMINFO_MACHINEREADABLE)
1408 {
1409 RTPrintf("generic%d=\"%ls\"\n", currentNIC + 1, strGenericDriver.raw());
1410 strAttachment = "Generic";
1411 }
1412 else
1413 {
1414 strAttachment.printf("Generic '%ls'", strGenericDriver.raw());
1415
1416 // show the generic properties
1417 com::SafeArray<BSTR> aProperties;
1418 com::SafeArray<BSTR> aValues;
1419 rc = nic->GetProperties(NULL,
1420 ComSafeArrayAsOutParam(aProperties),
1421 ComSafeArrayAsOutParam(aValues));
1422 if (SUCCEEDED(rc))
1423 {
1424 strAttachment += " { ";
1425 for (unsigned i = 0; i < aProperties.size(); ++i)
1426 strAttachment.appendPrintf(!i ? "%ls='%ls'" : ", %ls='%ls'", aProperties[i], aValues[i]);
1427 strAttachment += " }";
1428 }
1429 }
1430 break;
1431 }
1432
1433 case NetworkAttachmentType_NATNetwork:
1434 {
1435 Bstr strNetwork;
1436 nic->COMGETTER(NATNetwork)(strNetwork.asOutParam());
1437 if (details == VMINFO_MACHINEREADABLE)
1438 {
1439 RTPrintf("nat-network%d=\"%ls\"\n", currentNIC + 1, strNetwork.raw());
1440 strAttachment = "natnetwork";
1441 }
1442 else
1443 strAttachment.printf("NAT Network '%s'", Utf8Str(strNetwork).c_str());
1444 break;
1445 }
1446
1447#ifdef VBOX_WITH_CLOUD_NET
1448 case NetworkAttachmentType_Cloud:
1449 {
1450 Bstr strNetwork;
1451 nic->COMGETTER(CloudNetwork)(strNetwork.asOutParam());
1452 if (details == VMINFO_MACHINEREADABLE)
1453 {
1454 RTPrintf("cloud-network%d=\"%ls\"\n", currentNIC + 1, strNetwork.raw());
1455 strAttachment = "cloudnetwork";
1456 }
1457 else
1458 strAttachment.printf("Cloud Network '%s'", Utf8Str(strNetwork).c_str());
1459 break;
1460 }
1461#endif /* VBOX_WITH_CLOUD_NET */
1462
1463 default:
1464 strAttachment = "unknown";
1465 break;
1466 }
1467
1468 /* cable connected */
1469 BOOL fConnected;
1470 nic->COMGETTER(CableConnected)(&fConnected);
1471
1472 /* promisc policy */
1473 NetworkAdapterPromiscModePolicy_T enmPromiscModePolicy;
1474 CHECK_ERROR2I_RET(nic, COMGETTER(PromiscModePolicy)(&enmPromiscModePolicy), hrcCheck);
1475 const char *pszPromiscuousGuestPolicy;
1476 switch (enmPromiscModePolicy)
1477 {
1478 case NetworkAdapterPromiscModePolicy_Deny: pszPromiscuousGuestPolicy = "deny"; break;
1479 case NetworkAdapterPromiscModePolicy_AllowNetwork: pszPromiscuousGuestPolicy = "allow-vms"; break;
1480 case NetworkAdapterPromiscModePolicy_AllowAll: pszPromiscuousGuestPolicy = "allow-all"; break;
1481 default: AssertFailedReturn(E_INVALIDARG);
1482 }
1483
1484 /* trace stuff */
1485 BOOL fTraceEnabled;
1486 nic->COMGETTER(TraceEnabled)(&fTraceEnabled);
1487 Bstr traceFile;
1488 nic->COMGETTER(TraceFile)(traceFile.asOutParam());
1489
1490 /* NIC type */
1491 NetworkAdapterType_T NICType;
1492 nic->COMGETTER(AdapterType)(&NICType);
1493 const char *pszNICType;
1494 switch (NICType)
1495 {
1496 case NetworkAdapterType_Am79C970A: pszNICType = "Am79C970A"; break;
1497 case NetworkAdapterType_Am79C973: pszNICType = "Am79C973"; break;
1498 case NetworkAdapterType_Am79C960: pszNICType = "Am79C960"; break;
1499#ifdef VBOX_WITH_E1000
1500 case NetworkAdapterType_I82540EM: pszNICType = "82540EM"; break;
1501 case NetworkAdapterType_I82543GC: pszNICType = "82543GC"; break;
1502 case NetworkAdapterType_I82545EM: pszNICType = "82545EM"; break;
1503#endif
1504#ifdef VBOX_WITH_VIRTIO
1505 case NetworkAdapterType_Virtio: pszNICType = "virtio"; break;
1506
1507#endif
1508#ifdef VBOX_WITH_VIRTIO_NET_1_0
1509 case NetworkAdapterType_Virtio_1_0: pszNICType = "virtio_1.0"; break;
1510#endif
1511 default: AssertFailed(); pszNICType = "unknown"; break;
1512 }
1513
1514 /* reported line speed */
1515 ULONG ulLineSpeed;
1516 nic->COMGETTER(LineSpeed)(&ulLineSpeed);
1517
1518 /* boot priority of the adapter */
1519 ULONG ulBootPriority;
1520 nic->COMGETTER(BootPriority)(&ulBootPriority);
1521
1522 /* bandwidth group */
1523 ComObjPtr<IBandwidthGroup> pBwGroup;
1524 Bstr strBwGroup;
1525 nic->COMGETTER(BandwidthGroup)(pBwGroup.asOutParam());
1526 if (!pBwGroup.isNull())
1527 pBwGroup->COMGETTER(Name)(strBwGroup.asOutParam());
1528
1529 if (details == VMINFO_MACHINEREADABLE)
1530 {
1531 RTPrintf("macaddress%d=\"%ls\"\n", currentNIC + 1, strMACAddress.raw());
1532 RTPrintf("cableconnected%d=\"%s\"\n", currentNIC + 1, fConnected ? "on" : "off");
1533 RTPrintf("nic%d=\"%s\"\n", currentNIC + 1, strAttachment.c_str());
1534 RTPrintf("nictype%d=\"%s\"\n", currentNIC + 1, pszNICType);
1535 RTPrintf("nicspeed%d=\"%d\"\n", currentNIC + 1, ulLineSpeed);
1536 }
1537 else
1538 RTPrintf("%-28s MAC: %ls, Attachment: %s, Cable connected: %s, Trace: %s (file: %ls), Type: %s, Reported speed: %d Mbps, Boot priority: %d, Promisc Policy: %s, Bandwidth group: %ls\n",
1539 szNm, strMACAddress.raw(), strAttachment.c_str(),
1540 fConnected ? "on" : "off",
1541 fTraceEnabled ? "on" : "off",
1542 traceFile.isEmpty() ? Bstr("none").raw() : traceFile.raw(),
1543 pszNICType,
1544 ulLineSpeed / 1000,
1545 (int)ulBootPriority,
1546 pszPromiscuousGuestPolicy,
1547 strBwGroup.isEmpty() ? Bstr("none").raw() : strBwGroup.raw());
1548 if (strNatSettings.length())
1549 RTPrintf(strNatSettings.c_str());
1550 if (strNatForwardings.length())
1551 RTPrintf(strNatForwardings.c_str());
1552 }
1553 }
1554 }
1555
1556 /* Pointing device information */
1557 PointingHIDType_T aPointingHID;
1558 const char *pszHID = "Unknown";
1559 const char *pszMrHID = "unknown";
1560 machine->COMGETTER(PointingHIDType)(&aPointingHID);
1561 switch (aPointingHID)
1562 {
1563 case PointingHIDType_None:
1564 pszHID = "None";
1565 pszMrHID = "none";
1566 break;
1567 case PointingHIDType_PS2Mouse:
1568 pszHID = "PS/2 Mouse";
1569 pszMrHID = "ps2mouse";
1570 break;
1571 case PointingHIDType_USBMouse:
1572 pszHID = "USB Mouse";
1573 pszMrHID = "usbmouse";
1574 break;
1575 case PointingHIDType_USBTablet:
1576 pszHID = "USB Tablet";
1577 pszMrHID = "usbtablet";
1578 break;
1579 case PointingHIDType_ComboMouse:
1580 pszHID = "USB Tablet and PS/2 Mouse";
1581 pszMrHID = "combomouse";
1582 break;
1583 case PointingHIDType_USBMultiTouch:
1584 pszHID = "USB Multi-Touch";
1585 pszMrHID = "usbmultitouch";
1586 break;
1587 default:
1588 break;
1589 }
1590 SHOW_UTF8_STRING("hidpointing", "Pointing Device:", details == VMINFO_MACHINEREADABLE ? pszMrHID : pszHID);
1591
1592 /* Keyboard device information */
1593 KeyboardHIDType_T aKeyboardHID;
1594 machine->COMGETTER(KeyboardHIDType)(&aKeyboardHID);
1595 pszHID = "Unknown";
1596 pszMrHID = "unknown";
1597 switch (aKeyboardHID)
1598 {
1599 case KeyboardHIDType_None:
1600 pszHID = "None";
1601 pszMrHID = "none";
1602 break;
1603 case KeyboardHIDType_PS2Keyboard:
1604 pszHID = "PS/2 Keyboard";
1605 pszMrHID = "ps2kbd";
1606 break;
1607 case KeyboardHIDType_USBKeyboard:
1608 pszHID = "USB Keyboard";
1609 pszMrHID = "usbkbd";
1610 break;
1611 case KeyboardHIDType_ComboKeyboard:
1612 pszHID = "USB and PS/2 Keyboard";
1613 pszMrHID = "combokbd";
1614 break;
1615 default:
1616 break;
1617 }
1618 SHOW_UTF8_STRING("hidkeyboard", "Keyboard Device:", details == VMINFO_MACHINEREADABLE ? pszMrHID : pszHID);
1619
1620 ComPtr<ISystemProperties> sysProps;
1621 pVirtualBox->COMGETTER(SystemProperties)(sysProps.asOutParam());
1622
1623 /* get the maximum amount of UARTs */
1624 ULONG maxUARTs = 0;
1625 sysProps->COMGETTER(SerialPortCount)(&maxUARTs);
1626 for (ULONG currentUART = 0; currentUART < maxUARTs; currentUART++)
1627 {
1628 ComPtr<ISerialPort> uart;
1629 rc = machine->GetSerialPort(currentUART, uart.asOutParam());
1630 if (SUCCEEDED(rc) && uart)
1631 {
1632 FmtNm(szNm, details == VMINFO_MACHINEREADABLE ? "uart%u" : "UART %u:", currentUART + 1);
1633
1634 /* show the config of this UART */
1635 BOOL fEnabled;
1636 uart->COMGETTER(Enabled)(&fEnabled);
1637 if (!fEnabled)
1638 {
1639 if (details == VMINFO_MACHINEREADABLE)
1640 RTPrintf("%s=\"off\"\n", szNm);
1641 else
1642 RTPrintf("%-28s disabled\n", szNm);
1643 }
1644 else
1645 {
1646 ULONG ulIRQ, ulIOBase;
1647 PortMode_T HostMode;
1648 Bstr path;
1649 BOOL fServer;
1650 UartType_T UartType;
1651 uart->COMGETTER(IRQ)(&ulIRQ);
1652 uart->COMGETTER(IOBase)(&ulIOBase);
1653 uart->COMGETTER(Path)(path.asOutParam());
1654 uart->COMGETTER(Server)(&fServer);
1655 uart->COMGETTER(HostMode)(&HostMode);
1656 uart->COMGETTER(UartType)(&UartType);
1657
1658 if (details == VMINFO_MACHINEREADABLE)
1659 RTPrintf("%s=\"%#06x,%d\"\n", szNm, ulIOBase, ulIRQ);
1660 else
1661 RTPrintf("%-28s I/O base: %#06x, IRQ: %d", szNm, ulIOBase, ulIRQ);
1662 switch (HostMode)
1663 {
1664 default:
1665 case PortMode_Disconnected:
1666 if (details == VMINFO_MACHINEREADABLE)
1667 RTPrintf("uartmode%d=\"disconnected\"\n", currentUART + 1);
1668 else
1669 RTPrintf(", disconnected");
1670 break;
1671 case PortMode_RawFile:
1672 if (details == VMINFO_MACHINEREADABLE)
1673 RTPrintf("uartmode%d=\"file,%ls\"\n", currentUART + 1,
1674 path.raw());
1675 else
1676 RTPrintf(", attached to raw file '%ls'\n",
1677 path.raw());
1678 break;
1679 case PortMode_TCP:
1680 if (details == VMINFO_MACHINEREADABLE)
1681 RTPrintf("uartmode%d=\"%s,%ls\"\n", currentUART + 1,
1682 fServer ? "tcpserver" : "tcpclient", path.raw());
1683 else
1684 RTPrintf(", attached to tcp (%s) '%ls'",
1685 fServer ? "server" : "client", path.raw());
1686 break;
1687 case PortMode_HostPipe:
1688 if (details == VMINFO_MACHINEREADABLE)
1689 RTPrintf("uartmode%d=\"%s,%ls\"\n", currentUART + 1,
1690 fServer ? "server" : "client", path.raw());
1691 else
1692 RTPrintf(", attached to pipe (%s) '%ls'",
1693 fServer ? "server" : "client", path.raw());
1694 break;
1695 case PortMode_HostDevice:
1696 if (details == VMINFO_MACHINEREADABLE)
1697 RTPrintf("uartmode%d=\"%ls\"\n", currentUART + 1,
1698 path.raw());
1699 else
1700 RTPrintf(", attached to device '%ls'", path.raw());
1701 break;
1702 }
1703 switch (UartType)
1704 {
1705 default:
1706 case UartType_U16450:
1707 if (details == VMINFO_MACHINEREADABLE)
1708 RTPrintf("uarttype%d=\"16450\"\n", currentUART + 1);
1709 else
1710 RTPrintf(", 16450\n");
1711 break;
1712 case UartType_U16550A:
1713 if (details == VMINFO_MACHINEREADABLE)
1714 RTPrintf("uarttype%d=\"16550A\"\n", currentUART + 1);
1715 else
1716 RTPrintf(", 16550A\n");
1717 break;
1718 case UartType_U16750:
1719 if (details == VMINFO_MACHINEREADABLE)
1720 RTPrintf("uarttype%d=\"16750\"\n", currentUART + 1);
1721 else
1722 RTPrintf(", 16750\n");
1723 break;
1724 }
1725 }
1726 }
1727 }
1728
1729 /* get the maximum amount of LPTs */
1730 ULONG maxLPTs = 0;
1731 sysProps->COMGETTER(ParallelPortCount)(&maxLPTs);
1732 for (ULONG currentLPT = 0; currentLPT < maxLPTs; currentLPT++)
1733 {
1734 ComPtr<IParallelPort> lpt;
1735 rc = machine->GetParallelPort(currentLPT, lpt.asOutParam());
1736 if (SUCCEEDED(rc) && lpt)
1737 {
1738 FmtNm(szNm, details == VMINFO_MACHINEREADABLE ? "lpt%u" : "LPT %u:", currentLPT + 1);
1739
1740 /* show the config of this LPT */
1741 BOOL fEnabled;
1742 lpt->COMGETTER(Enabled)(&fEnabled);
1743 if (!fEnabled)
1744 {
1745 if (details == VMINFO_MACHINEREADABLE)
1746 RTPrintf("%s=\"off\"\n", szNm);
1747 else
1748 RTPrintf("%-28s disabled\n", szNm);
1749 }
1750 else
1751 {
1752 ULONG ulIRQ, ulIOBase;
1753 Bstr path;
1754 lpt->COMGETTER(IRQ)(&ulIRQ);
1755 lpt->COMGETTER(IOBase)(&ulIOBase);
1756 lpt->COMGETTER(Path)(path.asOutParam());
1757
1758 if (details == VMINFO_MACHINEREADABLE)
1759 RTPrintf("%s=\"%#06x,%d\"\n", szNm, ulIOBase, ulIRQ);
1760 else
1761 RTPrintf("%-28s I/O base: %#06x, IRQ: %d", szNm, ulIOBase, ulIRQ);
1762 if (details == VMINFO_MACHINEREADABLE)
1763 RTPrintf("lptmode%d=\"%ls\"\n", currentLPT + 1, path.raw());
1764 else
1765 RTPrintf(", attached to device '%ls'\n", path.raw());
1766 }
1767 }
1768 }
1769
1770 ComPtr<IAudioAdapter> AudioAdapter;
1771 rc = machine->COMGETTER(AudioAdapter)(AudioAdapter.asOutParam());
1772 if (SUCCEEDED(rc))
1773 {
1774 const char *pszDrv = "Unknown";
1775 const char *pszCtrl = "Unknown";
1776 const char *pszCodec = "Unknown";
1777 BOOL fEnabled;
1778 rc = AudioAdapter->COMGETTER(Enabled)(&fEnabled);
1779 if (SUCCEEDED(rc) && fEnabled)
1780 {
1781 AudioDriverType_T enmDrvType;
1782 rc = AudioAdapter->COMGETTER(AudioDriver)(&enmDrvType);
1783 switch (enmDrvType)
1784 {
1785 case AudioDriverType_Null:
1786 if (details == VMINFO_MACHINEREADABLE)
1787 pszDrv = "null";
1788 else
1789 pszDrv = "Null";
1790 break;
1791 case AudioDriverType_WinMM:
1792 if (details == VMINFO_MACHINEREADABLE)
1793 pszDrv = "winmm";
1794 else
1795 pszDrv = "WINMM";
1796 break;
1797 case AudioDriverType_DirectSound:
1798 if (details == VMINFO_MACHINEREADABLE)
1799 pszDrv = "dsound";
1800 else
1801 pszDrv = "DSOUND";
1802 break;
1803 case AudioDriverType_OSS:
1804 if (details == VMINFO_MACHINEREADABLE)
1805 pszDrv = "oss";
1806 else
1807 pszDrv = "OSS";
1808 break;
1809 case AudioDriverType_ALSA:
1810 if (details == VMINFO_MACHINEREADABLE)
1811 pszDrv = "alsa";
1812 else
1813 pszDrv = "ALSA";
1814 break;
1815 case AudioDriverType_Pulse:
1816 if (details == VMINFO_MACHINEREADABLE)
1817 pszDrv = "pulse";
1818 else
1819 pszDrv = "PulseAudio";
1820 break;
1821 case AudioDriverType_CoreAudio:
1822 if (details == VMINFO_MACHINEREADABLE)
1823 pszDrv = "coreaudio";
1824 else
1825 pszDrv = "CoreAudio";
1826 break;
1827 case AudioDriverType_SolAudio:
1828 if (details == VMINFO_MACHINEREADABLE)
1829 pszDrv = "solaudio";
1830 else
1831 pszDrv = "SolAudio";
1832 break;
1833 default:
1834 if (details == VMINFO_MACHINEREADABLE)
1835 pszDrv = "unknown";
1836 break;
1837 }
1838 AudioControllerType_T enmCtrlType;
1839 rc = AudioAdapter->COMGETTER(AudioController)(&enmCtrlType);
1840 switch (enmCtrlType)
1841 {
1842 case AudioControllerType_AC97:
1843 if (details == VMINFO_MACHINEREADABLE)
1844 pszCtrl = "ac97";
1845 else
1846 pszCtrl = "AC97";
1847 break;
1848 case AudioControllerType_SB16:
1849 if (details == VMINFO_MACHINEREADABLE)
1850 pszCtrl = "sb16";
1851 else
1852 pszCtrl = "SB16";
1853 break;
1854 case AudioControllerType_HDA:
1855 if (details == VMINFO_MACHINEREADABLE)
1856 pszCtrl = "hda";
1857 else
1858 pszCtrl = "HDA";
1859 break;
1860 default:
1861 break;
1862 }
1863 AudioCodecType_T enmCodecType;
1864 rc = AudioAdapter->COMGETTER(AudioCodec)(&enmCodecType);
1865 switch (enmCodecType)
1866 {
1867 case AudioCodecType_SB16:
1868 pszCodec = "SB16";
1869 break;
1870 case AudioCodecType_STAC9700:
1871 pszCodec = "STAC9700";
1872 break;
1873 case AudioCodecType_AD1980:
1874 pszCodec = "AD1980";
1875 break;
1876 case AudioCodecType_STAC9221:
1877 pszCodec = "STAC9221";
1878 break;
1879 case AudioCodecType_Null: break; /* Shut up MSC. */
1880 default: break;
1881 }
1882 }
1883 else
1884 fEnabled = FALSE;
1885
1886 if (details == VMINFO_MACHINEREADABLE)
1887 RTPrintf("audio=\"%s\"\n", fEnabled ? pszDrv : "none");
1888 else
1889 {
1890 RTPrintf("%-28s %s", "Audio:", fEnabled ? "enabled" : "disabled");
1891 if (fEnabled)
1892 RTPrintf(" (Driver: %s, Controller: %s, Codec: %s)", pszDrv, pszCtrl, pszCodec);
1893 RTPrintf("\n");
1894 }
1895 SHOW_BOOLEAN_PROP(AudioAdapter, EnabledOut, "audio_out", "Audio playback:");
1896 SHOW_BOOLEAN_PROP(AudioAdapter, EnabledIn, "audio_in", "Audio capture:");
1897 }
1898
1899 /* Shared clipboard */
1900 {
1901 const char *psz;
1902 ClipboardMode_T enmMode = (ClipboardMode_T)0;
1903 rc = machine->COMGETTER(ClipboardMode)(&enmMode);
1904 switch (enmMode)
1905 {
1906 case ClipboardMode_Disabled:
1907 psz = "disabled";
1908 break;
1909 case ClipboardMode_HostToGuest:
1910 psz = details == VMINFO_MACHINEREADABLE ? "hosttoguest" : "HostToGuest";
1911 break;
1912 case ClipboardMode_GuestToHost:
1913 psz = details == VMINFO_MACHINEREADABLE ? "guesttohost" : "GuestToHost";
1914 break;
1915 case ClipboardMode_Bidirectional:
1916 psz = details == VMINFO_MACHINEREADABLE ? "bidirectional" : "Bidirectional";
1917 break;
1918 default:
1919 psz = details == VMINFO_MACHINEREADABLE ? "unknown" : "Unknown";
1920 break;
1921 }
1922 SHOW_UTF8_STRING("clipboard", "Clipboard Mode:", psz);
1923#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
1924 SHOW_BOOLEAN_PROP(machine, ClipboardFileTransfersEnabled, "clipboard_file_transfers", "Clipboard file transfers:");
1925#endif
1926 }
1927
1928 /* Drag and drop */
1929 {
1930 const char *psz;
1931 DnDMode_T enmMode;
1932 rc = machine->COMGETTER(DnDMode)(&enmMode);
1933 switch (enmMode)
1934 {
1935 case DnDMode_Disabled:
1936 psz = "disabled";
1937 break;
1938 case DnDMode_HostToGuest:
1939 psz = details == VMINFO_MACHINEREADABLE ? "hosttoguest" : "HostToGuest";
1940 break;
1941 case DnDMode_GuestToHost:
1942 psz = details == VMINFO_MACHINEREADABLE ? "guesttohost" : "GuestToHost";
1943 break;
1944 case DnDMode_Bidirectional:
1945 psz = details == VMINFO_MACHINEREADABLE ? "bidirectional" : "Bidirectional";
1946 break;
1947 default:
1948 psz = details == VMINFO_MACHINEREADABLE ? "unknown" : "Unknown";
1949 break;
1950 }
1951 SHOW_UTF8_STRING("draganddrop", "Drag and drop Mode:", psz);
1952 }
1953
1954 {
1955 SessionState_T sessState;
1956 rc = machine->COMGETTER(SessionState)(&sessState);
1957 if (SUCCEEDED(rc) && sessState != SessionState_Unlocked)
1958 {
1959 Bstr sessName;
1960 rc = machine->COMGETTER(SessionName)(sessName.asOutParam());
1961 if (SUCCEEDED(rc) && !sessName.isEmpty())
1962 SHOW_BSTR_STRING("SessionName", "Session name:", sessName);
1963 }
1964 }
1965
1966 if (pConsole)
1967 {
1968 do
1969 {
1970 ComPtr<IDisplay> display;
1971 rc = pConsole->COMGETTER(Display)(display.asOutParam());
1972 if (rc == E_ACCESSDENIED || display.isNull())
1973 break; /* VM not powered up */
1974 if (FAILED(rc))
1975 {
1976 com::GlueHandleComError(pConsole, "COMGETTER(Display)(display.asOutParam())", rc, __FILE__, __LINE__);
1977 return rc;
1978 }
1979 ULONG xRes, yRes, bpp;
1980 LONG xOrigin, yOrigin;
1981 GuestMonitorStatus_T monitorStatus;
1982 rc = display->GetScreenResolution(0, &xRes, &yRes, &bpp, &xOrigin, &yOrigin, &monitorStatus);
1983 if (rc == E_ACCESSDENIED)
1984 break; /* VM not powered up */
1985 if (FAILED(rc))
1986 {
1987 com::ErrorInfo info(display, COM_IIDOF(IDisplay));
1988 GluePrintErrorInfo(info);
1989 return rc;
1990 }
1991 if (details == VMINFO_MACHINEREADABLE)
1992 RTPrintf("VideoMode=\"%d,%d,%d\"@%d,%d %d\n", xRes, yRes, bpp, xOrigin, yOrigin, monitorStatus);
1993 else
1994 {
1995 const char *pszMonitorStatus = "unknown status";
1996 switch (monitorStatus)
1997 {
1998 case GuestMonitorStatus_Blank: pszMonitorStatus = "blank"; break;
1999 case GuestMonitorStatus_Enabled: pszMonitorStatus = "enabled"; break;
2000 case GuestMonitorStatus_Disabled: pszMonitorStatus = "disabled"; break;
2001 default: break;
2002 }
2003 RTPrintf("%-28s %dx%dx%d at %d,%d %s\n", "Video mode:", xRes, yRes, bpp, xOrigin, yOrigin, pszMonitorStatus);
2004 }
2005 }
2006 while (0);
2007 }
2008
2009 /*
2010 * Remote Desktop
2011 */
2012 ComPtr<IVRDEServer> vrdeServer;
2013 rc = machine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
2014 if (SUCCEEDED(rc) && vrdeServer)
2015 {
2016 BOOL fEnabled = false;
2017 vrdeServer->COMGETTER(Enabled)(&fEnabled);
2018 if (fEnabled)
2019 {
2020 LONG currentPort = -1;
2021 Bstr ports;
2022 vrdeServer->GetVRDEProperty(Bstr("TCP/Ports").raw(), ports.asOutParam());
2023 Bstr address;
2024 vrdeServer->GetVRDEProperty(Bstr("TCP/Address").raw(), address.asOutParam());
2025 BOOL fMultiCon;
2026 vrdeServer->COMGETTER(AllowMultiConnection)(&fMultiCon);
2027 BOOL fReuseCon;
2028 vrdeServer->COMGETTER(ReuseSingleConnection)(&fReuseCon);
2029 Bstr videoChannel;
2030 vrdeServer->GetVRDEProperty(Bstr("VideoChannel/Enabled").raw(), videoChannel.asOutParam());
2031 BOOL fVideoChannel = (videoChannel.compare(Bstr("true"), Bstr::CaseInsensitive)== 0)
2032 || (videoChannel == "1");
2033 Bstr videoChannelQuality;
2034 vrdeServer->GetVRDEProperty(Bstr("VideoChannel/Quality").raw(), videoChannelQuality.asOutParam());
2035 AuthType_T authType = (AuthType_T)0;
2036 const char *strAuthType;
2037 vrdeServer->COMGETTER(AuthType)(&authType);
2038 switch (authType)
2039 {
2040 case AuthType_Null:
2041 strAuthType = "null";
2042 break;
2043 case AuthType_External:
2044 strAuthType = "external";
2045 break;
2046 case AuthType_Guest:
2047 strAuthType = "guest";
2048 break;
2049 default:
2050 strAuthType = "unknown";
2051 break;
2052 }
2053 if (pConsole)
2054 {
2055 ComPtr<IVRDEServerInfo> vrdeServerInfo;
2056 CHECK_ERROR_RET(pConsole, COMGETTER(VRDEServerInfo)(vrdeServerInfo.asOutParam()), rc);
2057 if (!vrdeServerInfo.isNull())
2058 {
2059 rc = vrdeServerInfo->COMGETTER(Port)(&currentPort);
2060 if (rc == E_ACCESSDENIED)
2061 {
2062 currentPort = -1; /* VM not powered up */
2063 }
2064 else if (FAILED(rc))
2065 {
2066 com::ErrorInfo info(vrdeServerInfo, COM_IIDOF(IVRDEServerInfo));
2067 GluePrintErrorInfo(info);
2068 return rc;
2069 }
2070 }
2071 }
2072 if (details == VMINFO_MACHINEREADABLE)
2073 {
2074 RTPrintf("vrde=\"on\"\n");
2075 RTPrintf("vrdeport=%d\n", currentPort);
2076 RTPrintf("vrdeports=\"%ls\"\n", ports.raw());
2077 RTPrintf("vrdeaddress=\"%ls\"\n", address.raw());
2078 RTPrintf("vrdeauthtype=\"%s\"\n", strAuthType);
2079 RTPrintf("vrdemulticon=\"%s\"\n", fMultiCon ? "on" : "off");
2080 RTPrintf("vrdereusecon=\"%s\"\n", fReuseCon ? "on" : "off");
2081 RTPrintf("vrdevideochannel=\"%s\"\n", fVideoChannel ? "on" : "off");
2082 if (fVideoChannel)
2083 RTPrintf("vrdevideochannelquality=\"%ls\"\n", videoChannelQuality.raw());
2084 }
2085 else
2086 {
2087 if (address.isEmpty())
2088 address = "0.0.0.0";
2089 RTPrintf("%-28s enabled (Address %ls, Ports %ls, MultiConn: %s, ReuseSingleConn: %s, Authentication type: %s)\n",
2090 "VRDE:", address.raw(), ports.raw(), fMultiCon ? "on" : "off", fReuseCon ? "on" : "off", strAuthType);
2091 if (pConsole && currentPort != -1 && currentPort != 0)
2092 RTPrintf("%-28s %d\n", "VRDE port:", currentPort);
2093 if (fVideoChannel)
2094 RTPrintf("%-28s enabled (Quality %ls)\n", "Video redirection:", videoChannelQuality.raw());
2095 else
2096 RTPrintf("%-28s disabled\n", "Video redirection:");
2097 }
2098 com::SafeArray<BSTR> aProperties;
2099 if (SUCCEEDED(vrdeServer->COMGETTER(VRDEProperties)(ComSafeArrayAsOutParam(aProperties))))
2100 {
2101 unsigned i;
2102 for (i = 0; i < aProperties.size(); ++i)
2103 {
2104 Bstr value;
2105 vrdeServer->GetVRDEProperty(aProperties[i], value.asOutParam());
2106 if (details == VMINFO_MACHINEREADABLE)
2107 {
2108 if (value.isEmpty())
2109 RTPrintf("vrdeproperty[%ls]=<not set>\n", aProperties[i]);
2110 else
2111 RTPrintf("vrdeproperty[%ls]=\"%ls\"\n", aProperties[i], value.raw());
2112 }
2113 else
2114 {
2115 if (value.isEmpty())
2116 RTPrintf("%-28s: %-10lS = <not set>\n", "VRDE property", aProperties[i]);
2117 else
2118 RTPrintf("%-28s: %-10lS = \"%ls\"\n", "VRDE property", aProperties[i], value.raw());
2119 }
2120 }
2121 }
2122 }
2123 else
2124 {
2125 if (details == VMINFO_MACHINEREADABLE)
2126 RTPrintf("vrde=\"off\"\n");
2127 else
2128 RTPrintf("%-28s disabled\n", "VRDE:");
2129 }
2130 }
2131
2132 /*
2133 * USB.
2134 */
2135 SafeIfaceArray<IUSBController> USBCtlColl;
2136 rc = machine->COMGETTER(USBControllers)(ComSafeArrayAsOutParam(USBCtlColl));
2137 if (SUCCEEDED(rc))
2138 {
2139 bool fOhciEnabled = false;
2140 bool fEhciEnabled = false;
2141 bool fXhciEnabled = false;
2142
2143 for (unsigned i = 0; i < USBCtlColl.size(); i++)
2144 {
2145 USBControllerType_T enmType;
2146
2147 rc = USBCtlColl[i]->COMGETTER(Type)(&enmType);
2148 if (SUCCEEDED(rc))
2149 {
2150 switch (enmType)
2151 {
2152 case USBControllerType_OHCI:
2153 fOhciEnabled = true;
2154 break;
2155 case USBControllerType_EHCI:
2156 fEhciEnabled = true;
2157 break;
2158 case USBControllerType_XHCI:
2159 fXhciEnabled = true;
2160 break;
2161 default:
2162 break;
2163 }
2164 }
2165 }
2166
2167 SHOW_BOOL_VALUE("usb", "OHCI USB:", fOhciEnabled);
2168 SHOW_BOOL_VALUE("ehci", "EHCI USB:", fEhciEnabled);
2169 SHOW_BOOL_VALUE("xhci", "xHCI USB:", fXhciEnabled);
2170 }
2171
2172 ComPtr<IUSBDeviceFilters> USBFlts;
2173 rc = machine->COMGETTER(USBDeviceFilters)(USBFlts.asOutParam());
2174 if (SUCCEEDED(rc))
2175 {
2176 SafeIfaceArray <IUSBDeviceFilter> Coll;
2177 rc = USBFlts->COMGETTER(DeviceFilters)(ComSafeArrayAsOutParam(Coll));
2178 if (SUCCEEDED(rc))
2179 {
2180 if (details != VMINFO_MACHINEREADABLE)
2181 RTPrintf("\nUSB Device Filters:\n\n");
2182
2183 if (Coll.size() == 0)
2184 {
2185 if (details != VMINFO_MACHINEREADABLE)
2186 RTPrintf("<none>\n\n");
2187 }
2188 else
2189 {
2190 for (size_t index = 0; index < Coll.size(); ++index)
2191 {
2192 ComPtr<IUSBDeviceFilter> DevPtr = Coll[index];
2193
2194 if (details != VMINFO_MACHINEREADABLE)
2195 SHOW_UTF8_STRING("index", "Index:", FmtNm(szNm, "%zu", index));
2196 SHOW_BOOLEAN_PROP_EX(DevPtr, Active, FmtNm(szNm, "USBFilterActive%zu", index + 1), "Active:", "yes", "no");
2197 SHOW_STRING_PROP(DevPtr, Name, FmtNm(szNm, "USBFilterName%zu", index + 1), "Name:");
2198 SHOW_STRING_PROP(DevPtr, VendorId, FmtNm(szNm, "USBFilterVendorId%zu", index + 1), "VendorId:");
2199 SHOW_STRING_PROP(DevPtr, ProductId, FmtNm(szNm, "USBFilterProductId%zu", index + 1), "ProductId:");
2200 SHOW_STRING_PROP(DevPtr, Revision, FmtNm(szNm, "USBFilterRevision%zu", index + 1), "Revision:");
2201 SHOW_STRING_PROP(DevPtr, Manufacturer, FmtNm(szNm, "USBFilterManufacturer%zu", index + 1), "Manufacturer:");
2202 SHOW_STRING_PROP(DevPtr, Product, FmtNm(szNm, "USBFilterProduct%zu", index + 1), "Product:");
2203 SHOW_STRING_PROP(DevPtr, Remote, FmtNm(szNm, "USBFilterRemote%zu", index + 1), "Remote:");
2204 SHOW_STRING_PROP(DevPtr, SerialNumber, FmtNm(szNm, "USBFilterSerialNumber%zu", index + 1), "Serial Number:");
2205 if (details != VMINFO_MACHINEREADABLE)
2206 {
2207 ULONG fMaskedIfs;
2208 CHECK_ERROR_RET(DevPtr, COMGETTER(MaskedInterfaces)(&fMaskedIfs), rc);
2209 if (fMaskedIfs)
2210 RTPrintf("%-28s %#010x\n", "Masked Interfaces:", fMaskedIfs);
2211 RTPrintf("\n");
2212 }
2213 }
2214 }
2215 }
2216
2217 if (pConsole)
2218 {
2219 /* scope */
2220 {
2221 if (details != VMINFO_MACHINEREADABLE)
2222 RTPrintf("Available remote USB devices:\n\n");
2223
2224 SafeIfaceArray <IHostUSBDevice> coll;
2225 CHECK_ERROR_RET(pConsole, COMGETTER(RemoteUSBDevices)(ComSafeArrayAsOutParam(coll)), rc);
2226
2227 if (coll.size() == 0)
2228 {
2229 if (details != VMINFO_MACHINEREADABLE)
2230 RTPrintf("<none>\n\n");
2231 }
2232 else
2233 {
2234 /* This code is duplicated below, with USBAttach as prefix. */
2235 const char *pszPfx = "USBRemote";
2236 for (size_t i = 0; i < coll.size(); ++i)
2237 {
2238 ComPtr<IHostUSBDevice> dev = coll[i];
2239
2240 SHOW_STRING_PROP(dev, Id, FmtNm(szNm, "%sActive%zu", pszPfx, i + 1), "UUID:");
2241 SHOW_USHORT_PROP_EX2(dev, VendorId, FmtNm(szNm, "%sVendorId%zu", pszPfx, i + 1), "VendorId:", "", "%#06x", "%#06x (%04X)");
2242 SHOW_USHORT_PROP_EX2(dev, ProductId, FmtNm(szNm, "%sProductId%zu", pszPfx, i + 1), "ProductId:", "", "%#06x", "%#06x (%04X)");
2243
2244 USHORT bcdRevision;
2245 CHECK_ERROR_RET(dev, COMGETTER(Revision)(&bcdRevision), rc);
2246 if (details == VMINFO_MACHINEREADABLE)
2247 RTStrPrintf(szValue, sizeof(szValue), "%#04x%02x", bcdRevision >> 8, bcdRevision & 0xff);
2248 else
2249 RTStrPrintf(szValue, sizeof(szValue), "%u.%u (%02u%02u)\n",
2250 bcdRevision >> 8, bcdRevision & 0xff, bcdRevision >> 8, bcdRevision & 0xff);
2251 SHOW_UTF8_STRING(FmtNm(szNm, "%sRevision%zu", pszPfx, i + 1), "Revision:", szValue);
2252
2253 SHOW_STRING_PROP_NOT_EMPTY(dev, Manufacturer, FmtNm(szNm, "%sManufacturer%zu", pszPfx, i + 1), "Manufacturer:");
2254 SHOW_STRING_PROP_NOT_EMPTY(dev, Product, FmtNm(szNm, "%sProduct%zu", pszPfx, i + 1), "Product:");
2255 SHOW_STRING_PROP_NOT_EMPTY(dev, SerialNumber, FmtNm(szNm, "%sSerialNumber%zu", pszPfx, i + 1), "SerialNumber:");
2256 SHOW_STRING_PROP_NOT_EMPTY(dev, Address, FmtNm(szNm, "%sAddress%zu", pszPfx, i + 1), "Address:");
2257
2258 if (details != VMINFO_MACHINEREADABLE)
2259 RTPrintf("\n");
2260 }
2261 }
2262 }
2263
2264 /* scope */
2265 {
2266 if (details != VMINFO_MACHINEREADABLE)
2267 RTPrintf("Currently Attached USB Devices:\n\n");
2268
2269 SafeIfaceArray <IUSBDevice> coll;
2270 CHECK_ERROR_RET(pConsole, COMGETTER(USBDevices)(ComSafeArrayAsOutParam(coll)), rc);
2271
2272 if (coll.size() == 0)
2273 {
2274 if (details != VMINFO_MACHINEREADABLE)
2275 RTPrintf("<none>\n\n");
2276 }
2277 else
2278 {
2279 /* This code is duplicated below, with USBAttach as prefix. */
2280 const char *pszPfx = "USBAttach";
2281 for (size_t i = 0; i < coll.size(); ++i)
2282 {
2283 ComPtr<IUSBDevice> dev = coll[i];
2284
2285 SHOW_STRING_PROP(dev, Id, FmtNm(szNm, "%sActive%zu", pszPfx, i + 1), "UUID:");
2286 SHOW_USHORT_PROP_EX2(dev, VendorId, FmtNm(szNm, "%sVendorId%zu", pszPfx, i + 1), "VendorId:", "", "%#06x", "%#06x (%04X)");
2287 SHOW_USHORT_PROP_EX2(dev, ProductId, FmtNm(szNm, "%sProductId%zu", pszPfx, i + 1), "ProductId:", "", "%#06x", "%#06x (%04X)");
2288
2289 USHORT bcdRevision;
2290 CHECK_ERROR_RET(dev, COMGETTER(Revision)(&bcdRevision), rc);
2291 if (details == VMINFO_MACHINEREADABLE)
2292 RTStrPrintf(szValue, sizeof(szValue), "%#04x%02x", bcdRevision >> 8, bcdRevision & 0xff);
2293 else
2294 RTStrPrintf(szValue, sizeof(szValue), "%u.%u (%02u%02u)\n",
2295 bcdRevision >> 8, bcdRevision & 0xff, bcdRevision >> 8, bcdRevision & 0xff);
2296 SHOW_UTF8_STRING(FmtNm(szNm, "%sRevision%zu", pszPfx, i + 1), "Revision:", szValue);
2297
2298 SHOW_STRING_PROP_NOT_EMPTY(dev, Manufacturer, FmtNm(szNm, "%sManufacturer%zu", pszPfx, i + 1), "Manufacturer:");
2299 SHOW_STRING_PROP_NOT_EMPTY(dev, Product, FmtNm(szNm, "%sProduct%zu", pszPfx, i + 1), "Product:");
2300 SHOW_STRING_PROP_NOT_EMPTY(dev, SerialNumber, FmtNm(szNm, "%sSerialNumber%zu", pszPfx, i + 1), "SerialNumber:");
2301 SHOW_STRING_PROP_NOT_EMPTY(dev, Address, FmtNm(szNm, "%sAddress%zu", pszPfx, i + 1), "Address:");
2302
2303 if (details != VMINFO_MACHINEREADABLE)
2304 RTPrintf("\n");
2305 }
2306 }
2307 }
2308 }
2309 } /* USB */
2310
2311#ifdef VBOX_WITH_PCI_PASSTHROUGH
2312 /* Host PCI passthrough devices */
2313 {
2314 SafeIfaceArray <IPCIDeviceAttachment> assignments;
2315 rc = machine->COMGETTER(PCIDeviceAssignments)(ComSafeArrayAsOutParam(assignments));
2316 if (SUCCEEDED(rc))
2317 {
2318 if (assignments.size() > 0 && (details != VMINFO_MACHINEREADABLE))
2319 {
2320 RTPrintf("\nAttached physical PCI devices:\n\n");
2321 }
2322
2323 for (size_t index = 0; index < assignments.size(); ++index)
2324 {
2325 ComPtr<IPCIDeviceAttachment> Assignment = assignments[index];
2326 char szHostPCIAddress[32], szGuestPCIAddress[32];
2327 LONG iHostPCIAddress = -1, iGuestPCIAddress = -1;
2328 Bstr DevName;
2329
2330 Assignment->COMGETTER(Name)(DevName.asOutParam());
2331 Assignment->COMGETTER(HostAddress)(&iHostPCIAddress);
2332 Assignment->COMGETTER(GuestAddress)(&iGuestPCIAddress);
2333 PCIBusAddress().fromLong(iHostPCIAddress).format(szHostPCIAddress, sizeof(szHostPCIAddress));
2334 PCIBusAddress().fromLong(iGuestPCIAddress).format(szGuestPCIAddress, sizeof(szGuestPCIAddress));
2335
2336 if (details == VMINFO_MACHINEREADABLE)
2337 RTPrintf("AttachedHostPCI=%s,%s\n", szHostPCIAddress, szGuestPCIAddress);
2338 else
2339 RTPrintf(" Host device %ls at %s attached as %s\n", DevName.raw(), szHostPCIAddress, szGuestPCIAddress);
2340 }
2341
2342 if (assignments.size() > 0 && (details != VMINFO_MACHINEREADABLE))
2343 {
2344 RTPrintf("\n");
2345 }
2346 }
2347 }
2348 /* Host PCI passthrough devices */
2349#endif
2350
2351 /*
2352 * Bandwidth groups
2353 */
2354 if (details != VMINFO_MACHINEREADABLE)
2355 RTPrintf("Bandwidth groups: ");
2356 {
2357 ComPtr<IBandwidthControl> bwCtrl;
2358 CHECK_ERROR_RET(machine, COMGETTER(BandwidthControl)(bwCtrl.asOutParam()), rc);
2359
2360 rc = showBandwidthGroups(bwCtrl, details);
2361 }
2362
2363
2364 /*
2365 * Shared folders
2366 */
2367 if (details != VMINFO_MACHINEREADABLE)
2368 RTPrintf("Shared folders:");
2369 uint32_t numSharedFolders = 0;
2370#if 0 // not yet implemented
2371 /* globally shared folders first */
2372 {
2373 SafeIfaceArray <ISharedFolder> sfColl;
2374 CHECK_ERROR_RET(pVirtualBox, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(sfColl)), rc);
2375 for (size_t i = 0; i < sfColl.size(); ++i)
2376 {
2377 ComPtr<ISharedFolder> sf = sfColl[i];
2378 showSharedFolder(sf, details, "global mapping", "GlobalMapping", i + 1, numSharedFolders == 0);
2379 ++numSharedFolders;
2380 }
2381 }
2382#endif
2383 /* now VM mappings */
2384 {
2385 com::SafeIfaceArray <ISharedFolder> folders;
2386 CHECK_ERROR_RET(machine, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(folders)), rc);
2387 for (size_t i = 0; i < folders.size(); ++i)
2388 {
2389 ComPtr<ISharedFolder> sf = folders[i];
2390 showSharedFolder(sf, details, "machine mapping", "MachineMapping", i + 1, numSharedFolders == 0);
2391 ++numSharedFolders;
2392 }
2393 }
2394 /* transient mappings */
2395 if (pConsole)
2396 {
2397 com::SafeIfaceArray <ISharedFolder> folders;
2398 CHECK_ERROR_RET(pConsole, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(folders)), rc);
2399 for (size_t i = 0; i < folders.size(); ++i)
2400 {
2401 ComPtr<ISharedFolder> sf = folders[i];
2402 showSharedFolder(sf, details, "transient mapping", "TransientMapping", i + 1, numSharedFolders == 0);
2403 ++numSharedFolders;
2404 }
2405 }
2406 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
2407 RTPrintf("<none>\n");
2408 if (details != VMINFO_MACHINEREADABLE)
2409 RTPrintf("\n");
2410
2411 if (pConsole)
2412 {
2413 /*
2414 * Live VRDE info.
2415 */
2416 ComPtr<IVRDEServerInfo> vrdeServerInfo;
2417 CHECK_ERROR_RET(pConsole, COMGETTER(VRDEServerInfo)(vrdeServerInfo.asOutParam()), rc);
2418 BOOL fActive = FALSE;
2419 ULONG cNumberOfClients = 0;
2420 LONG64 BeginTime = 0;
2421 LONG64 EndTime = 0;
2422 LONG64 BytesSent = 0;
2423 LONG64 BytesSentTotal = 0;
2424 LONG64 BytesReceived = 0;
2425 LONG64 BytesReceivedTotal = 0;
2426 Bstr User;
2427 Bstr Domain;
2428 Bstr ClientName;
2429 Bstr ClientIP;
2430 ULONG ClientVersion = 0;
2431 ULONG EncryptionStyle = 0;
2432
2433 if (!vrdeServerInfo.isNull())
2434 {
2435 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(Active)(&fActive), rc);
2436 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(NumberOfClients)(&cNumberOfClients), rc);
2437 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BeginTime)(&BeginTime), rc);
2438 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(EndTime)(&EndTime), rc);
2439 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesSent)(&BytesSent), rc);
2440 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesSentTotal)(&BytesSentTotal), rc);
2441 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesReceived)(&BytesReceived), rc);
2442 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesReceivedTotal)(&BytesReceivedTotal), rc);
2443 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(User)(User.asOutParam()), rc);
2444 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(Domain)(Domain.asOutParam()), rc);
2445 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(ClientName)(ClientName.asOutParam()), rc);
2446 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(ClientIP)(ClientIP.asOutParam()), rc);
2447 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(ClientVersion)(&ClientVersion), rc);
2448 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(EncryptionStyle)(&EncryptionStyle), rc);
2449 }
2450
2451 SHOW_BOOL_VALUE_EX("VRDEActiveConnection", "VRDE Connection:", fActive, "active", "not active");
2452 SHOW_ULONG_VALUE("VRDEClients=", "Clients so far:", cNumberOfClients, "");
2453
2454 if (cNumberOfClients > 0)
2455 {
2456 char szTimeValue[128];
2457 makeTimeStr(szTimeValue, sizeof(szTimeValue), BeginTime);
2458 if (fActive)
2459 SHOW_UTF8_STRING("VRDEStartTime", "Start time:", szTimeValue);
2460 else
2461 {
2462 SHOW_UTF8_STRING("VRDELastStartTime", "Last started:", szTimeValue);
2463 makeTimeStr(szTimeValue, sizeof(szTimeValue), EndTime);
2464 SHOW_UTF8_STRING("VRDELastEndTime", "Last ended:", szTimeValue);
2465 }
2466
2467 int64_t ThroughputSend = 0;
2468 int64_t ThroughputReceive = 0;
2469 if (EndTime != BeginTime)
2470 {
2471 ThroughputSend = (BytesSent * 1000) / (EndTime - BeginTime);
2472 ThroughputReceive = (BytesReceived * 1000) / (EndTime - BeginTime);
2473 }
2474 SHOW_LONG64_VALUE("VRDEBytesSent", "Sent:", BytesSent, "Bytes");
2475 SHOW_LONG64_VALUE("VRDEThroughputSend", "Average speed:", ThroughputSend, "B/s");
2476 SHOW_LONG64_VALUE("VRDEBytesSentTotal", "Sent total:", BytesSentTotal, "Bytes");
2477
2478 SHOW_LONG64_VALUE("VRDEBytesReceived", "Received:", BytesReceived, "Bytes");
2479 SHOW_LONG64_VALUE("VRDEThroughputReceive", "Speed:", ThroughputReceive, "B/s");
2480 SHOW_LONG64_VALUE("VRDEBytesReceivedTotal", "Received total:", BytesReceivedTotal, "Bytes");
2481
2482 if (fActive)
2483 {
2484 SHOW_BSTR_STRING("VRDEUserName", "User name:", User);
2485 SHOW_BSTR_STRING("VRDEDomain", "Domain:", Domain);
2486 SHOW_BSTR_STRING("VRDEClientName", "Client name:", ClientName);
2487 SHOW_BSTR_STRING("VRDEClientIP", "Client IP:", ClientIP);
2488 SHOW_ULONG_VALUE("VRDEClientVersion", "Client version:", ClientVersion, "");
2489 SHOW_UTF8_STRING("VRDEEncryption", "Encryption:", EncryptionStyle == 0 ? "RDP4" : "RDP5 (X.509)");
2490 }
2491 }
2492
2493 if (details != VMINFO_MACHINEREADABLE)
2494 RTPrintf("\n");
2495 }
2496
2497#ifdef VBOX_WITH_RECORDING
2498 {
2499 /* Video capture */
2500 BOOL fCaptureVideo = FALSE;
2501# ifdef VBOX_WITH_AUDIO_RECORDING
2502 BOOL fCaptureAudio = FALSE;
2503# endif
2504
2505 ComPtr<IRecordingSettings> recordingSettings;
2506 CHECK_ERROR_RET(machine, COMGETTER(RecordingSettings)(recordingSettings.asOutParam()), rc);
2507
2508 SafeIfaceArray <IRecordingScreenSettings> saRecordingScreenScreens;
2509 CHECK_ERROR_RET(recordingSettings, COMGETTER(Screens)(ComSafeArrayAsOutParam(saRecordingScreenScreens)), rc);
2510
2511 /* For now all screens have the same configuration; so take screen 0 and work with that. */
2512 ULONG fFeatures;
2513 CHECK_ERROR_RET(saRecordingScreenScreens[0], COMGETTER(Features)(&fFeatures), rc);
2514 ULONG Width;
2515 CHECK_ERROR_RET(saRecordingScreenScreens[0], COMGETTER(VideoWidth)(&Width), rc);
2516 ULONG Height;
2517 CHECK_ERROR_RET(saRecordingScreenScreens[0], COMGETTER(VideoHeight)(&Height), rc);
2518 ULONG Rate;
2519 CHECK_ERROR_RET(saRecordingScreenScreens[0], COMGETTER(VideoRate)(&Rate), rc);
2520 ULONG Fps;
2521 CHECK_ERROR_RET(saRecordingScreenScreens[0], COMGETTER(VideoFPS)(&Fps), rc);
2522 Bstr bstrFile;
2523 CHECK_ERROR_RET(saRecordingScreenScreens[0], COMGETTER(Filename)(bstrFile.asOutParam()), rc);
2524 Bstr bstrOptions;
2525 CHECK_ERROR_RET(saRecordingScreenScreens[0], COMGETTER(Options)(bstrOptions.asOutParam()), rc);
2526
2527 Utf8Str strOptions(bstrOptions);
2528 size_t pos = 0;
2529 com::Utf8Str key, value;
2530 while ((pos = strOptions.parseKeyValue(key, value, pos)) != com::Utf8Str::npos)
2531 {
2532 if (key.compare("vc_enabled", Utf8Str::CaseInsensitive) == 0)
2533 {
2534 fCaptureVideo = value.compare("true", Utf8Str::CaseInsensitive) == 0;
2535 }
2536 else if (key.compare("ac_enabled", Utf8Str::CaseInsensitive) == 0)
2537 {
2538# ifdef VBOX_WITH_AUDIO_RECORDING
2539 fCaptureAudio = value.compare("true", Utf8Str::CaseInsensitive) == 0;
2540# endif
2541 }
2542 }
2543
2544 SHOW_BOOL_VALUE_EX("videocap", "Capturing:", fCaptureVideo, "active", "not active");
2545# ifdef VBOX_WITH_AUDIO_RECORDING
2546 SHOW_BOOL_VALUE_EX("videocapaudio", "Capture audio:", fCaptureAudio, "active", "not active");
2547# endif
2548 szValue[0] = '\0';
2549 for (size_t i = 0, off = 0; i < saRecordingScreenScreens.size(); i++)
2550 {
2551 BOOL fEnabled;
2552 CHECK_ERROR_RET(saRecordingScreenScreens[i], COMGETTER(Enabled)(&fEnabled), rc);
2553 if (fEnabled && off < sizeof(szValue) - 3)
2554 off += RTStrPrintf(&szValue[off], sizeof(szValue) - off, off ? ",%zu" : "%zu", i);
2555 }
2556 SHOW_UTF8_STRING("capturescreens", "Capture screens:", szValue);
2557 SHOW_BSTR_STRING("capturefilename", "Capture file:", bstrFile);
2558 RTStrPrintf(szValue, sizeof(szValue), "%ux%u", Width, Height);
2559 SHOW_UTF8_STRING("captureres", "Capture dimensions:", szValue);
2560 SHOW_ULONG_VALUE("capturevideorate", "Capture rate:", Rate, "kbps");
2561 SHOW_ULONG_VALUE("capturevideofps", "Capture FPS:", Fps, "kbps");
2562 SHOW_BSTR_STRING("captureopts", "Capture options:", bstrOptions);
2563
2564 if (details != VMINFO_MACHINEREADABLE)
2565 RTPrintf("\n");
2566 /** @todo Add more audio capturing profile / information here. */
2567 }
2568#endif /* VBOX_WITH_RECORDING */
2569
2570 if ( details == VMINFO_STANDARD
2571 || details == VMINFO_FULL
2572 || details == VMINFO_MACHINEREADABLE)
2573 {
2574 Bstr description;
2575 machine->COMGETTER(Description)(description.asOutParam());
2576 if (!description.isEmpty())
2577 {
2578 if (details == VMINFO_MACHINEREADABLE)
2579 outputMachineReadableString("description", &description);
2580 else
2581 RTPrintf("Description:\n%ls\n", description.raw());
2582 }
2583 }
2584
2585 if (details != VMINFO_MACHINEREADABLE)
2586 RTPrintf("Guest:\n\n");
2587
2588 SHOW_ULONG_PROP(machine, MemoryBalloonSize, "GuestMemoryBalloon", "Configured memory balloon size:", "MB");
2589
2590 if (pConsole)
2591 {
2592 ComPtr<IGuest> guest;
2593 rc = pConsole->COMGETTER(Guest)(guest.asOutParam());
2594 if (SUCCEEDED(rc) && !guest.isNull())
2595 {
2596 SHOW_STRING_PROP_NOT_EMPTY(guest, OSTypeId, "GuestOSType", "OS type:");
2597
2598 AdditionsRunLevelType_T guestRunLevel; /** @todo Add a runlevel-to-string (e.g. 0 = "None") method? */
2599 rc = guest->COMGETTER(AdditionsRunLevel)(&guestRunLevel);
2600 if (SUCCEEDED(rc))
2601 SHOW_ULONG_VALUE("GuestAdditionsRunLevel", "Additions run level:", (ULONG)guestRunLevel, "");
2602
2603 Bstr guestString;
2604 rc = guest->COMGETTER(AdditionsVersion)(guestString.asOutParam());
2605 if ( SUCCEEDED(rc)
2606 && !guestString.isEmpty())
2607 {
2608 ULONG uRevision;
2609 rc = guest->COMGETTER(AdditionsRevision)(&uRevision);
2610 if (FAILED(rc))
2611 uRevision = 0;
2612 RTStrPrintf(szValue, sizeof(szValue), "%ls r%u", guestString.raw(), uRevision);
2613 SHOW_UTF8_STRING("GuestAdditionsVersion", "Additions version:", szValue);
2614 }
2615
2616 if (details != VMINFO_MACHINEREADABLE)
2617 RTPrintf("\nGuest Facilities:\n\n");
2618
2619 /* Print information about known Guest Additions facilities: */
2620 SafeIfaceArray <IAdditionsFacility> collFac;
2621 CHECK_ERROR_RET(guest, COMGETTER(Facilities)(ComSafeArrayAsOutParam(collFac)), rc);
2622 LONG64 lLastUpdatedMS;
2623 char szLastUpdated[32];
2624 AdditionsFacilityStatus_T curStatus;
2625 for (size_t index = 0; index < collFac.size(); ++index)
2626 {
2627 ComPtr<IAdditionsFacility> fac = collFac[index];
2628 if (fac)
2629 {
2630 CHECK_ERROR_RET(fac, COMGETTER(Name)(guestString.asOutParam()), rc);
2631 if (!guestString.isEmpty())
2632 {
2633 CHECK_ERROR_RET(fac, COMGETTER(Status)(&curStatus), rc);
2634 CHECK_ERROR_RET(fac, COMGETTER(LastUpdated)(&lLastUpdatedMS), rc);
2635 if (details == VMINFO_MACHINEREADABLE)
2636 RTPrintf("GuestAdditionsFacility_%ls=%u,%lld\n",
2637 guestString.raw(), curStatus, lLastUpdatedMS);
2638 else
2639 {
2640 makeTimeStr(szLastUpdated, sizeof(szLastUpdated), lLastUpdatedMS);
2641 RTPrintf("Facility \"%ls\": %s (last update: %s)\n",
2642 guestString.raw(), facilityStateToName(curStatus, false /* No short naming */), szLastUpdated);
2643 }
2644 }
2645 else
2646 AssertMsgFailed(("Facility with undefined name retrieved!\n"));
2647 }
2648 else
2649 AssertMsgFailed(("Invalid facility returned!\n"));
2650 }
2651 if (!collFac.size() && details != VMINFO_MACHINEREADABLE)
2652 RTPrintf("No active facilities.\n");
2653 }
2654 }
2655
2656 if (details != VMINFO_MACHINEREADABLE)
2657 RTPrintf("\n");
2658
2659 /*
2660 * snapshots
2661 */
2662 ComPtr<ISnapshot> snapshot;
2663 rc = machine->FindSnapshot(Bstr().raw(), snapshot.asOutParam());
2664 if (SUCCEEDED(rc) && snapshot)
2665 {
2666 ComPtr<ISnapshot> currentSnapshot;
2667 rc = machine->COMGETTER(CurrentSnapshot)(currentSnapshot.asOutParam());
2668 if (SUCCEEDED(rc))
2669 {
2670 if (details != VMINFO_MACHINEREADABLE)
2671 RTPrintf("Snapshots:\n\n");
2672 showSnapshots(snapshot, currentSnapshot, details);
2673 }
2674 }
2675
2676 if (details != VMINFO_MACHINEREADABLE)
2677 RTPrintf("\n");
2678 return S_OK;
2679}
2680
2681#if defined(_MSC_VER)
2682# pragma optimize("", on)
2683# pragma warning(pop)
2684#endif
2685
2686static const RTGETOPTDEF g_aShowVMInfoOptions[] =
2687{
2688 { "--details", 'D', RTGETOPT_REQ_NOTHING },
2689 { "-details", 'D', RTGETOPT_REQ_NOTHING }, // deprecated
2690 { "--machinereadable", 'M', RTGETOPT_REQ_NOTHING },
2691 { "-machinereadable", 'M', RTGETOPT_REQ_NOTHING }, // deprecated
2692 { "--log", 'l', RTGETOPT_REQ_UINT32 },
2693};
2694
2695RTEXITCODE handleShowVMInfo(HandlerArg *a)
2696{
2697 HRESULT rc;
2698 const char *VMNameOrUuid = NULL;
2699 bool fLog = false;
2700 uint32_t uLogIdx = 0;
2701 bool fDetails = false;
2702 bool fMachinereadable = false;
2703
2704 int c;
2705 RTGETOPTUNION ValueUnion;
2706 RTGETOPTSTATE GetState;
2707 // start at 0 because main() has hacked both the argc and argv given to us
2708 RTGetOptInit(&GetState, a->argc, a->argv, g_aShowVMInfoOptions, RT_ELEMENTS(g_aShowVMInfoOptions),
2709 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
2710 while ((c = RTGetOpt(&GetState, &ValueUnion)))
2711 {
2712 switch (c)
2713 {
2714 case 'D': // --details
2715 fDetails = true;
2716 break;
2717
2718 case 'M': // --machinereadable
2719 fMachinereadable = true;
2720 break;
2721
2722 case 'l': // --log
2723 fLog = true;
2724 uLogIdx = ValueUnion.u32;
2725 break;
2726
2727 case VINF_GETOPT_NOT_OPTION:
2728 if (!VMNameOrUuid)
2729 VMNameOrUuid = ValueUnion.psz;
2730 else
2731 return errorSyntax(USAGE_SHOWVMINFO, "Invalid parameter '%s'", ValueUnion.psz);
2732 break;
2733
2734 default:
2735 return errorGetOpt(USAGE_SHOWVMINFO, c, &ValueUnion);
2736 }
2737 }
2738
2739 /* check for required options */
2740 if (!VMNameOrUuid)
2741 return errorSyntax(USAGE_SHOWVMINFO, "VM name or UUID required");
2742
2743 /* try to find the given machine */
2744 ComPtr<IMachine> machine;
2745 CHECK_ERROR(a->virtualBox, FindMachine(Bstr(VMNameOrUuid).raw(),
2746 machine.asOutParam()));
2747 if (FAILED(rc))
2748 return RTEXITCODE_FAILURE;
2749
2750 /* Printing the log is exclusive. */
2751 if (fLog && (fMachinereadable || fDetails))
2752 return errorSyntax(USAGE_SHOWVMINFO, "Option --log is exclusive");
2753
2754 if (fLog)
2755 {
2756 ULONG64 uOffset = 0;
2757 SafeArray<BYTE> aLogData;
2758 size_t cbLogData;
2759 while (true)
2760 {
2761 /* Reset the array */
2762 aLogData.setNull();
2763 /* Fetch a chunk of the log file */
2764 CHECK_ERROR_BREAK(machine, ReadLog(uLogIdx, uOffset, _1M,
2765 ComSafeArrayAsOutParam(aLogData)));
2766 cbLogData = aLogData.size();
2767 if (cbLogData == 0)
2768 break;
2769 /* aLogData has a platform dependent line ending, standardize on
2770 * Unix style, as RTStrmWrite does the LF -> CR/LF replacement on
2771 * Windows. Otherwise we end up with CR/CR/LF on Windows. */
2772 size_t cbLogDataPrint = cbLogData;
2773 for (BYTE *s = aLogData.raw(), *d = s;
2774 s - aLogData.raw() < (ssize_t)cbLogData;
2775 s++, d++)
2776 {
2777 if (*s == '\r')
2778 {
2779 /* skip over CR, adjust destination */
2780 d--;
2781 cbLogDataPrint--;
2782 }
2783 else if (s != d)
2784 *d = *s;
2785 }
2786 RTStrmWrite(g_pStdOut, aLogData.raw(), cbLogDataPrint);
2787 uOffset += cbLogData;
2788 }
2789 }
2790 else
2791 {
2792 /* 2nd option can be -details or -argdump */
2793 VMINFO_DETAILS details = VMINFO_NONE;
2794 if (fMachinereadable)
2795 details = VMINFO_MACHINEREADABLE;
2796 else if (fDetails)
2797 details = VMINFO_FULL;
2798 else
2799 details = VMINFO_STANDARD;
2800
2801 /* open an existing session for the VM */
2802 rc = machine->LockMachine(a->session, LockType_Shared);
2803 if (SUCCEEDED(rc))
2804 /* get the session machine */
2805 rc = a->session->COMGETTER(Machine)(machine.asOutParam());
2806
2807 rc = showVMInfo(a->virtualBox, machine, a->session, details);
2808
2809 a->session->UnlockMachine();
2810 }
2811
2812 return SUCCEEDED(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
2813}
2814
2815#endif /* !VBOX_ONLY_DOCS */
2816/* vi: set tabstop=4 shiftwidth=4 expandtab: */
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