VirtualBox

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

Last change on this file since 92124 was 92107, checked in by vboxsync, 3 years ago

VBoxManage/showvminfo: 'VBoxManage showvminfo VM' reports "unknown" as
the 'Storage Controller Type' for NVMe and VirtioSCSI.

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