VirtualBox

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

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

VBoxManage: move getMaxNics() to VBoxManageUtils.cpp. bugref:9966.

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