VirtualBox

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

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

AMD IOMMU: bugref:9654 Main/API: AMD IOMMU support.

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