VirtualBox

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

最後變更 在這個檔案從91326是 91326,由 vboxsync 提交於 3 年 前

Main/NvramStore,FE/VBoxManage: Allow multiple NVRAM states (UEFI,TPM,etc.) to exist for a VM and and manage them in a central place. This allows to collect them in a single tar archive and provide a single interface to get access to the individual states (work in progress), bugref:10098

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 117.7 KB
 
1/* $Id: VBoxManageInfo.cpp 91326 2021-09-22 15:10:38Z 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.alldomusa.eu.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 ComPtr<INvramStore> nvramStore;
880 CHECK_ERROR2I_RET(machine, COMGETTER(NonVolatileStore)(nvramStore.asOutParam()), hrcCheck);
881
882 BIOSBootMenuMode_T bootMenuMode;
883 CHECK_ERROR2I_RET(biosSettings, COMGETTER(BootMenuMode)(&bootMenuMode), hrcCheck);
884 const char *pszBootMenu;
885 switch (bootMenuMode)
886 {
887 case BIOSBootMenuMode_Disabled:
888 pszBootMenu = "disabled";
889 break;
890 case BIOSBootMenuMode_MenuOnly:
891 if (details == VMINFO_MACHINEREADABLE)
892 pszBootMenu = "menuonly";
893 else
894 pszBootMenu = "menu only";
895 break;
896 default:
897 if (details == VMINFO_MACHINEREADABLE)
898 pszBootMenu = "messageandmenu";
899 else
900 pszBootMenu = "message and menu";
901 }
902 SHOW_UTF8_STRING("bootmenu", "Boot menu mode:", pszBootMenu);
903
904 ComPtr<ISystemProperties> systemProperties;
905 CHECK_ERROR2I_RET(pVirtualBox, COMGETTER(SystemProperties)(systemProperties.asOutParam()), hrcCheck);
906 ULONG maxBootPosition = 0;
907 CHECK_ERROR2I_RET(systemProperties, COMGETTER(MaxBootPosition)(&maxBootPosition), hrcCheck);
908 for (ULONG i = 1; i <= maxBootPosition; i++)
909 {
910 DeviceType_T bootOrder;
911 CHECK_ERROR2I_RET(machine, GetBootOrder(i, &bootOrder), hrcCheck);
912 const char *pszDevice;
913 if (bootOrder == DeviceType_Floppy)
914 pszDevice = details == VMINFO_MACHINEREADABLE ? "floppy" : "Floppy";
915 else if (bootOrder == DeviceType_DVD)
916 pszDevice = details == VMINFO_MACHINEREADABLE ? "dvd" : "DVD";
917 else if (bootOrder == DeviceType_HardDisk)
918 pszDevice = details == VMINFO_MACHINEREADABLE ? "disk" : "HardDisk";
919 else if (bootOrder == DeviceType_Network)
920 pszDevice = details == VMINFO_MACHINEREADABLE ? "net" : "Network";
921 else if (bootOrder == DeviceType_USB)
922 pszDevice = details == VMINFO_MACHINEREADABLE ? "usb" : "USB";
923 else if (bootOrder == DeviceType_SharedFolder)
924 pszDevice = details == VMINFO_MACHINEREADABLE ? "sharedfolder" : "Shared Folder";
925 else
926 pszDevice = details == VMINFO_MACHINEREADABLE ? "none" : "Not Assigned";
927 SHOW_UTF8_STRING(FmtNm(szNm, "boot%u", i), FmtNm(szNm, "Boot Device %u:", i), pszDevice);
928 }
929
930 SHOW_BOOLEAN_PROP(biosSettings, ACPIEnabled, "acpi", "ACPI:");
931 SHOW_BOOLEAN_PROP(biosSettings, IOAPICEnabled, "ioapic", "IOAPIC:");
932
933 APICMode_T apicMode;
934 CHECK_ERROR2I_RET(biosSettings, COMGETTER(APICMode)(&apicMode), hrcCheck);
935 const char *pszAPIC;
936 switch (apicMode)
937 {
938 case APICMode_Disabled:
939 pszAPIC = "disabled";
940 break;
941 case APICMode_APIC:
942 default:
943 if (details == VMINFO_MACHINEREADABLE)
944 pszAPIC = "apic";
945 else
946 pszAPIC = "APIC";
947 break;
948 case APICMode_X2APIC:
949 if (details == VMINFO_MACHINEREADABLE)
950 pszAPIC = "x2apic";
951 else
952 pszAPIC = "x2APIC";
953 break;
954 }
955 SHOW_UTF8_STRING("biosapic", "BIOS APIC mode:", pszAPIC);
956
957 SHOW_LONG64_PROP(biosSettings, TimeOffset, "biossystemtimeoffset", "Time offset:", "ms");
958 Bstr bstrNVRAMFile;
959 CHECK_ERROR2I_RET(nvramStore, COMGETTER(NonVolatileStorageFile)(bstrNVRAMFile.asOutParam()), hrcCheck);
960 if (bstrNVRAMFile.isNotEmpty())
961 SHOW_BSTR_STRING("BIOS NVRAM File", "BIOS NVRAM File:", bstrNVRAMFile);
962 SHOW_BOOLEAN_PROP_EX(machine, RTCUseUTC, "rtcuseutc", "RTC:", "UTC", "local time");
963 SHOW_BOOLEAN_METHOD(machine, GetHWVirtExProperty(HWVirtExPropertyType_Enabled, &f), "hwvirtex", "Hardware Virtualization:");
964 SHOW_BOOLEAN_METHOD(machine, GetHWVirtExProperty(HWVirtExPropertyType_NestedPaging, &f),"nestedpaging", "Nested Paging:");
965 SHOW_BOOLEAN_METHOD(machine, GetHWVirtExProperty(HWVirtExPropertyType_LargePages, &f), "largepages", "Large Pages:");
966 SHOW_BOOLEAN_METHOD(machine, GetHWVirtExProperty(HWVirtExPropertyType_VPID, &f), "vtxvpid", "VT-x VPID:");
967 SHOW_BOOLEAN_METHOD(machine, GetHWVirtExProperty(HWVirtExPropertyType_UnrestrictedExecution, &f), "vtxux", "VT-x Unrestricted Exec.:");
968 SHOW_BOOLEAN_METHOD(machine, GetHWVirtExProperty(HWVirtExPropertyType_VirtVmsaveVmload, &f), "virtvmsavevmload", "AMD-V Virt. Vmsave/Vmload:");
969
970#ifdef VBOX_WITH_IOMMU_AMD
971 IommuType_T iommuType;
972 CHECK_ERROR2I_RET(machine, COMGETTER(IommuType)(&iommuType), hrcCheck);
973 const char *pszIommuType = iommuTypeToString(iommuType, details);
974 SHOW_UTF8_STRING("iommu", "IOMMU:", pszIommuType);
975#endif
976
977 ParavirtProvider_T paravirtProvider;
978 CHECK_ERROR2I_RET(machine, COMGETTER(ParavirtProvider)(&paravirtProvider), hrcCheck);
979 const char *pszParavirtProvider = paravirtProviderToString(paravirtProvider, details);
980 SHOW_UTF8_STRING("paravirtprovider", "Paravirt. Provider:", pszParavirtProvider);
981
982 ParavirtProvider_T effParavirtProvider;
983 CHECK_ERROR2I_RET(machine, GetEffectiveParavirtProvider(&effParavirtProvider), hrcCheck);
984 const char *pszEffParavirtProvider = paravirtProviderToString(effParavirtProvider, details);
985 SHOW_UTF8_STRING("effparavirtprovider", "Effective Paravirt. Prov.:", pszEffParavirtProvider);
986
987 Bstr paravirtDebug;
988 CHECK_ERROR2I_RET(machine, COMGETTER(ParavirtDebug)(paravirtDebug.asOutParam()), hrcCheck);
989 if (paravirtDebug.isNotEmpty())
990 SHOW_BSTR_STRING("paravirtdebug", "Paravirt. Debug:", paravirtDebug);
991
992 MachineState_T machineState;
993 CHECK_ERROR2I_RET(machine, COMGETTER(State)(&machineState), hrcCheck);
994 const char *pszState = machineStateToName(machineState, details == VMINFO_MACHINEREADABLE /*=fShort*/);
995
996 LONG64 stateSince;
997 machine->COMGETTER(LastStateChange)(&stateSince);
998 RTTIMESPEC timeSpec;
999 RTTimeSpecSetMilli(&timeSpec, stateSince);
1000 char pszTime[30] = {0};
1001 RTTimeSpecToString(&timeSpec, pszTime, sizeof(pszTime));
1002 if (details == VMINFO_MACHINEREADABLE)
1003 {
1004 RTPrintf("VMState=\"%s\"\n", pszState);
1005 RTPrintf("VMStateChangeTime=\"%s\"\n", pszTime);
1006
1007 Bstr stateFile;
1008 machine->COMGETTER(StateFilePath)(stateFile.asOutParam());
1009 if (!stateFile.isEmpty())
1010 RTPrintf("VMStateFile=\"%ls\"\n", stateFile.raw());
1011 }
1012 else
1013 RTPrintf("%-28s %s (since %s)\n", "State:", pszState, pszTime);
1014
1015 GraphicsControllerType_T enmGraphics;
1016 rc = pGraphicsAdapter->COMGETTER(GraphicsControllerType)(&enmGraphics);
1017 if (SUCCEEDED(rc))
1018 {
1019 const char *pszCtrl = "Unknown";
1020 switch (enmGraphics)
1021 {
1022 case GraphicsControllerType_Null:
1023 if (details == VMINFO_MACHINEREADABLE)
1024 pszCtrl = "null";
1025 else
1026 pszCtrl = "Null";
1027 break;
1028 case GraphicsControllerType_VBoxVGA:
1029 if (details == VMINFO_MACHINEREADABLE)
1030 pszCtrl = "vboxvga";
1031 else
1032 pszCtrl = "VBoxVGA";
1033 break;
1034 case GraphicsControllerType_VMSVGA:
1035 if (details == VMINFO_MACHINEREADABLE)
1036 pszCtrl = "vmsvga";
1037 else
1038 pszCtrl = "VMSVGA";
1039 break;
1040 case GraphicsControllerType_VBoxSVGA:
1041 if (details == VMINFO_MACHINEREADABLE)
1042 pszCtrl = "vboxsvga";
1043 else
1044 pszCtrl = "VBoxSVGA";
1045 break;
1046 default:
1047 if (details == VMINFO_MACHINEREADABLE)
1048 pszCtrl = "unknown";
1049 break;
1050 }
1051
1052 if (details == VMINFO_MACHINEREADABLE)
1053 RTPrintf("graphicscontroller=\"%s\"\n", pszCtrl);
1054 else
1055 RTPrintf("%-28s %s\n", "Graphics Controller:", pszCtrl);
1056 }
1057
1058 SHOW_ULONG_PROP(pGraphicsAdapter, MonitorCount, "monitorcount", "Monitor count:", "");
1059 SHOW_BOOLEAN_PROP(pGraphicsAdapter, Accelerate3DEnabled, "accelerate3d", "3D Acceleration:");
1060#ifdef VBOX_WITH_VIDEOHWACCEL
1061 SHOW_BOOLEAN_PROP(pGraphicsAdapter, Accelerate2DVideoEnabled, "accelerate2dvideo", "2D Video Acceleration:");
1062#endif
1063 SHOW_BOOLEAN_PROP( machine, TeleporterEnabled, "teleporterenabled", "Teleporter Enabled:");
1064 SHOW_ULONG_PROP( machine, TeleporterPort, "teleporterport", "Teleporter Port:", "");
1065 SHOW_STRING_PROP( machine, TeleporterAddress, "teleporteraddress", "Teleporter Address:");
1066 SHOW_STRING_PROP( machine, TeleporterPassword, "teleporterpassword", "Teleporter Password:");
1067 SHOW_BOOLEAN_PROP( machine, TracingEnabled, "tracing-enabled", "Tracing Enabled:");
1068 SHOW_BOOLEAN_PROP( machine, AllowTracingToAccessVM, "tracing-allow-vm-access", "Allow Tracing to Access VM:");
1069 SHOW_STRING_PROP( machine, TracingConfig, "tracing-config", "Tracing Configuration:");
1070 SHOW_BOOLEAN_PROP( machine, AutostartEnabled, "autostart-enabled", "Autostart Enabled:");
1071 SHOW_ULONG_PROP( machine, AutostartDelay, "autostart-delay", "Autostart Delay:", "");
1072 SHOW_STRING_PROP( machine, DefaultFrontend, "defaultfrontend", "Default Frontend:");
1073
1074 VMProcPriority_T enmVMProcPriority;
1075 CHECK_ERROR2I_RET(machine, COMGETTER(VMProcessPriority)(&enmVMProcPriority), hrcCheck);
1076 const char *pszVMProcPriority;
1077 switch (enmVMProcPriority)
1078 {
1079 case VMProcPriority_Flat:
1080 pszVMProcPriority = "flat";
1081 break;
1082 case VMProcPriority_Low:
1083 pszVMProcPriority = "low";
1084 break;
1085 case VMProcPriority_Normal:
1086 pszVMProcPriority = "normal";
1087 break;
1088 case VMProcPriority_High:
1089 pszVMProcPriority = "high";
1090 break;
1091 default:
1092 pszVMProcPriority = "default";
1093 break;
1094 }
1095 SHOW_UTF8_STRING("vmprocpriority", "VM process priority:", pszVMProcPriority);
1096
1097/** @todo Convert the remainder of the function to SHOW_XXX macros and add error
1098 * checking where missing. */
1099 /*
1100 * Storage Controllers and their attached Mediums.
1101 */
1102 com::SafeIfaceArray<IStorageController> storageCtls;
1103 CHECK_ERROR(machine, COMGETTER(StorageControllers)(ComSafeArrayAsOutParam(storageCtls)));
1104 for (size_t i = 0; i < storageCtls.size(); ++ i)
1105 {
1106 ComPtr<IStorageController> storageCtl = storageCtls[i];
1107 StorageControllerType_T enmCtlType = StorageControllerType_Null;
1108 const char *pszCtl = NULL;
1109 ULONG ulValue = 0;
1110 BOOL fBootable = FALSE;
1111 Bstr storageCtlName;
1112
1113 storageCtl->COMGETTER(Name)(storageCtlName.asOutParam());
1114 if (details == VMINFO_MACHINEREADABLE)
1115 RTPrintf("storagecontrollername%u=\"%ls\"\n", i, storageCtlName.raw());
1116 else
1117 RTPrintf("Storage Controller Name (%u): %ls\n", i, storageCtlName.raw());
1118
1119 storageCtl->COMGETTER(ControllerType)(&enmCtlType);
1120 switch (enmCtlType)
1121 {
1122 case StorageControllerType_LsiLogic:
1123 pszCtl = "LsiLogic";
1124 break;
1125 case StorageControllerType_LsiLogicSas:
1126 pszCtl = "LsiLogicSas";
1127 break;
1128 case StorageControllerType_BusLogic:
1129 pszCtl = "BusLogic";
1130 break;
1131 case StorageControllerType_IntelAhci:
1132 pszCtl = "IntelAhci";
1133 break;
1134 case StorageControllerType_PIIX3:
1135 pszCtl = "PIIX3";
1136 break;
1137 case StorageControllerType_PIIX4:
1138 pszCtl = "PIIX4";
1139 break;
1140 case StorageControllerType_ICH6:
1141 pszCtl = "ICH6";
1142 break;
1143 case StorageControllerType_I82078:
1144 pszCtl = "I82078";
1145 break;
1146 case StorageControllerType_USB:
1147 pszCtl = "USB";
1148 break;
1149
1150 default:
1151 pszCtl = "unknown";
1152 }
1153 if (details == VMINFO_MACHINEREADABLE)
1154 RTPrintf("storagecontrollertype%u=\"%s\"\n", i, pszCtl);
1155 else
1156 RTPrintf("Storage Controller Type (%u): %s\n", i, pszCtl);
1157
1158 storageCtl->COMGETTER(Instance)(&ulValue);
1159 if (details == VMINFO_MACHINEREADABLE)
1160 RTPrintf("storagecontrollerinstance%u=\"%lu\"\n", i, ulValue);
1161 else
1162 RTPrintf("Storage Controller Instance Number (%u): %lu\n", i, ulValue);
1163
1164 storageCtl->COMGETTER(MaxPortCount)(&ulValue);
1165 if (details == VMINFO_MACHINEREADABLE)
1166 RTPrintf("storagecontrollermaxportcount%u=\"%lu\"\n", i, ulValue);
1167 else
1168 RTPrintf("Storage Controller Max Port Count (%u): %lu\n", i, ulValue);
1169
1170 storageCtl->COMGETTER(PortCount)(&ulValue);
1171 if (details == VMINFO_MACHINEREADABLE)
1172 RTPrintf("storagecontrollerportcount%u=\"%lu\"\n", i, ulValue);
1173 else
1174 RTPrintf("Storage Controller Port Count (%u): %lu\n", i, ulValue);
1175
1176 storageCtl->COMGETTER(Bootable)(&fBootable);
1177 if (details == VMINFO_MACHINEREADABLE)
1178 RTPrintf("storagecontrollerbootable%u=\"%s\"\n", i, fBootable ? "on" : "off");
1179 else
1180 RTPrintf("Storage Controller Bootable (%u): %s\n", i, fBootable ? "on" : "off");
1181 }
1182
1183 for (size_t j = 0; j < storageCtls.size(); ++ j)
1184 {
1185 ComPtr<IStorageController> storageCtl = storageCtls[j];
1186 ComPtr<IMedium> medium;
1187 Bstr storageCtlName;
1188 Bstr filePath;
1189 ULONG cDevices;
1190 ULONG cPorts;
1191
1192 storageCtl->COMGETTER(Name)(storageCtlName.asOutParam());
1193 storageCtl->COMGETTER(MaxDevicesPerPortCount)(&cDevices);
1194 storageCtl->COMGETTER(PortCount)(&cPorts);
1195
1196 for (ULONG i = 0; i < cPorts; ++ i)
1197 {
1198 for (ULONG k = 0; k < cDevices; ++ k)
1199 {
1200 ComPtr<IMediumAttachment> mediumAttach;
1201 machine->GetMediumAttachment(storageCtlName.raw(),
1202 i, k,
1203 mediumAttach.asOutParam());
1204 BOOL fIsEjected = FALSE;
1205 BOOL fTempEject = FALSE;
1206 DeviceType_T devType = DeviceType_Null;
1207 if (mediumAttach)
1208 {
1209 mediumAttach->COMGETTER(TemporaryEject)(&fTempEject);
1210 mediumAttach->COMGETTER(IsEjected)(&fIsEjected);
1211 mediumAttach->COMGETTER(Type)(&devType);
1212 }
1213 rc = machine->GetMedium(storageCtlName.raw(), i, k,
1214 medium.asOutParam());
1215 if (SUCCEEDED(rc) && medium)
1216 {
1217 BOOL fPassthrough = FALSE;
1218
1219 if (mediumAttach)
1220 mediumAttach->COMGETTER(Passthrough)(&fPassthrough);
1221
1222 medium->COMGETTER(Location)(filePath.asOutParam());
1223 Bstr uuid;
1224 medium->COMGETTER(Id)(uuid.asOutParam());
1225
1226 if (details == VMINFO_MACHINEREADABLE)
1227 {
1228 RTPrintf("\"%ls-%d-%d\"=\"%ls\"\n", storageCtlName.raw(),
1229 i, k, filePath.raw());
1230 RTPrintf("\"%ls-ImageUUID-%d-%d\"=\"%s\"\n",
1231 storageCtlName.raw(), i, k, Utf8Str(uuid).c_str());
1232 if (fPassthrough)
1233 RTPrintf("\"%ls-dvdpassthrough\"=\"%s\"\n", storageCtlName.raw(),
1234 fPassthrough ? "on" : "off");
1235 if (devType == DeviceType_DVD)
1236 {
1237 RTPrintf("\"%ls-tempeject\"=\"%s\"\n", storageCtlName.raw(),
1238 fTempEject ? "on" : "off");
1239 RTPrintf("\"%ls-IsEjected\"=\"%s\"\n", storageCtlName.raw(),
1240 fIsEjected ? "on" : "off");
1241 }
1242 }
1243 else
1244 {
1245 RTPrintf("%ls (%d, %d): %ls (UUID: %s)",
1246 storageCtlName.raw(), i, k, filePath.raw(),
1247 Utf8Str(uuid).c_str());
1248 if (fPassthrough)
1249 RTPrintf(" (passthrough enabled)");
1250 if (fTempEject)
1251 RTPrintf(" (temp eject)");
1252 if (fIsEjected)
1253 RTPrintf(" (ejected)");
1254 RTPrintf("\n");
1255 }
1256 }
1257 else if (SUCCEEDED(rc))
1258 {
1259 if (details == VMINFO_MACHINEREADABLE)
1260 {
1261 RTPrintf("\"%ls-%d-%d\"=\"emptydrive\"\n", storageCtlName.raw(), i, k);
1262 if (devType == DeviceType_DVD)
1263 RTPrintf("\"%ls-IsEjected\"=\"%s\"\n", storageCtlName.raw(),
1264 fIsEjected ? "on" : "off");
1265 }
1266 else
1267 {
1268 RTPrintf("%ls (%d, %d): Empty", storageCtlName.raw(), i, k);
1269 if (fTempEject)
1270 RTPrintf(" (temp eject)");
1271 if (fIsEjected)
1272 RTPrintf(" (ejected)");
1273 RTPrintf("\n");
1274 }
1275 }
1276 else
1277 {
1278 if (details == VMINFO_MACHINEREADABLE)
1279 RTPrintf("\"%ls-%d-%d\"=\"none\"\n", storageCtlName.raw(), i, k);
1280 }
1281 }
1282 }
1283 }
1284
1285 /* get the maximum amount of NICS */
1286 ULONG maxNICs = getMaxNics(pVirtualBox, machine);
1287
1288 for (ULONG currentNIC = 0; currentNIC < maxNICs; currentNIC++)
1289 {
1290 ComPtr<INetworkAdapter> nic;
1291 rc = machine->GetNetworkAdapter(currentNIC, nic.asOutParam());
1292 if (SUCCEEDED(rc) && nic)
1293 {
1294 FmtNm(szNm, details == VMINFO_MACHINEREADABLE ? "nic%u" : "NIC %u:", currentNIC + 1);
1295
1296 BOOL fEnabled;
1297 nic->COMGETTER(Enabled)(&fEnabled);
1298 if (!fEnabled)
1299 {
1300 if (details == VMINFO_MACHINEREADABLE)
1301 RTPrintf("%s=\"none\"\n", szNm);
1302 else
1303 RTPrintf("%-28s disabled\n", szNm);
1304 }
1305 else
1306 {
1307 Bstr strMACAddress;
1308 nic->COMGETTER(MACAddress)(strMACAddress.asOutParam());
1309 Utf8Str strAttachment;
1310 Utf8Str strNatSettings;
1311 Utf8Str strNatForwardings;
1312 NetworkAttachmentType_T attachment;
1313 nic->COMGETTER(AttachmentType)(&attachment);
1314 switch (attachment)
1315 {
1316 case NetworkAttachmentType_Null:
1317 if (details == VMINFO_MACHINEREADABLE)
1318 strAttachment = "null";
1319 else
1320 strAttachment = "none";
1321 break;
1322
1323 case NetworkAttachmentType_NAT:
1324 {
1325 Bstr strNetwork;
1326 ComPtr<INATEngine> engine;
1327 nic->COMGETTER(NATEngine)(engine.asOutParam());
1328 engine->COMGETTER(Network)(strNetwork.asOutParam());
1329 com::SafeArray<BSTR> forwardings;
1330 engine->COMGETTER(Redirects)(ComSafeArrayAsOutParam(forwardings));
1331 strNatForwardings = "";
1332 for (size_t i = 0; i < forwardings.size(); ++i)
1333 {
1334 bool fSkip = false;
1335 BSTR r = forwardings[i];
1336 Utf8Str utf = Utf8Str(r);
1337 Utf8Str strName;
1338 Utf8Str strProto;
1339 Utf8Str strHostPort;
1340 Utf8Str strHostIP;
1341 Utf8Str strGuestPort;
1342 Utf8Str strGuestIP;
1343 size_t pos, ppos;
1344 pos = ppos = 0;
1345#define ITERATE_TO_NEXT_TERM(res, str, pos, ppos) \
1346 do { \
1347 pos = str.find(",", ppos); \
1348 if (pos == Utf8Str::npos) \
1349 { \
1350 Log(( #res " extracting from %s is failed\n", str.c_str())); \
1351 fSkip = true; \
1352 } \
1353 res = str.substr(ppos, pos - ppos); \
1354 Log2((#res " %s pos:%d, ppos:%d\n", res.c_str(), pos, ppos)); \
1355 ppos = pos + 1; \
1356 } while (0)
1357 ITERATE_TO_NEXT_TERM(strName, utf, pos, ppos);
1358 if (fSkip) continue;
1359 ITERATE_TO_NEXT_TERM(strProto, utf, pos, ppos);
1360 if (fSkip) continue;
1361 ITERATE_TO_NEXT_TERM(strHostIP, utf, pos, ppos);
1362 if (fSkip) continue;
1363 ITERATE_TO_NEXT_TERM(strHostPort, utf, pos, ppos);
1364 if (fSkip) continue;
1365 ITERATE_TO_NEXT_TERM(strGuestIP, utf, pos, ppos);
1366 if (fSkip) continue;
1367 strGuestPort = utf.substr(ppos, utf.length() - ppos);
1368#undef ITERATE_TO_NEXT_TERM
1369 switch (strProto.toUInt32())
1370 {
1371 case NATProtocol_TCP:
1372 strProto = "tcp";
1373 break;
1374 case NATProtocol_UDP:
1375 strProto = "udp";
1376 break;
1377 default:
1378 strProto = "unk";
1379 break;
1380 }
1381 if (details == VMINFO_MACHINEREADABLE)
1382 /** @todo r=bird: This probably isn't good enough wrt escaping. */
1383 strNatForwardings.printf("%sForwarding(%d)=\"%s,%s,%s,%s,%s,%s\"\n",
1384 strNatForwardings.c_str(), i, strName.c_str(), strProto.c_str(),
1385 strHostIP.c_str(), strHostPort.c_str(),
1386 strGuestIP.c_str(), strGuestPort.c_str());
1387 else
1388 strNatForwardings.printf("%sNIC %d Rule(%d): name = %s, protocol = %s, host ip = %s, host port = %s, guest ip = %s, guest port = %s\n",
1389 strNatForwardings.c_str(), currentNIC + 1, i, strName.c_str(),
1390 strProto.c_str(), strHostIP.c_str(), strHostPort.c_str(),
1391 strGuestIP.c_str(), strGuestPort.c_str());
1392 }
1393 ULONG mtu = 0;
1394 ULONG sockSnd = 0;
1395 ULONG sockRcv = 0;
1396 ULONG tcpSnd = 0;
1397 ULONG tcpRcv = 0;
1398 engine->GetNetworkSettings(&mtu, &sockSnd, &sockRcv, &tcpSnd, &tcpRcv);
1399
1400/** @todo r=klaus dnsproxy etc needs to be dumped, too */
1401 if (details == VMINFO_MACHINEREADABLE)
1402 {
1403 RTPrintf("natnet%d=\"%ls\"\n", currentNIC + 1, strNetwork.length() ? strNetwork.raw(): Bstr("nat").raw());
1404 strAttachment = "nat";
1405 strNatSettings.printf("mtu=\"%d\"\nsockSnd=\"%d\"\nsockRcv=\"%d\"\ntcpWndSnd=\"%d\"\ntcpWndRcv=\"%d\"\n",
1406 mtu, sockSnd ? sockSnd : 64, sockRcv ? sockRcv : 64, tcpSnd ? tcpSnd : 64, tcpRcv ? tcpRcv : 64);
1407 }
1408 else
1409 {
1410 strAttachment = "NAT";
1411 strNatSettings.printf("NIC %d Settings: MTU: %d, Socket (send: %d, receive: %d), TCP Window (send:%d, receive: %d)\n",
1412 currentNIC + 1, mtu, sockSnd ? sockSnd : 64, sockRcv ? sockRcv : 64, tcpSnd ? tcpSnd : 64, tcpRcv ? tcpRcv : 64);
1413 }
1414 break;
1415 }
1416
1417 case NetworkAttachmentType_Bridged:
1418 {
1419 Bstr strBridgeAdp;
1420 nic->COMGETTER(BridgedInterface)(strBridgeAdp.asOutParam());
1421 if (details == VMINFO_MACHINEREADABLE)
1422 {
1423 RTPrintf("bridgeadapter%d=\"%ls\"\n", currentNIC + 1, strBridgeAdp.raw());
1424 strAttachment = "bridged";
1425 }
1426 else
1427 strAttachment.printf("Bridged Interface '%ls'", strBridgeAdp.raw());
1428 break;
1429 }
1430
1431 case NetworkAttachmentType_Internal:
1432 {
1433 Bstr strNetwork;
1434 nic->COMGETTER(InternalNetwork)(strNetwork.asOutParam());
1435 if (details == VMINFO_MACHINEREADABLE)
1436 {
1437 RTPrintf("intnet%d=\"%ls\"\n", currentNIC + 1, strNetwork.raw());
1438 strAttachment = "intnet";
1439 }
1440 else
1441 strAttachment.printf("Internal Network '%s'", Utf8Str(strNetwork).c_str());
1442 break;
1443 }
1444
1445 case NetworkAttachmentType_HostOnly:
1446 {
1447 Bstr strHostonlyAdp;
1448 nic->COMGETTER(HostOnlyInterface)(strHostonlyAdp.asOutParam());
1449 if (details == VMINFO_MACHINEREADABLE)
1450 {
1451 RTPrintf("hostonlyadapter%d=\"%ls\"\n", currentNIC + 1, strHostonlyAdp.raw());
1452 strAttachment = "hostonly";
1453 }
1454 else
1455 strAttachment.printf("Host-only Interface '%ls'", strHostonlyAdp.raw());
1456 break;
1457 }
1458
1459 case NetworkAttachmentType_Generic:
1460 {
1461 Bstr strGenericDriver;
1462 nic->COMGETTER(GenericDriver)(strGenericDriver.asOutParam());
1463 if (details == VMINFO_MACHINEREADABLE)
1464 {
1465 RTPrintf("generic%d=\"%ls\"\n", currentNIC + 1, strGenericDriver.raw());
1466 strAttachment = "Generic";
1467 }
1468 else
1469 {
1470 strAttachment.printf("Generic '%ls'", strGenericDriver.raw());
1471
1472 // show the generic properties
1473 com::SafeArray<BSTR> aProperties;
1474 com::SafeArray<BSTR> aValues;
1475 rc = nic->GetProperties(NULL,
1476 ComSafeArrayAsOutParam(aProperties),
1477 ComSafeArrayAsOutParam(aValues));
1478 if (SUCCEEDED(rc))
1479 {
1480 strAttachment += " { ";
1481 for (unsigned i = 0; i < aProperties.size(); ++i)
1482 strAttachment.appendPrintf(!i ? "%ls='%ls'" : ", %ls='%ls'", aProperties[i], aValues[i]);
1483 strAttachment += " }";
1484 }
1485 }
1486 break;
1487 }
1488
1489 case NetworkAttachmentType_NATNetwork:
1490 {
1491 Bstr strNetwork;
1492 nic->COMGETTER(NATNetwork)(strNetwork.asOutParam());
1493 if (details == VMINFO_MACHINEREADABLE)
1494 {
1495 RTPrintf("nat-network%d=\"%ls\"\n", currentNIC + 1, strNetwork.raw());
1496 strAttachment = "natnetwork";
1497 }
1498 else
1499 strAttachment.printf("NAT Network '%s'", Utf8Str(strNetwork).c_str());
1500 break;
1501 }
1502
1503#ifdef VBOX_WITH_CLOUD_NET
1504 case NetworkAttachmentType_Cloud:
1505 {
1506 Bstr strNetwork;
1507 nic->COMGETTER(CloudNetwork)(strNetwork.asOutParam());
1508 if (details == VMINFO_MACHINEREADABLE)
1509 {
1510 RTPrintf("cloud-network%d=\"%ls\"\n", currentNIC + 1, strNetwork.raw());
1511 strAttachment = "cloudnetwork";
1512 }
1513 else
1514 strAttachment.printf("Cloud Network '%s'", Utf8Str(strNetwork).c_str());
1515 break;
1516 }
1517#endif /* VBOX_WITH_CLOUD_NET */
1518
1519 default:
1520 strAttachment = "unknown";
1521 break;
1522 }
1523
1524 /* cable connected */
1525 BOOL fConnected;
1526 nic->COMGETTER(CableConnected)(&fConnected);
1527
1528 /* promisc policy */
1529 NetworkAdapterPromiscModePolicy_T enmPromiscModePolicy;
1530 CHECK_ERROR2I_RET(nic, COMGETTER(PromiscModePolicy)(&enmPromiscModePolicy), hrcCheck);
1531 const char *pszPromiscuousGuestPolicy;
1532 switch (enmPromiscModePolicy)
1533 {
1534 case NetworkAdapterPromiscModePolicy_Deny: pszPromiscuousGuestPolicy = "deny"; break;
1535 case NetworkAdapterPromiscModePolicy_AllowNetwork: pszPromiscuousGuestPolicy = "allow-vms"; break;
1536 case NetworkAdapterPromiscModePolicy_AllowAll: pszPromiscuousGuestPolicy = "allow-all"; break;
1537 default: AssertFailedReturn(E_INVALIDARG);
1538 }
1539
1540 /* trace stuff */
1541 BOOL fTraceEnabled;
1542 nic->COMGETTER(TraceEnabled)(&fTraceEnabled);
1543 Bstr traceFile;
1544 nic->COMGETTER(TraceFile)(traceFile.asOutParam());
1545
1546 /* NIC type */
1547 NetworkAdapterType_T NICType;
1548 nic->COMGETTER(AdapterType)(&NICType);
1549 const char *pszNICType;
1550 switch (NICType)
1551 {
1552 case NetworkAdapterType_Am79C970A: pszNICType = "Am79C970A"; break;
1553 case NetworkAdapterType_Am79C973: pszNICType = "Am79C973"; break;
1554 case NetworkAdapterType_Am79C960: pszNICType = "Am79C960"; break;
1555#ifdef VBOX_WITH_E1000
1556 case NetworkAdapterType_I82540EM: pszNICType = "82540EM"; break;
1557 case NetworkAdapterType_I82543GC: pszNICType = "82543GC"; break;
1558 case NetworkAdapterType_I82545EM: pszNICType = "82545EM"; break;
1559#endif
1560#ifdef VBOX_WITH_VIRTIO
1561 case NetworkAdapterType_Virtio: pszNICType = "virtio"; break;
1562
1563#endif
1564#ifdef VBOX_WITH_VIRTIO_NET_1_0
1565 case NetworkAdapterType_Virtio_1_0: pszNICType = "virtio_1.0"; break;
1566#endif
1567 default: AssertFailed(); pszNICType = "unknown"; break;
1568 }
1569
1570 /* reported line speed */
1571 ULONG ulLineSpeed;
1572 nic->COMGETTER(LineSpeed)(&ulLineSpeed);
1573
1574 /* boot priority of the adapter */
1575 ULONG ulBootPriority;
1576 nic->COMGETTER(BootPriority)(&ulBootPriority);
1577
1578 /* bandwidth group */
1579 ComObjPtr<IBandwidthGroup> pBwGroup;
1580 Bstr strBwGroup;
1581 nic->COMGETTER(BandwidthGroup)(pBwGroup.asOutParam());
1582 if (!pBwGroup.isNull())
1583 pBwGroup->COMGETTER(Name)(strBwGroup.asOutParam());
1584
1585 if (details == VMINFO_MACHINEREADABLE)
1586 {
1587 RTPrintf("macaddress%d=\"%ls\"\n", currentNIC + 1, strMACAddress.raw());
1588 RTPrintf("cableconnected%d=\"%s\"\n", currentNIC + 1, fConnected ? "on" : "off");
1589 RTPrintf("nic%d=\"%s\"\n", currentNIC + 1, strAttachment.c_str());
1590 RTPrintf("nictype%d=\"%s\"\n", currentNIC + 1, pszNICType);
1591 RTPrintf("nicspeed%d=\"%d\"\n", currentNIC + 1, ulLineSpeed);
1592 }
1593 else
1594 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",
1595 szNm, strMACAddress.raw(), strAttachment.c_str(),
1596 fConnected ? "on" : "off",
1597 fTraceEnabled ? "on" : "off",
1598 traceFile.isEmpty() ? Bstr("none").raw() : traceFile.raw(),
1599 pszNICType,
1600 ulLineSpeed / 1000,
1601 (int)ulBootPriority,
1602 pszPromiscuousGuestPolicy,
1603 strBwGroup.isEmpty() ? Bstr("none").raw() : strBwGroup.raw());
1604 if (strNatSettings.length())
1605 RTPrintf(strNatSettings.c_str());
1606 if (strNatForwardings.length())
1607 RTPrintf(strNatForwardings.c_str());
1608 }
1609 }
1610 }
1611
1612 /* Pointing device information */
1613 PointingHIDType_T aPointingHID;
1614 const char *pszHID = "Unknown";
1615 const char *pszMrHID = "unknown";
1616 machine->COMGETTER(PointingHIDType)(&aPointingHID);
1617 switch (aPointingHID)
1618 {
1619 case PointingHIDType_None:
1620 pszHID = "None";
1621 pszMrHID = "none";
1622 break;
1623 case PointingHIDType_PS2Mouse:
1624 pszHID = "PS/2 Mouse";
1625 pszMrHID = "ps2mouse";
1626 break;
1627 case PointingHIDType_USBMouse:
1628 pszHID = "USB Mouse";
1629 pszMrHID = "usbmouse";
1630 break;
1631 case PointingHIDType_USBTablet:
1632 pszHID = "USB Tablet";
1633 pszMrHID = "usbtablet";
1634 break;
1635 case PointingHIDType_ComboMouse:
1636 pszHID = "USB Tablet and PS/2 Mouse";
1637 pszMrHID = "combomouse";
1638 break;
1639 case PointingHIDType_USBMultiTouch:
1640 pszHID = "USB Multi-Touch";
1641 pszMrHID = "usbmultitouch";
1642 break;
1643 default:
1644 break;
1645 }
1646 SHOW_UTF8_STRING("hidpointing", "Pointing Device:", details == VMINFO_MACHINEREADABLE ? pszMrHID : pszHID);
1647
1648 /* Keyboard device information */
1649 KeyboardHIDType_T aKeyboardHID;
1650 machine->COMGETTER(KeyboardHIDType)(&aKeyboardHID);
1651 pszHID = "Unknown";
1652 pszMrHID = "unknown";
1653 switch (aKeyboardHID)
1654 {
1655 case KeyboardHIDType_None:
1656 pszHID = "None";
1657 pszMrHID = "none";
1658 break;
1659 case KeyboardHIDType_PS2Keyboard:
1660 pszHID = "PS/2 Keyboard";
1661 pszMrHID = "ps2kbd";
1662 break;
1663 case KeyboardHIDType_USBKeyboard:
1664 pszHID = "USB Keyboard";
1665 pszMrHID = "usbkbd";
1666 break;
1667 case KeyboardHIDType_ComboKeyboard:
1668 pszHID = "USB and PS/2 Keyboard";
1669 pszMrHID = "combokbd";
1670 break;
1671 default:
1672 break;
1673 }
1674 SHOW_UTF8_STRING("hidkeyboard", "Keyboard Device:", details == VMINFO_MACHINEREADABLE ? pszMrHID : pszHID);
1675
1676 ComPtr<ISystemProperties> sysProps;
1677 pVirtualBox->COMGETTER(SystemProperties)(sysProps.asOutParam());
1678
1679 /* get the maximum amount of UARTs */
1680 ULONG maxUARTs = 0;
1681 sysProps->COMGETTER(SerialPortCount)(&maxUARTs);
1682 for (ULONG currentUART = 0; currentUART < maxUARTs; currentUART++)
1683 {
1684 ComPtr<ISerialPort> uart;
1685 rc = machine->GetSerialPort(currentUART, uart.asOutParam());
1686 if (SUCCEEDED(rc) && uart)
1687 {
1688 FmtNm(szNm, details == VMINFO_MACHINEREADABLE ? "uart%u" : "UART %u:", currentUART + 1);
1689
1690 /* show the config of this UART */
1691 BOOL fEnabled;
1692 uart->COMGETTER(Enabled)(&fEnabled);
1693 if (!fEnabled)
1694 {
1695 if (details == VMINFO_MACHINEREADABLE)
1696 RTPrintf("%s=\"off\"\n", szNm);
1697 else
1698 RTPrintf("%-28s disabled\n", szNm);
1699 }
1700 else
1701 {
1702 ULONG ulIRQ, ulIOBase;
1703 PortMode_T HostMode;
1704 Bstr path;
1705 BOOL fServer;
1706 UartType_T UartType;
1707 uart->COMGETTER(IRQ)(&ulIRQ);
1708 uart->COMGETTER(IOBase)(&ulIOBase);
1709 uart->COMGETTER(Path)(path.asOutParam());
1710 uart->COMGETTER(Server)(&fServer);
1711 uart->COMGETTER(HostMode)(&HostMode);
1712 uart->COMGETTER(UartType)(&UartType);
1713
1714 if (details == VMINFO_MACHINEREADABLE)
1715 RTPrintf("%s=\"%#06x,%d\"\n", szNm, ulIOBase, ulIRQ);
1716 else
1717 RTPrintf("%-28s I/O base: %#06x, IRQ: %d", szNm, ulIOBase, ulIRQ);
1718 switch (HostMode)
1719 {
1720 default:
1721 case PortMode_Disconnected:
1722 if (details == VMINFO_MACHINEREADABLE)
1723 RTPrintf("uartmode%d=\"disconnected\"\n", currentUART + 1);
1724 else
1725 RTPrintf(", disconnected");
1726 break;
1727 case PortMode_RawFile:
1728 if (details == VMINFO_MACHINEREADABLE)
1729 RTPrintf("uartmode%d=\"file,%ls\"\n", currentUART + 1,
1730 path.raw());
1731 else
1732 RTPrintf(", attached to raw file '%ls'\n",
1733 path.raw());
1734 break;
1735 case PortMode_TCP:
1736 if (details == VMINFO_MACHINEREADABLE)
1737 RTPrintf("uartmode%d=\"%s,%ls\"\n", currentUART + 1,
1738 fServer ? "tcpserver" : "tcpclient", path.raw());
1739 else
1740 RTPrintf(", attached to tcp (%s) '%ls'",
1741 fServer ? "server" : "client", path.raw());
1742 break;
1743 case PortMode_HostPipe:
1744 if (details == VMINFO_MACHINEREADABLE)
1745 RTPrintf("uartmode%d=\"%s,%ls\"\n", currentUART + 1,
1746 fServer ? "server" : "client", path.raw());
1747 else
1748 RTPrintf(", attached to pipe (%s) '%ls'",
1749 fServer ? "server" : "client", path.raw());
1750 break;
1751 case PortMode_HostDevice:
1752 if (details == VMINFO_MACHINEREADABLE)
1753 RTPrintf("uartmode%d=\"%ls\"\n", currentUART + 1,
1754 path.raw());
1755 else
1756 RTPrintf(", attached to device '%ls'", path.raw());
1757 break;
1758 }
1759 switch (UartType)
1760 {
1761 default:
1762 case UartType_U16450:
1763 if (details == VMINFO_MACHINEREADABLE)
1764 RTPrintf("uarttype%d=\"16450\"\n", currentUART + 1);
1765 else
1766 RTPrintf(", 16450\n");
1767 break;
1768 case UartType_U16550A:
1769 if (details == VMINFO_MACHINEREADABLE)
1770 RTPrintf("uarttype%d=\"16550A\"\n", currentUART + 1);
1771 else
1772 RTPrintf(", 16550A\n");
1773 break;
1774 case UartType_U16750:
1775 if (details == VMINFO_MACHINEREADABLE)
1776 RTPrintf("uarttype%d=\"16750\"\n", currentUART + 1);
1777 else
1778 RTPrintf(", 16750\n");
1779 break;
1780 }
1781 }
1782 }
1783 }
1784
1785 /* get the maximum amount of LPTs */
1786 ULONG maxLPTs = 0;
1787 sysProps->COMGETTER(ParallelPortCount)(&maxLPTs);
1788 for (ULONG currentLPT = 0; currentLPT < maxLPTs; currentLPT++)
1789 {
1790 ComPtr<IParallelPort> lpt;
1791 rc = machine->GetParallelPort(currentLPT, lpt.asOutParam());
1792 if (SUCCEEDED(rc) && lpt)
1793 {
1794 FmtNm(szNm, details == VMINFO_MACHINEREADABLE ? "lpt%u" : "LPT %u:", currentLPT + 1);
1795
1796 /* show the config of this LPT */
1797 BOOL fEnabled;
1798 lpt->COMGETTER(Enabled)(&fEnabled);
1799 if (!fEnabled)
1800 {
1801 if (details == VMINFO_MACHINEREADABLE)
1802 RTPrintf("%s=\"off\"\n", szNm);
1803 else
1804 RTPrintf("%-28s disabled\n", szNm);
1805 }
1806 else
1807 {
1808 ULONG ulIRQ, ulIOBase;
1809 Bstr path;
1810 lpt->COMGETTER(IRQ)(&ulIRQ);
1811 lpt->COMGETTER(IOBase)(&ulIOBase);
1812 lpt->COMGETTER(Path)(path.asOutParam());
1813
1814 if (details == VMINFO_MACHINEREADABLE)
1815 RTPrintf("%s=\"%#06x,%d\"\n", szNm, ulIOBase, ulIRQ);
1816 else
1817 RTPrintf("%-28s I/O base: %#06x, IRQ: %d", szNm, ulIOBase, ulIRQ);
1818 if (details == VMINFO_MACHINEREADABLE)
1819 RTPrintf("lptmode%d=\"%ls\"\n", currentLPT + 1, path.raw());
1820 else
1821 RTPrintf(", attached to device '%ls'\n", path.raw());
1822 }
1823 }
1824 }
1825
1826 ComPtr<IAudioAdapter> AudioAdapter;
1827 rc = machine->COMGETTER(AudioAdapter)(AudioAdapter.asOutParam());
1828 if (SUCCEEDED(rc))
1829 {
1830 const char *pszDrv = "Unknown";
1831 const char *pszCtrl = "Unknown";
1832 const char *pszCodec = "Unknown";
1833 BOOL fEnabled;
1834 rc = AudioAdapter->COMGETTER(Enabled)(&fEnabled);
1835 if (SUCCEEDED(rc) && fEnabled)
1836 {
1837 AudioDriverType_T enmDrvType;
1838 rc = AudioAdapter->COMGETTER(AudioDriver)(&enmDrvType);
1839 switch (enmDrvType)
1840 {
1841 case AudioDriverType_Null:
1842 if (details == VMINFO_MACHINEREADABLE)
1843 pszDrv = "null";
1844 else
1845 pszDrv = "Null";
1846 break;
1847 case AudioDriverType_WinMM:
1848 if (details == VMINFO_MACHINEREADABLE)
1849 pszDrv = "winmm";
1850 else
1851 pszDrv = "WINMM";
1852 break;
1853 case AudioDriverType_DirectSound:
1854 if (details == VMINFO_MACHINEREADABLE)
1855 pszDrv = "dsound";
1856 else
1857 pszDrv = "DSOUND";
1858 break;
1859 case AudioDriverType_OSS:
1860 if (details == VMINFO_MACHINEREADABLE)
1861 pszDrv = "oss";
1862 else
1863 pszDrv = "OSS";
1864 break;
1865 case AudioDriverType_ALSA:
1866 if (details == VMINFO_MACHINEREADABLE)
1867 pszDrv = "alsa";
1868 else
1869 pszDrv = "ALSA";
1870 break;
1871 case AudioDriverType_Pulse:
1872 if (details == VMINFO_MACHINEREADABLE)
1873 pszDrv = "pulse";
1874 else
1875 pszDrv = "PulseAudio";
1876 break;
1877 case AudioDriverType_CoreAudio:
1878 if (details == VMINFO_MACHINEREADABLE)
1879 pszDrv = "coreaudio";
1880 else
1881 pszDrv = "CoreAudio";
1882 break;
1883 case AudioDriverType_SolAudio:
1884 if (details == VMINFO_MACHINEREADABLE)
1885 pszDrv = "solaudio";
1886 else
1887 pszDrv = "SolAudio";
1888 break;
1889 default:
1890 if (details == VMINFO_MACHINEREADABLE)
1891 pszDrv = "unknown";
1892 break;
1893 }
1894 AudioControllerType_T enmCtrlType;
1895 rc = AudioAdapter->COMGETTER(AudioController)(&enmCtrlType);
1896 switch (enmCtrlType)
1897 {
1898 case AudioControllerType_AC97:
1899 if (details == VMINFO_MACHINEREADABLE)
1900 pszCtrl = "ac97";
1901 else
1902 pszCtrl = "AC97";
1903 break;
1904 case AudioControllerType_SB16:
1905 if (details == VMINFO_MACHINEREADABLE)
1906 pszCtrl = "sb16";
1907 else
1908 pszCtrl = "SB16";
1909 break;
1910 case AudioControllerType_HDA:
1911 if (details == VMINFO_MACHINEREADABLE)
1912 pszCtrl = "hda";
1913 else
1914 pszCtrl = "HDA";
1915 break;
1916 default:
1917 break;
1918 }
1919 AudioCodecType_T enmCodecType;
1920 rc = AudioAdapter->COMGETTER(AudioCodec)(&enmCodecType);
1921 switch (enmCodecType)
1922 {
1923 case AudioCodecType_SB16:
1924 pszCodec = "SB16";
1925 break;
1926 case AudioCodecType_STAC9700:
1927 pszCodec = "STAC9700";
1928 break;
1929 case AudioCodecType_AD1980:
1930 pszCodec = "AD1980";
1931 break;
1932 case AudioCodecType_STAC9221:
1933 pszCodec = "STAC9221";
1934 break;
1935 case AudioCodecType_Null: break; /* Shut up MSC. */
1936 default: break;
1937 }
1938 }
1939 else
1940 fEnabled = FALSE;
1941
1942 if (details == VMINFO_MACHINEREADABLE)
1943 RTPrintf("audio=\"%s\"\n", fEnabled ? pszDrv : "none");
1944 else
1945 {
1946 RTPrintf("%-28s %s", "Audio:", fEnabled ? "enabled" : "disabled");
1947 if (fEnabled)
1948 RTPrintf(" (Driver: %s, Controller: %s, Codec: %s)", pszDrv, pszCtrl, pszCodec);
1949 RTPrintf("\n");
1950 }
1951 SHOW_BOOLEAN_PROP(AudioAdapter, EnabledOut, "audio_out", "Audio playback:");
1952 SHOW_BOOLEAN_PROP(AudioAdapter, EnabledIn, "audio_in", "Audio capture:");
1953 }
1954
1955 /* Shared clipboard */
1956 {
1957 const char *psz;
1958 ClipboardMode_T enmMode = (ClipboardMode_T)0;
1959 rc = machine->COMGETTER(ClipboardMode)(&enmMode);
1960 switch (enmMode)
1961 {
1962 case ClipboardMode_Disabled:
1963 psz = "disabled";
1964 break;
1965 case ClipboardMode_HostToGuest:
1966 psz = details == VMINFO_MACHINEREADABLE ? "hosttoguest" : "HostToGuest";
1967 break;
1968 case ClipboardMode_GuestToHost:
1969 psz = details == VMINFO_MACHINEREADABLE ? "guesttohost" : "GuestToHost";
1970 break;
1971 case ClipboardMode_Bidirectional:
1972 psz = details == VMINFO_MACHINEREADABLE ? "bidirectional" : "Bidirectional";
1973 break;
1974 default:
1975 psz = details == VMINFO_MACHINEREADABLE ? "unknown" : "Unknown";
1976 break;
1977 }
1978 SHOW_UTF8_STRING("clipboard", "Clipboard Mode:", psz);
1979#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
1980 SHOW_BOOLEAN_PROP(machine, ClipboardFileTransfersEnabled, "clipboard_file_transfers", "Clipboard file transfers:");
1981#endif
1982 }
1983
1984 /* Drag and drop */
1985 {
1986 const char *psz;
1987 DnDMode_T enmMode;
1988 rc = machine->COMGETTER(DnDMode)(&enmMode);
1989 switch (enmMode)
1990 {
1991 case DnDMode_Disabled:
1992 psz = "disabled";
1993 break;
1994 case DnDMode_HostToGuest:
1995 psz = details == VMINFO_MACHINEREADABLE ? "hosttoguest" : "HostToGuest";
1996 break;
1997 case DnDMode_GuestToHost:
1998 psz = details == VMINFO_MACHINEREADABLE ? "guesttohost" : "GuestToHost";
1999 break;
2000 case DnDMode_Bidirectional:
2001 psz = details == VMINFO_MACHINEREADABLE ? "bidirectional" : "Bidirectional";
2002 break;
2003 default:
2004 psz = details == VMINFO_MACHINEREADABLE ? "unknown" : "Unknown";
2005 break;
2006 }
2007 SHOW_UTF8_STRING("draganddrop", "Drag and drop Mode:", psz);
2008 }
2009
2010 {
2011 SessionState_T sessState;
2012 rc = machine->COMGETTER(SessionState)(&sessState);
2013 if (SUCCEEDED(rc) && sessState != SessionState_Unlocked)
2014 {
2015 Bstr sessName;
2016 rc = machine->COMGETTER(SessionName)(sessName.asOutParam());
2017 if (SUCCEEDED(rc) && !sessName.isEmpty())
2018 SHOW_BSTR_STRING("SessionName", "Session name:", sessName);
2019 }
2020 }
2021
2022 if (pConsole)
2023 {
2024 do
2025 {
2026 ComPtr<IDisplay> display;
2027 rc = pConsole->COMGETTER(Display)(display.asOutParam());
2028 if (rc == E_ACCESSDENIED || display.isNull())
2029 break; /* VM not powered up */
2030 if (FAILED(rc))
2031 {
2032 com::GlueHandleComError(pConsole, "COMGETTER(Display)(display.asOutParam())", rc, __FILE__, __LINE__);
2033 return rc;
2034 }
2035 ULONG xRes, yRes, bpp;
2036 LONG xOrigin, yOrigin;
2037 GuestMonitorStatus_T monitorStatus;
2038 rc = display->GetScreenResolution(0, &xRes, &yRes, &bpp, &xOrigin, &yOrigin, &monitorStatus);
2039 if (rc == E_ACCESSDENIED)
2040 break; /* VM not powered up */
2041 if (FAILED(rc))
2042 {
2043 com::ErrorInfo info(display, COM_IIDOF(IDisplay));
2044 GluePrintErrorInfo(info);
2045 return rc;
2046 }
2047 if (details == VMINFO_MACHINEREADABLE)
2048 RTPrintf("VideoMode=\"%d,%d,%d\"@%d,%d %d\n", xRes, yRes, bpp, xOrigin, yOrigin, monitorStatus);
2049 else
2050 {
2051 const char *pszMonitorStatus = "unknown status";
2052 switch (monitorStatus)
2053 {
2054 case GuestMonitorStatus_Blank: pszMonitorStatus = "blank"; break;
2055 case GuestMonitorStatus_Enabled: pszMonitorStatus = "enabled"; break;
2056 case GuestMonitorStatus_Disabled: pszMonitorStatus = "disabled"; break;
2057 default: break;
2058 }
2059 RTPrintf("%-28s %dx%dx%d at %d,%d %s\n", "Video mode:", xRes, yRes, bpp, xOrigin, yOrigin, pszMonitorStatus);
2060 }
2061 }
2062 while (0);
2063 }
2064
2065 /*
2066 * Remote Desktop
2067 */
2068 ComPtr<IVRDEServer> vrdeServer;
2069 rc = machine->COMGETTER(VRDEServer)(vrdeServer.asOutParam());
2070 if (SUCCEEDED(rc) && vrdeServer)
2071 {
2072 BOOL fEnabled = false;
2073 vrdeServer->COMGETTER(Enabled)(&fEnabled);
2074 if (fEnabled)
2075 {
2076 LONG currentPort = -1;
2077 Bstr ports;
2078 vrdeServer->GetVRDEProperty(Bstr("TCP/Ports").raw(), ports.asOutParam());
2079 Bstr address;
2080 vrdeServer->GetVRDEProperty(Bstr("TCP/Address").raw(), address.asOutParam());
2081 BOOL fMultiCon;
2082 vrdeServer->COMGETTER(AllowMultiConnection)(&fMultiCon);
2083 BOOL fReuseCon;
2084 vrdeServer->COMGETTER(ReuseSingleConnection)(&fReuseCon);
2085 Bstr videoChannel;
2086 vrdeServer->GetVRDEProperty(Bstr("VideoChannel/Enabled").raw(), videoChannel.asOutParam());
2087 BOOL fVideoChannel = (videoChannel.compare(Bstr("true"), Bstr::CaseInsensitive)== 0)
2088 || (videoChannel == "1");
2089 Bstr videoChannelQuality;
2090 vrdeServer->GetVRDEProperty(Bstr("VideoChannel/Quality").raw(), videoChannelQuality.asOutParam());
2091 AuthType_T authType = (AuthType_T)0;
2092 const char *strAuthType;
2093 vrdeServer->COMGETTER(AuthType)(&authType);
2094 switch (authType)
2095 {
2096 case AuthType_Null:
2097 strAuthType = "null";
2098 break;
2099 case AuthType_External:
2100 strAuthType = "external";
2101 break;
2102 case AuthType_Guest:
2103 strAuthType = "guest";
2104 break;
2105 default:
2106 strAuthType = "unknown";
2107 break;
2108 }
2109 if (pConsole)
2110 {
2111 ComPtr<IVRDEServerInfo> vrdeServerInfo;
2112 CHECK_ERROR_RET(pConsole, COMGETTER(VRDEServerInfo)(vrdeServerInfo.asOutParam()), rc);
2113 if (!vrdeServerInfo.isNull())
2114 {
2115 rc = vrdeServerInfo->COMGETTER(Port)(&currentPort);
2116 if (rc == E_ACCESSDENIED)
2117 {
2118 currentPort = -1; /* VM not powered up */
2119 }
2120 else if (FAILED(rc))
2121 {
2122 com::ErrorInfo info(vrdeServerInfo, COM_IIDOF(IVRDEServerInfo));
2123 GluePrintErrorInfo(info);
2124 return rc;
2125 }
2126 }
2127 }
2128 if (details == VMINFO_MACHINEREADABLE)
2129 {
2130 RTPrintf("vrde=\"on\"\n");
2131 RTPrintf("vrdeport=%d\n", currentPort);
2132 RTPrintf("vrdeports=\"%ls\"\n", ports.raw());
2133 RTPrintf("vrdeaddress=\"%ls\"\n", address.raw());
2134 RTPrintf("vrdeauthtype=\"%s\"\n", strAuthType);
2135 RTPrintf("vrdemulticon=\"%s\"\n", fMultiCon ? "on" : "off");
2136 RTPrintf("vrdereusecon=\"%s\"\n", fReuseCon ? "on" : "off");
2137 RTPrintf("vrdevideochannel=\"%s\"\n", fVideoChannel ? "on" : "off");
2138 if (fVideoChannel)
2139 RTPrintf("vrdevideochannelquality=\"%ls\"\n", videoChannelQuality.raw());
2140 }
2141 else
2142 {
2143 if (address.isEmpty())
2144 address = "0.0.0.0";
2145 RTPrintf("%-28s enabled (Address %ls, Ports %ls, MultiConn: %s, ReuseSingleConn: %s, Authentication type: %s)\n",
2146 "VRDE:", address.raw(), ports.raw(), fMultiCon ? "on" : "off", fReuseCon ? "on" : "off", strAuthType);
2147 if (pConsole && currentPort != -1 && currentPort != 0)
2148 RTPrintf("%-28s %d\n", "VRDE port:", currentPort);
2149 if (fVideoChannel)
2150 RTPrintf("%-28s enabled (Quality %ls)\n", "Video redirection:", videoChannelQuality.raw());
2151 else
2152 RTPrintf("%-28s disabled\n", "Video redirection:");
2153 }
2154 com::SafeArray<BSTR> aProperties;
2155 if (SUCCEEDED(vrdeServer->COMGETTER(VRDEProperties)(ComSafeArrayAsOutParam(aProperties))))
2156 {
2157 unsigned i;
2158 for (i = 0; i < aProperties.size(); ++i)
2159 {
2160 Bstr value;
2161 vrdeServer->GetVRDEProperty(aProperties[i], value.asOutParam());
2162 if (details == VMINFO_MACHINEREADABLE)
2163 {
2164 if (value.isEmpty())
2165 RTPrintf("vrdeproperty[%ls]=<not set>\n", aProperties[i]);
2166 else
2167 RTPrintf("vrdeproperty[%ls]=\"%ls\"\n", aProperties[i], value.raw());
2168 }
2169 else
2170 {
2171 if (value.isEmpty())
2172 RTPrintf("%-28s: %-10lS = <not set>\n", "VRDE property", aProperties[i]);
2173 else
2174 RTPrintf("%-28s: %-10lS = \"%ls\"\n", "VRDE property", aProperties[i], value.raw());
2175 }
2176 }
2177 }
2178 }
2179 else
2180 {
2181 if (details == VMINFO_MACHINEREADABLE)
2182 RTPrintf("vrde=\"off\"\n");
2183 else
2184 RTPrintf("%-28s disabled\n", "VRDE:");
2185 }
2186 }
2187
2188 /*
2189 * USB.
2190 */
2191 SafeIfaceArray<IUSBController> USBCtlColl;
2192 rc = machine->COMGETTER(USBControllers)(ComSafeArrayAsOutParam(USBCtlColl));
2193 if (SUCCEEDED(rc))
2194 {
2195 bool fOhciEnabled = false;
2196 bool fEhciEnabled = false;
2197 bool fXhciEnabled = false;
2198
2199 for (unsigned i = 0; i < USBCtlColl.size(); i++)
2200 {
2201 USBControllerType_T enmType;
2202
2203 rc = USBCtlColl[i]->COMGETTER(Type)(&enmType);
2204 if (SUCCEEDED(rc))
2205 {
2206 switch (enmType)
2207 {
2208 case USBControllerType_OHCI:
2209 fOhciEnabled = true;
2210 break;
2211 case USBControllerType_EHCI:
2212 fEhciEnabled = true;
2213 break;
2214 case USBControllerType_XHCI:
2215 fXhciEnabled = true;
2216 break;
2217 default:
2218 break;
2219 }
2220 }
2221 }
2222
2223 SHOW_BOOL_VALUE("usb", "OHCI USB:", fOhciEnabled);
2224 SHOW_BOOL_VALUE("ehci", "EHCI USB:", fEhciEnabled);
2225 SHOW_BOOL_VALUE("xhci", "xHCI USB:", fXhciEnabled);
2226 }
2227
2228 ComPtr<IUSBDeviceFilters> USBFlts;
2229 rc = machine->COMGETTER(USBDeviceFilters)(USBFlts.asOutParam());
2230 if (SUCCEEDED(rc))
2231 {
2232 SafeIfaceArray <IUSBDeviceFilter> Coll;
2233 rc = USBFlts->COMGETTER(DeviceFilters)(ComSafeArrayAsOutParam(Coll));
2234 if (SUCCEEDED(rc))
2235 {
2236 if (details != VMINFO_MACHINEREADABLE)
2237 RTPrintf("\nUSB Device Filters:\n\n");
2238
2239 if (Coll.size() == 0)
2240 {
2241 if (details != VMINFO_MACHINEREADABLE)
2242 RTPrintf("<none>\n\n");
2243 }
2244 else
2245 {
2246 for (size_t index = 0; index < Coll.size(); ++index)
2247 {
2248 ComPtr<IUSBDeviceFilter> DevPtr = Coll[index];
2249
2250 if (details != VMINFO_MACHINEREADABLE)
2251 SHOW_UTF8_STRING("index", "Index:", FmtNm(szNm, "%zu", index));
2252 SHOW_BOOLEAN_PROP_EX(DevPtr, Active, FmtNm(szNm, "USBFilterActive%zu", index + 1), "Active:", "yes", "no");
2253 SHOW_STRING_PROP(DevPtr, Name, FmtNm(szNm, "USBFilterName%zu", index + 1), "Name:");
2254 SHOW_STRING_PROP(DevPtr, VendorId, FmtNm(szNm, "USBFilterVendorId%zu", index + 1), "VendorId:");
2255 SHOW_STRING_PROP(DevPtr, ProductId, FmtNm(szNm, "USBFilterProductId%zu", index + 1), "ProductId:");
2256 SHOW_STRING_PROP(DevPtr, Revision, FmtNm(szNm, "USBFilterRevision%zu", index + 1), "Revision:");
2257 SHOW_STRING_PROP(DevPtr, Manufacturer, FmtNm(szNm, "USBFilterManufacturer%zu", index + 1), "Manufacturer:");
2258 SHOW_STRING_PROP(DevPtr, Product, FmtNm(szNm, "USBFilterProduct%zu", index + 1), "Product:");
2259 SHOW_STRING_PROP(DevPtr, Remote, FmtNm(szNm, "USBFilterRemote%zu", index + 1), "Remote:");
2260 SHOW_STRING_PROP(DevPtr, SerialNumber, FmtNm(szNm, "USBFilterSerialNumber%zu", index + 1), "Serial Number:");
2261 if (details != VMINFO_MACHINEREADABLE)
2262 {
2263 ULONG fMaskedIfs;
2264 CHECK_ERROR_RET(DevPtr, COMGETTER(MaskedInterfaces)(&fMaskedIfs), rc);
2265 if (fMaskedIfs)
2266 RTPrintf("%-28s %#010x\n", "Masked Interfaces:", fMaskedIfs);
2267 RTPrintf("\n");
2268 }
2269 }
2270 }
2271 }
2272
2273 if (pConsole)
2274 {
2275 /* scope */
2276 {
2277 if (details != VMINFO_MACHINEREADABLE)
2278 RTPrintf("Available remote USB devices:\n\n");
2279
2280 SafeIfaceArray <IHostUSBDevice> coll;
2281 CHECK_ERROR_RET(pConsole, COMGETTER(RemoteUSBDevices)(ComSafeArrayAsOutParam(coll)), rc);
2282
2283 if (coll.size() == 0)
2284 {
2285 if (details != VMINFO_MACHINEREADABLE)
2286 RTPrintf("<none>\n\n");
2287 }
2288 else
2289 {
2290 /* This code is duplicated below, with USBAttach as prefix. */
2291 const char *pszPfx = "USBRemote";
2292 for (size_t i = 0; i < coll.size(); ++i)
2293 {
2294 ComPtr<IHostUSBDevice> dev = coll[i];
2295
2296 SHOW_STRING_PROP(dev, Id, FmtNm(szNm, "%sActive%zu", pszPfx, i + 1), "UUID:");
2297 SHOW_USHORT_PROP_EX2(dev, VendorId, FmtNm(szNm, "%sVendorId%zu", pszPfx, i + 1), "VendorId:", "", "%#06x", "%#06x (%04X)");
2298 SHOW_USHORT_PROP_EX2(dev, ProductId, FmtNm(szNm, "%sProductId%zu", pszPfx, i + 1), "ProductId:", "", "%#06x", "%#06x (%04X)");
2299
2300 USHORT bcdRevision;
2301 CHECK_ERROR_RET(dev, COMGETTER(Revision)(&bcdRevision), rc);
2302 if (details == VMINFO_MACHINEREADABLE)
2303 RTStrPrintf(szValue, sizeof(szValue), "%#04x%02x", bcdRevision >> 8, bcdRevision & 0xff);
2304 else
2305 RTStrPrintf(szValue, sizeof(szValue), "%u.%u (%02u%02u)\n",
2306 bcdRevision >> 8, bcdRevision & 0xff, bcdRevision >> 8, bcdRevision & 0xff);
2307 SHOW_UTF8_STRING(FmtNm(szNm, "%sRevision%zu", pszPfx, i + 1), "Revision:", szValue);
2308
2309 SHOW_STRING_PROP_NOT_EMPTY(dev, Manufacturer, FmtNm(szNm, "%sManufacturer%zu", pszPfx, i + 1), "Manufacturer:");
2310 SHOW_STRING_PROP_NOT_EMPTY(dev, Product, FmtNm(szNm, "%sProduct%zu", pszPfx, i + 1), "Product:");
2311 SHOW_STRING_PROP_NOT_EMPTY(dev, SerialNumber, FmtNm(szNm, "%sSerialNumber%zu", pszPfx, i + 1), "SerialNumber:");
2312 SHOW_STRING_PROP_NOT_EMPTY(dev, Address, FmtNm(szNm, "%sAddress%zu", pszPfx, i + 1), "Address:");
2313
2314 if (details != VMINFO_MACHINEREADABLE)
2315 RTPrintf("\n");
2316 }
2317 }
2318 }
2319
2320 /* scope */
2321 {
2322 if (details != VMINFO_MACHINEREADABLE)
2323 RTPrintf("Currently Attached USB Devices:\n\n");
2324
2325 SafeIfaceArray <IUSBDevice> coll;
2326 CHECK_ERROR_RET(pConsole, COMGETTER(USBDevices)(ComSafeArrayAsOutParam(coll)), rc);
2327
2328 if (coll.size() == 0)
2329 {
2330 if (details != VMINFO_MACHINEREADABLE)
2331 RTPrintf("<none>\n\n");
2332 }
2333 else
2334 {
2335 /* This code is duplicated below, with USBAttach as prefix. */
2336 const char *pszPfx = "USBAttach";
2337 for (size_t i = 0; i < coll.size(); ++i)
2338 {
2339 ComPtr<IUSBDevice> dev = coll[i];
2340
2341 SHOW_STRING_PROP(dev, Id, FmtNm(szNm, "%sActive%zu", pszPfx, i + 1), "UUID:");
2342 SHOW_USHORT_PROP_EX2(dev, VendorId, FmtNm(szNm, "%sVendorId%zu", pszPfx, i + 1), "VendorId:", "", "%#06x", "%#06x (%04X)");
2343 SHOW_USHORT_PROP_EX2(dev, ProductId, FmtNm(szNm, "%sProductId%zu", pszPfx, i + 1), "ProductId:", "", "%#06x", "%#06x (%04X)");
2344
2345 USHORT bcdRevision;
2346 CHECK_ERROR_RET(dev, COMGETTER(Revision)(&bcdRevision), rc);
2347 if (details == VMINFO_MACHINEREADABLE)
2348 RTStrPrintf(szValue, sizeof(szValue), "%#04x%02x", bcdRevision >> 8, bcdRevision & 0xff);
2349 else
2350 RTStrPrintf(szValue, sizeof(szValue), "%u.%u (%02u%02u)\n",
2351 bcdRevision >> 8, bcdRevision & 0xff, bcdRevision >> 8, bcdRevision & 0xff);
2352 SHOW_UTF8_STRING(FmtNm(szNm, "%sRevision%zu", pszPfx, i + 1), "Revision:", szValue);
2353
2354 SHOW_STRING_PROP_NOT_EMPTY(dev, Manufacturer, FmtNm(szNm, "%sManufacturer%zu", pszPfx, i + 1), "Manufacturer:");
2355 SHOW_STRING_PROP_NOT_EMPTY(dev, Product, FmtNm(szNm, "%sProduct%zu", pszPfx, i + 1), "Product:");
2356 SHOW_STRING_PROP_NOT_EMPTY(dev, SerialNumber, FmtNm(szNm, "%sSerialNumber%zu", pszPfx, i + 1), "SerialNumber:");
2357 SHOW_STRING_PROP_NOT_EMPTY(dev, Address, FmtNm(szNm, "%sAddress%zu", pszPfx, i + 1), "Address:");
2358
2359 if (details != VMINFO_MACHINEREADABLE)
2360 RTPrintf("\n");
2361 }
2362 }
2363 }
2364 }
2365 } /* USB */
2366
2367#ifdef VBOX_WITH_PCI_PASSTHROUGH
2368 /* Host PCI passthrough devices */
2369 {
2370 SafeIfaceArray <IPCIDeviceAttachment> assignments;
2371 rc = machine->COMGETTER(PCIDeviceAssignments)(ComSafeArrayAsOutParam(assignments));
2372 if (SUCCEEDED(rc))
2373 {
2374 if (assignments.size() > 0 && (details != VMINFO_MACHINEREADABLE))
2375 {
2376 RTPrintf("\nAttached physical PCI devices:\n\n");
2377 }
2378
2379 for (size_t index = 0; index < assignments.size(); ++index)
2380 {
2381 ComPtr<IPCIDeviceAttachment> Assignment = assignments[index];
2382 char szHostPCIAddress[32], szGuestPCIAddress[32];
2383 LONG iHostPCIAddress = -1, iGuestPCIAddress = -1;
2384 Bstr DevName;
2385
2386 Assignment->COMGETTER(Name)(DevName.asOutParam());
2387 Assignment->COMGETTER(HostAddress)(&iHostPCIAddress);
2388 Assignment->COMGETTER(GuestAddress)(&iGuestPCIAddress);
2389 PCIBusAddress().fromLong(iHostPCIAddress).format(szHostPCIAddress, sizeof(szHostPCIAddress));
2390 PCIBusAddress().fromLong(iGuestPCIAddress).format(szGuestPCIAddress, sizeof(szGuestPCIAddress));
2391
2392 if (details == VMINFO_MACHINEREADABLE)
2393 RTPrintf("AttachedHostPCI=%s,%s\n", szHostPCIAddress, szGuestPCIAddress);
2394 else
2395 RTPrintf(" Host device %ls at %s attached as %s\n", DevName.raw(), szHostPCIAddress, szGuestPCIAddress);
2396 }
2397
2398 if (assignments.size() > 0 && (details != VMINFO_MACHINEREADABLE))
2399 {
2400 RTPrintf("\n");
2401 }
2402 }
2403 }
2404 /* Host PCI passthrough devices */
2405#endif
2406
2407 /*
2408 * Bandwidth groups
2409 */
2410 if (details != VMINFO_MACHINEREADABLE)
2411 RTPrintf("Bandwidth groups: ");
2412 {
2413 ComPtr<IBandwidthControl> bwCtrl;
2414 CHECK_ERROR_RET(machine, COMGETTER(BandwidthControl)(bwCtrl.asOutParam()), rc);
2415
2416 rc = showBandwidthGroups(bwCtrl, details);
2417 }
2418
2419
2420 /*
2421 * Shared folders
2422 */
2423 if (details != VMINFO_MACHINEREADABLE)
2424 RTPrintf("Shared folders:");
2425 uint32_t numSharedFolders = 0;
2426#if 0 // not yet implemented
2427 /* globally shared folders first */
2428 {
2429 SafeIfaceArray <ISharedFolder> sfColl;
2430 CHECK_ERROR_RET(pVirtualBox, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(sfColl)), rc);
2431 for (size_t i = 0; i < sfColl.size(); ++i)
2432 {
2433 ComPtr<ISharedFolder> sf = sfColl[i];
2434 showSharedFolder(sf, details, "global mapping", "GlobalMapping", i + 1, numSharedFolders == 0);
2435 ++numSharedFolders;
2436 }
2437 }
2438#endif
2439 /* now VM mappings */
2440 {
2441 com::SafeIfaceArray <ISharedFolder> folders;
2442 CHECK_ERROR_RET(machine, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(folders)), rc);
2443 for (size_t i = 0; i < folders.size(); ++i)
2444 {
2445 ComPtr<ISharedFolder> sf = folders[i];
2446 showSharedFolder(sf, details, "machine mapping", "MachineMapping", i + 1, numSharedFolders == 0);
2447 ++numSharedFolders;
2448 }
2449 }
2450 /* transient mappings */
2451 if (pConsole)
2452 {
2453 com::SafeIfaceArray <ISharedFolder> folders;
2454 CHECK_ERROR_RET(pConsole, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(folders)), rc);
2455 for (size_t i = 0; i < folders.size(); ++i)
2456 {
2457 ComPtr<ISharedFolder> sf = folders[i];
2458 showSharedFolder(sf, details, "transient mapping", "TransientMapping", i + 1, numSharedFolders == 0);
2459 ++numSharedFolders;
2460 }
2461 }
2462 if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
2463 RTPrintf("<none>\n");
2464 if (details != VMINFO_MACHINEREADABLE)
2465 RTPrintf("\n");
2466
2467 if (pConsole)
2468 {
2469 /*
2470 * Live VRDE info.
2471 */
2472 ComPtr<IVRDEServerInfo> vrdeServerInfo;
2473 CHECK_ERROR_RET(pConsole, COMGETTER(VRDEServerInfo)(vrdeServerInfo.asOutParam()), rc);
2474 BOOL fActive = FALSE;
2475 ULONG cNumberOfClients = 0;
2476 LONG64 BeginTime = 0;
2477 LONG64 EndTime = 0;
2478 LONG64 BytesSent = 0;
2479 LONG64 BytesSentTotal = 0;
2480 LONG64 BytesReceived = 0;
2481 LONG64 BytesReceivedTotal = 0;
2482 Bstr User;
2483 Bstr Domain;
2484 Bstr ClientName;
2485 Bstr ClientIP;
2486 ULONG ClientVersion = 0;
2487 ULONG EncryptionStyle = 0;
2488
2489 if (!vrdeServerInfo.isNull())
2490 {
2491 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(Active)(&fActive), rc);
2492 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(NumberOfClients)(&cNumberOfClients), rc);
2493 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BeginTime)(&BeginTime), rc);
2494 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(EndTime)(&EndTime), rc);
2495 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesSent)(&BytesSent), rc);
2496 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesSentTotal)(&BytesSentTotal), rc);
2497 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesReceived)(&BytesReceived), rc);
2498 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(BytesReceivedTotal)(&BytesReceivedTotal), rc);
2499 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(User)(User.asOutParam()), rc);
2500 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(Domain)(Domain.asOutParam()), rc);
2501 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(ClientName)(ClientName.asOutParam()), rc);
2502 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(ClientIP)(ClientIP.asOutParam()), rc);
2503 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(ClientVersion)(&ClientVersion), rc);
2504 CHECK_ERROR_RET(vrdeServerInfo, COMGETTER(EncryptionStyle)(&EncryptionStyle), rc);
2505 }
2506
2507 SHOW_BOOL_VALUE_EX("VRDEActiveConnection", "VRDE Connection:", fActive, "active", "not active");
2508 SHOW_ULONG_VALUE("VRDEClients=", "Clients so far:", cNumberOfClients, "");
2509
2510 if (cNumberOfClients > 0)
2511 {
2512 char szTimeValue[128];
2513 makeTimeStr(szTimeValue, sizeof(szTimeValue), BeginTime);
2514 if (fActive)
2515 SHOW_UTF8_STRING("VRDEStartTime", "Start time:", szTimeValue);
2516 else
2517 {
2518 SHOW_UTF8_STRING("VRDELastStartTime", "Last started:", szTimeValue);
2519 makeTimeStr(szTimeValue, sizeof(szTimeValue), EndTime);
2520 SHOW_UTF8_STRING("VRDELastEndTime", "Last ended:", szTimeValue);
2521 }
2522
2523 int64_t ThroughputSend = 0;
2524 int64_t ThroughputReceive = 0;
2525 if (EndTime != BeginTime)
2526 {
2527 ThroughputSend = (BytesSent * 1000) / (EndTime - BeginTime);
2528 ThroughputReceive = (BytesReceived * 1000) / (EndTime - BeginTime);
2529 }
2530 SHOW_LONG64_VALUE("VRDEBytesSent", "Sent:", BytesSent, "Bytes");
2531 SHOW_LONG64_VALUE("VRDEThroughputSend", "Average speed:", ThroughputSend, "B/s");
2532 SHOW_LONG64_VALUE("VRDEBytesSentTotal", "Sent total:", BytesSentTotal, "Bytes");
2533
2534 SHOW_LONG64_VALUE("VRDEBytesReceived", "Received:", BytesReceived, "Bytes");
2535 SHOW_LONG64_VALUE("VRDEThroughputReceive", "Speed:", ThroughputReceive, "B/s");
2536 SHOW_LONG64_VALUE("VRDEBytesReceivedTotal", "Received total:", BytesReceivedTotal, "Bytes");
2537
2538 if (fActive)
2539 {
2540 SHOW_BSTR_STRING("VRDEUserName", "User name:", User);
2541 SHOW_BSTR_STRING("VRDEDomain", "Domain:", Domain);
2542 SHOW_BSTR_STRING("VRDEClientName", "Client name:", ClientName);
2543 SHOW_BSTR_STRING("VRDEClientIP", "Client IP:", ClientIP);
2544 SHOW_ULONG_VALUE("VRDEClientVersion", "Client version:", ClientVersion, "");
2545 SHOW_UTF8_STRING("VRDEEncryption", "Encryption:", EncryptionStyle == 0 ? "RDP4" : "RDP5 (X.509)");
2546 }
2547 }
2548
2549 if (details != VMINFO_MACHINEREADABLE)
2550 RTPrintf("\n");
2551 }
2552
2553#ifdef VBOX_WITH_RECORDING
2554 {
2555 /* Video capture */
2556 BOOL fCaptureVideo = FALSE;
2557# ifdef VBOX_WITH_AUDIO_RECORDING
2558 BOOL fCaptureAudio = FALSE;
2559# endif
2560
2561 ComPtr<IRecordingSettings> recordingSettings;
2562 CHECK_ERROR_RET(machine, COMGETTER(RecordingSettings)(recordingSettings.asOutParam()), rc);
2563
2564 SafeIfaceArray <IRecordingScreenSettings> saRecordingScreenScreens;
2565 CHECK_ERROR_RET(recordingSettings, COMGETTER(Screens)(ComSafeArrayAsOutParam(saRecordingScreenScreens)), rc);
2566
2567 /* For now all screens have the same configuration; so take screen 0 and work with that. */
2568 ULONG fFeatures;
2569 CHECK_ERROR_RET(saRecordingScreenScreens[0], COMGETTER(Features)(&fFeatures), rc);
2570 ULONG Width;
2571 CHECK_ERROR_RET(saRecordingScreenScreens[0], COMGETTER(VideoWidth)(&Width), rc);
2572 ULONG Height;
2573 CHECK_ERROR_RET(saRecordingScreenScreens[0], COMGETTER(VideoHeight)(&Height), rc);
2574 ULONG Rate;
2575 CHECK_ERROR_RET(saRecordingScreenScreens[0], COMGETTER(VideoRate)(&Rate), rc);
2576 ULONG Fps;
2577 CHECK_ERROR_RET(saRecordingScreenScreens[0], COMGETTER(VideoFPS)(&Fps), rc);
2578 Bstr bstrFile;
2579 CHECK_ERROR_RET(saRecordingScreenScreens[0], COMGETTER(Filename)(bstrFile.asOutParam()), rc);
2580 Bstr bstrOptions;
2581 CHECK_ERROR_RET(saRecordingScreenScreens[0], COMGETTER(Options)(bstrOptions.asOutParam()), rc);
2582
2583 Utf8Str strOptions(bstrOptions);
2584 size_t pos = 0;
2585 com::Utf8Str key, value;
2586 while ((pos = strOptions.parseKeyValue(key, value, pos)) != com::Utf8Str::npos)
2587 {
2588 if (key.compare("vc_enabled", Utf8Str::CaseInsensitive) == 0)
2589 {
2590 fCaptureVideo = value.compare("true", Utf8Str::CaseInsensitive) == 0;
2591 }
2592 else if (key.compare("ac_enabled", Utf8Str::CaseInsensitive) == 0)
2593 {
2594# ifdef VBOX_WITH_AUDIO_RECORDING
2595 fCaptureAudio = value.compare("true", Utf8Str::CaseInsensitive) == 0;
2596# endif
2597 }
2598 }
2599
2600 SHOW_BOOL_VALUE_EX("videocap", "Capturing:", fCaptureVideo, "active", "not active");
2601# ifdef VBOX_WITH_AUDIO_RECORDING
2602 SHOW_BOOL_VALUE_EX("videocapaudio", "Capture audio:", fCaptureAudio, "active", "not active");
2603# endif
2604 szValue[0] = '\0';
2605 for (size_t i = 0, off = 0; i < saRecordingScreenScreens.size(); i++)
2606 {
2607 BOOL fEnabled;
2608 CHECK_ERROR_RET(saRecordingScreenScreens[i], COMGETTER(Enabled)(&fEnabled), rc);
2609 if (fEnabled && off < sizeof(szValue) - 3)
2610 off += RTStrPrintf(&szValue[off], sizeof(szValue) - off, off ? ",%zu" : "%zu", i);
2611 }
2612 SHOW_UTF8_STRING("capturescreens", "Capture screens:", szValue);
2613 SHOW_BSTR_STRING("capturefilename", "Capture file:", bstrFile);
2614 RTStrPrintf(szValue, sizeof(szValue), "%ux%u", Width, Height);
2615 SHOW_UTF8_STRING("captureres", "Capture dimensions:", szValue);
2616 SHOW_ULONG_VALUE("capturevideorate", "Capture rate:", Rate, "kbps");
2617 SHOW_ULONG_VALUE("capturevideofps", "Capture FPS:", Fps, "kbps");
2618 SHOW_BSTR_STRING("captureopts", "Capture options:", bstrOptions);
2619
2620 if (details != VMINFO_MACHINEREADABLE)
2621 RTPrintf("\n");
2622 /** @todo Add more audio capturing profile / information here. */
2623 }
2624#endif /* VBOX_WITH_RECORDING */
2625
2626 if ( details == VMINFO_STANDARD
2627 || details == VMINFO_FULL
2628 || details == VMINFO_MACHINEREADABLE)
2629 {
2630 Bstr description;
2631 machine->COMGETTER(Description)(description.asOutParam());
2632 if (!description.isEmpty())
2633 {
2634 if (details == VMINFO_MACHINEREADABLE)
2635 outputMachineReadableString("description", &description);
2636 else
2637 RTPrintf("Description:\n%ls\n", description.raw());
2638 }
2639 }
2640
2641 if (details != VMINFO_MACHINEREADABLE)
2642 RTPrintf("Guest:\n\n");
2643
2644 SHOW_ULONG_PROP(machine, MemoryBalloonSize, "GuestMemoryBalloon", "Configured memory balloon size:", "MB");
2645
2646 if (pConsole)
2647 {
2648 ComPtr<IGuest> guest;
2649 rc = pConsole->COMGETTER(Guest)(guest.asOutParam());
2650 if (SUCCEEDED(rc) && !guest.isNull())
2651 {
2652 SHOW_STRING_PROP_NOT_EMPTY(guest, OSTypeId, "GuestOSType", "OS type:");
2653
2654 AdditionsRunLevelType_T guestRunLevel; /** @todo Add a runlevel-to-string (e.g. 0 = "None") method? */
2655 rc = guest->COMGETTER(AdditionsRunLevel)(&guestRunLevel);
2656 if (SUCCEEDED(rc))
2657 SHOW_ULONG_VALUE("GuestAdditionsRunLevel", "Additions run level:", (ULONG)guestRunLevel, "");
2658
2659 Bstr guestString;
2660 rc = guest->COMGETTER(AdditionsVersion)(guestString.asOutParam());
2661 if ( SUCCEEDED(rc)
2662 && !guestString.isEmpty())
2663 {
2664 ULONG uRevision;
2665 rc = guest->COMGETTER(AdditionsRevision)(&uRevision);
2666 if (FAILED(rc))
2667 uRevision = 0;
2668 RTStrPrintf(szValue, sizeof(szValue), "%ls r%u", guestString.raw(), uRevision);
2669 SHOW_UTF8_STRING("GuestAdditionsVersion", "Additions version:", szValue);
2670 }
2671
2672 if (details != VMINFO_MACHINEREADABLE)
2673 RTPrintf("\nGuest Facilities:\n\n");
2674
2675 /* Print information about known Guest Additions facilities: */
2676 SafeIfaceArray <IAdditionsFacility> collFac;
2677 CHECK_ERROR_RET(guest, COMGETTER(Facilities)(ComSafeArrayAsOutParam(collFac)), rc);
2678 LONG64 lLastUpdatedMS;
2679 char szLastUpdated[32];
2680 AdditionsFacilityStatus_T curStatus;
2681 for (size_t index = 0; index < collFac.size(); ++index)
2682 {
2683 ComPtr<IAdditionsFacility> fac = collFac[index];
2684 if (fac)
2685 {
2686 CHECK_ERROR_RET(fac, COMGETTER(Name)(guestString.asOutParam()), rc);
2687 if (!guestString.isEmpty())
2688 {
2689 CHECK_ERROR_RET(fac, COMGETTER(Status)(&curStatus), rc);
2690 CHECK_ERROR_RET(fac, COMGETTER(LastUpdated)(&lLastUpdatedMS), rc);
2691 if (details == VMINFO_MACHINEREADABLE)
2692 RTPrintf("GuestAdditionsFacility_%ls=%u,%lld\n",
2693 guestString.raw(), curStatus, lLastUpdatedMS);
2694 else
2695 {
2696 makeTimeStr(szLastUpdated, sizeof(szLastUpdated), lLastUpdatedMS);
2697 RTPrintf("Facility \"%ls\": %s (last update: %s)\n",
2698 guestString.raw(), facilityStateToName(curStatus, false /* No short naming */), szLastUpdated);
2699 }
2700 }
2701 else
2702 AssertMsgFailed(("Facility with undefined name retrieved!\n"));
2703 }
2704 else
2705 AssertMsgFailed(("Invalid facility returned!\n"));
2706 }
2707 if (!collFac.size() && details != VMINFO_MACHINEREADABLE)
2708 RTPrintf("No active facilities.\n");
2709 }
2710 }
2711
2712 if (details != VMINFO_MACHINEREADABLE)
2713 RTPrintf("\n");
2714
2715 /*
2716 * snapshots
2717 */
2718 ComPtr<ISnapshot> snapshot;
2719 rc = machine->FindSnapshot(Bstr().raw(), snapshot.asOutParam());
2720 if (SUCCEEDED(rc) && snapshot)
2721 {
2722 ComPtr<ISnapshot> currentSnapshot;
2723 rc = machine->COMGETTER(CurrentSnapshot)(currentSnapshot.asOutParam());
2724 if (SUCCEEDED(rc))
2725 {
2726 if (details != VMINFO_MACHINEREADABLE)
2727 RTPrintf("Snapshots:\n\n");
2728 showSnapshots(snapshot, currentSnapshot, details);
2729 }
2730 }
2731
2732 if (details != VMINFO_MACHINEREADABLE)
2733 RTPrintf("\n");
2734 return S_OK;
2735}
2736
2737#if defined(_MSC_VER)
2738# pragma optimize("", on)
2739# pragma warning(pop)
2740#endif
2741
2742static const RTGETOPTDEF g_aShowVMInfoOptions[] =
2743{
2744 { "--details", 'D', RTGETOPT_REQ_NOTHING },
2745 { "-details", 'D', RTGETOPT_REQ_NOTHING }, // deprecated
2746 { "--machinereadable", 'M', RTGETOPT_REQ_NOTHING },
2747 { "-machinereadable", 'M', RTGETOPT_REQ_NOTHING }, // deprecated
2748 { "--log", 'l', RTGETOPT_REQ_UINT32 },
2749};
2750
2751RTEXITCODE handleShowVMInfo(HandlerArg *a)
2752{
2753 HRESULT rc;
2754 const char *VMNameOrUuid = NULL;
2755 bool fLog = false;
2756 uint32_t uLogIdx = 0;
2757 bool fDetails = false;
2758 bool fMachinereadable = false;
2759
2760 int c;
2761 RTGETOPTUNION ValueUnion;
2762 RTGETOPTSTATE GetState;
2763 // start at 0 because main() has hacked both the argc and argv given to us
2764 RTGetOptInit(&GetState, a->argc, a->argv, g_aShowVMInfoOptions, RT_ELEMENTS(g_aShowVMInfoOptions),
2765 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
2766 while ((c = RTGetOpt(&GetState, &ValueUnion)))
2767 {
2768 switch (c)
2769 {
2770 case 'D': // --details
2771 fDetails = true;
2772 break;
2773
2774 case 'M': // --machinereadable
2775 fMachinereadable = true;
2776 break;
2777
2778 case 'l': // --log
2779 fLog = true;
2780 uLogIdx = ValueUnion.u32;
2781 break;
2782
2783 case VINF_GETOPT_NOT_OPTION:
2784 if (!VMNameOrUuid)
2785 VMNameOrUuid = ValueUnion.psz;
2786 else
2787 return errorSyntax(USAGE_SHOWVMINFO, "Invalid parameter '%s'", ValueUnion.psz);
2788 break;
2789
2790 default:
2791 return errorGetOpt(USAGE_SHOWVMINFO, c, &ValueUnion);
2792 }
2793 }
2794
2795 /* check for required options */
2796 if (!VMNameOrUuid)
2797 return errorSyntax(USAGE_SHOWVMINFO, "VM name or UUID required");
2798
2799 /* try to find the given machine */
2800 ComPtr<IMachine> machine;
2801 CHECK_ERROR(a->virtualBox, FindMachine(Bstr(VMNameOrUuid).raw(),
2802 machine.asOutParam()));
2803 if (FAILED(rc))
2804 return RTEXITCODE_FAILURE;
2805
2806 /* Printing the log is exclusive. */
2807 if (fLog && (fMachinereadable || fDetails))
2808 return errorSyntax(USAGE_SHOWVMINFO, "Option --log is exclusive");
2809
2810 if (fLog)
2811 {
2812 ULONG64 uOffset = 0;
2813 SafeArray<BYTE> aLogData;
2814 size_t cbLogData;
2815 while (true)
2816 {
2817 /* Reset the array */
2818 aLogData.setNull();
2819 /* Fetch a chunk of the log file */
2820 CHECK_ERROR_BREAK(machine, ReadLog(uLogIdx, uOffset, _1M,
2821 ComSafeArrayAsOutParam(aLogData)));
2822 cbLogData = aLogData.size();
2823 if (cbLogData == 0)
2824 break;
2825 /* aLogData has a platform dependent line ending, standardize on
2826 * Unix style, as RTStrmWrite does the LF -> CR/LF replacement on
2827 * Windows. Otherwise we end up with CR/CR/LF on Windows. */
2828 size_t cbLogDataPrint = cbLogData;
2829 for (BYTE *s = aLogData.raw(), *d = s;
2830 s - aLogData.raw() < (ssize_t)cbLogData;
2831 s++, d++)
2832 {
2833 if (*s == '\r')
2834 {
2835 /* skip over CR, adjust destination */
2836 d--;
2837 cbLogDataPrint--;
2838 }
2839 else if (s != d)
2840 *d = *s;
2841 }
2842 RTStrmWrite(g_pStdOut, aLogData.raw(), cbLogDataPrint);
2843 uOffset += cbLogData;
2844 }
2845 }
2846 else
2847 {
2848 /* 2nd option can be -details or -argdump */
2849 VMINFO_DETAILS details = VMINFO_NONE;
2850 if (fMachinereadable)
2851 details = VMINFO_MACHINEREADABLE;
2852 else if (fDetails)
2853 details = VMINFO_FULL;
2854 else
2855 details = VMINFO_STANDARD;
2856
2857 /* open an existing session for the VM */
2858 rc = machine->LockMachine(a->session, LockType_Shared);
2859 if (SUCCEEDED(rc))
2860 /* get the session machine */
2861 rc = a->session->COMGETTER(Machine)(machine.asOutParam());
2862
2863 rc = showVMInfo(a->virtualBox, machine, a->session, details);
2864
2865 a->session->UnlockMachine();
2866 }
2867
2868 return SUCCEEDED(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
2869}
2870
2871#endif /* !VBOX_ONLY_DOCS */
2872/* vi: set tabstop=4 shiftwidth=4 expandtab: */
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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