VirtualBox

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

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

VBoxManage/showvminfo: Fix forgotten change in r120461, and catch this in the future with Assert.

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

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