VirtualBox

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

Last change on this file since 91483 was 91416, checked in by vboxsync, 3 years ago

Devices: bugref:9932 DrvVMNet and host-only network initial implementation

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