VirtualBox

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

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

Main: bugref:1909: Added translation marks around messages of VBoxManage output

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

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